14ba319b5SDimitry Andric //===--------------------- PredicateExpander.cpp --------------------------===//
24ba319b5SDimitry Andric //
34ba319b5SDimitry Andric // The LLVM Compiler Infrastructure
44ba319b5SDimitry Andric //
54ba319b5SDimitry Andric // This file is distributed under the University of Illinois Open Source
64ba319b5SDimitry Andric // License. See LICENSE.TXT for details.
74ba319b5SDimitry Andric //
84ba319b5SDimitry Andric //===----------------------------------------------------------------------===//
94ba319b5SDimitry Andric /// \file
104ba319b5SDimitry Andric /// Functionalities used by the Tablegen backends to expand machine predicates.
114ba319b5SDimitry Andric //
124ba319b5SDimitry Andric //===----------------------------------------------------------------------===//
134ba319b5SDimitry Andric
144ba319b5SDimitry Andric #include "PredicateExpander.h"
15*b5893f02SDimitry Andric #include "CodeGenSchedule.h" // Definition of STIPredicateFunction.
164ba319b5SDimitry Andric
174ba319b5SDimitry Andric namespace llvm {
184ba319b5SDimitry Andric
expandTrue(raw_ostream & OS)19*b5893f02SDimitry Andric void PredicateExpander::expandTrue(raw_ostream &OS) { OS << "true"; }
expandFalse(raw_ostream & OS)20*b5893f02SDimitry Andric void PredicateExpander::expandFalse(raw_ostream &OS) { OS << "false"; }
214ba319b5SDimitry Andric
expandCheckImmOperand(raw_ostream & OS,int OpIndex,int ImmVal,StringRef FunctionMapper)22*b5893f02SDimitry Andric void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
23*b5893f02SDimitry Andric int ImmVal,
24*b5893f02SDimitry Andric StringRef FunctionMapper) {
25*b5893f02SDimitry Andric if (!FunctionMapper.empty())
26*b5893f02SDimitry Andric OS << FunctionMapper << "(";
274ba319b5SDimitry Andric OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
28*b5893f02SDimitry Andric << ").getImm()";
29*b5893f02SDimitry Andric if (!FunctionMapper.empty())
30*b5893f02SDimitry Andric OS << ")";
31*b5893f02SDimitry Andric OS << (shouldNegate() ? " != " : " == ") << ImmVal;
324ba319b5SDimitry Andric }
334ba319b5SDimitry Andric
expandCheckImmOperand(raw_ostream & OS,int OpIndex,StringRef ImmVal,StringRef FunctionMapper)34*b5893f02SDimitry Andric void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
35*b5893f02SDimitry Andric StringRef ImmVal,
36*b5893f02SDimitry Andric StringRef FunctionMapper) {
37*b5893f02SDimitry Andric if (ImmVal.empty())
38*b5893f02SDimitry Andric expandCheckImmOperandSimple(OS, OpIndex, FunctionMapper);
39*b5893f02SDimitry Andric
40*b5893f02SDimitry Andric if (!FunctionMapper.empty())
41*b5893f02SDimitry Andric OS << FunctionMapper << "(";
424ba319b5SDimitry Andric OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
43*b5893f02SDimitry Andric << ").getImm()";
44*b5893f02SDimitry Andric if (!FunctionMapper.empty())
45*b5893f02SDimitry Andric OS << ")";
46*b5893f02SDimitry Andric OS << (shouldNegate() ? " != " : " == ") << ImmVal;
474ba319b5SDimitry Andric }
484ba319b5SDimitry Andric
expandCheckImmOperandSimple(raw_ostream & OS,int OpIndex,StringRef FunctionMapper)49*b5893f02SDimitry Andric void PredicateExpander::expandCheckImmOperandSimple(raw_ostream &OS,
50*b5893f02SDimitry Andric int OpIndex,
51*b5893f02SDimitry Andric StringRef FunctionMapper) {
52*b5893f02SDimitry Andric if (shouldNegate())
53*b5893f02SDimitry Andric OS << "!";
54*b5893f02SDimitry Andric if (!FunctionMapper.empty())
55*b5893f02SDimitry Andric OS << FunctionMapper << "(";
56*b5893f02SDimitry Andric OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
57*b5893f02SDimitry Andric << ").getImm()";
58*b5893f02SDimitry Andric if (!FunctionMapper.empty())
59*b5893f02SDimitry Andric OS << ")";
60*b5893f02SDimitry Andric }
61*b5893f02SDimitry Andric
expandCheckRegOperand(raw_ostream & OS,int OpIndex,const Record * Reg,StringRef FunctionMapper)62*b5893f02SDimitry Andric void PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex,
63*b5893f02SDimitry Andric const Record *Reg,
64*b5893f02SDimitry Andric StringRef FunctionMapper) {
654ba319b5SDimitry Andric assert(Reg->isSubClassOf("Register") && "Expected a register Record!");
664ba319b5SDimitry Andric
67*b5893f02SDimitry Andric if (!FunctionMapper.empty())
68*b5893f02SDimitry Andric OS << FunctionMapper << "(";
694ba319b5SDimitry Andric OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
70*b5893f02SDimitry Andric << ").getReg()";
71*b5893f02SDimitry Andric if (!FunctionMapper.empty())
72*b5893f02SDimitry Andric OS << ")";
73*b5893f02SDimitry Andric OS << (shouldNegate() ? " != " : " == ");
744ba319b5SDimitry Andric const StringRef Str = Reg->getValueAsString("Namespace");
754ba319b5SDimitry Andric if (!Str.empty())
764ba319b5SDimitry Andric OS << Str << "::";
774ba319b5SDimitry Andric OS << Reg->getName();
784ba319b5SDimitry Andric }
794ba319b5SDimitry Andric
80*b5893f02SDimitry Andric
expandCheckRegOperandSimple(raw_ostream & OS,int OpIndex,StringRef FunctionMapper)81*b5893f02SDimitry Andric void PredicateExpander::expandCheckRegOperandSimple(raw_ostream &OS,
82*b5893f02SDimitry Andric int OpIndex,
83*b5893f02SDimitry Andric StringRef FunctionMapper) {
84*b5893f02SDimitry Andric if (shouldNegate())
85*b5893f02SDimitry Andric OS << "!";
86*b5893f02SDimitry Andric if (!FunctionMapper.empty())
87*b5893f02SDimitry Andric OS << FunctionMapper << "(";
88*b5893f02SDimitry Andric OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
89*b5893f02SDimitry Andric << ").getReg()";
90*b5893f02SDimitry Andric if (!FunctionMapper.empty())
91*b5893f02SDimitry Andric OS << ")";
92*b5893f02SDimitry Andric }
93*b5893f02SDimitry Andric
expandCheckInvalidRegOperand(raw_ostream & OS,int OpIndex)94*b5893f02SDimitry Andric void PredicateExpander::expandCheckInvalidRegOperand(raw_ostream &OS,
954ba319b5SDimitry Andric int OpIndex) {
964ba319b5SDimitry Andric OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
974ba319b5SDimitry Andric << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0";
984ba319b5SDimitry Andric }
994ba319b5SDimitry Andric
expandCheckSameRegOperand(raw_ostream & OS,int First,int Second)100*b5893f02SDimitry Andric void PredicateExpander::expandCheckSameRegOperand(raw_ostream &OS, int First,
101*b5893f02SDimitry Andric int Second) {
1024ba319b5SDimitry Andric OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First
1034ba319b5SDimitry Andric << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI"
1044ba319b5SDimitry Andric << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()";
1054ba319b5SDimitry Andric }
1064ba319b5SDimitry Andric
expandCheckNumOperands(raw_ostream & OS,int NumOps)107*b5893f02SDimitry Andric void PredicateExpander::expandCheckNumOperands(raw_ostream &OS, int NumOps) {
1084ba319b5SDimitry Andric OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() "
1094ba319b5SDimitry Andric << (shouldNegate() ? "!= " : "== ") << NumOps;
1104ba319b5SDimitry Andric }
1114ba319b5SDimitry Andric
expandCheckOpcode(raw_ostream & OS,const Record * Inst)112*b5893f02SDimitry Andric void PredicateExpander::expandCheckOpcode(raw_ostream &OS, const Record *Inst) {
1134ba319b5SDimitry Andric OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() "
1144ba319b5SDimitry Andric << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace")
1154ba319b5SDimitry Andric << "::" << Inst->getName();
1164ba319b5SDimitry Andric }
1174ba319b5SDimitry Andric
expandCheckOpcode(raw_ostream & OS,const RecVec & Opcodes)118*b5893f02SDimitry Andric void PredicateExpander::expandCheckOpcode(raw_ostream &OS,
1194ba319b5SDimitry Andric const RecVec &Opcodes) {
1204ba319b5SDimitry Andric assert(!Opcodes.empty() && "Expected at least one opcode to check!");
1214ba319b5SDimitry Andric bool First = true;
1224ba319b5SDimitry Andric
1234ba319b5SDimitry Andric if (Opcodes.size() == 1) {
1244ba319b5SDimitry Andric OS << "( ";
1254ba319b5SDimitry Andric expandCheckOpcode(OS, Opcodes[0]);
1264ba319b5SDimitry Andric OS << " )";
1274ba319b5SDimitry Andric return;
1284ba319b5SDimitry Andric }
1294ba319b5SDimitry Andric
1304ba319b5SDimitry Andric OS << '(';
1314ba319b5SDimitry Andric increaseIndentLevel();
1324ba319b5SDimitry Andric for (const Record *Rec : Opcodes) {
1334ba319b5SDimitry Andric OS << '\n';
134*b5893f02SDimitry Andric OS.indent(getIndentLevel() * 2);
1354ba319b5SDimitry Andric if (!First)
1364ba319b5SDimitry Andric OS << (shouldNegate() ? "&& " : "|| ");
1374ba319b5SDimitry Andric
1384ba319b5SDimitry Andric expandCheckOpcode(OS, Rec);
1394ba319b5SDimitry Andric First = false;
1404ba319b5SDimitry Andric }
1414ba319b5SDimitry Andric
1424ba319b5SDimitry Andric OS << '\n';
1434ba319b5SDimitry Andric decreaseIndentLevel();
144*b5893f02SDimitry Andric OS.indent(getIndentLevel() * 2);
1454ba319b5SDimitry Andric OS << ')';
1464ba319b5SDimitry Andric }
1474ba319b5SDimitry Andric
expandCheckPseudo(raw_ostream & OS,const RecVec & Opcodes)148*b5893f02SDimitry Andric void PredicateExpander::expandCheckPseudo(raw_ostream &OS,
1494ba319b5SDimitry Andric const RecVec &Opcodes) {
1504ba319b5SDimitry Andric if (shouldExpandForMC())
1514ba319b5SDimitry Andric expandFalse(OS);
1524ba319b5SDimitry Andric else
1534ba319b5SDimitry Andric expandCheckOpcode(OS, Opcodes);
1544ba319b5SDimitry Andric }
1554ba319b5SDimitry Andric
expandPredicateSequence(raw_ostream & OS,const RecVec & Sequence,bool IsCheckAll)156*b5893f02SDimitry Andric void PredicateExpander::expandPredicateSequence(raw_ostream &OS,
1574ba319b5SDimitry Andric const RecVec &Sequence,
1584ba319b5SDimitry Andric bool IsCheckAll) {
1594ba319b5SDimitry Andric assert(!Sequence.empty() && "Found an invalid empty predicate set!");
1604ba319b5SDimitry Andric if (Sequence.size() == 1)
1614ba319b5SDimitry Andric return expandPredicate(OS, Sequence[0]);
1624ba319b5SDimitry Andric
1634ba319b5SDimitry Andric // Okay, there is more than one predicate in the set.
1644ba319b5SDimitry Andric bool First = true;
1654ba319b5SDimitry Andric OS << (shouldNegate() ? "!(" : "(");
1664ba319b5SDimitry Andric increaseIndentLevel();
1674ba319b5SDimitry Andric
1684ba319b5SDimitry Andric bool OldValue = shouldNegate();
1694ba319b5SDimitry Andric setNegatePredicate(false);
1704ba319b5SDimitry Andric for (const Record *Rec : Sequence) {
1714ba319b5SDimitry Andric OS << '\n';
172*b5893f02SDimitry Andric OS.indent(getIndentLevel() * 2);
1734ba319b5SDimitry Andric if (!First)
1744ba319b5SDimitry Andric OS << (IsCheckAll ? "&& " : "|| ");
1754ba319b5SDimitry Andric expandPredicate(OS, Rec);
1764ba319b5SDimitry Andric First = false;
1774ba319b5SDimitry Andric }
1784ba319b5SDimitry Andric OS << '\n';
1794ba319b5SDimitry Andric decreaseIndentLevel();
180*b5893f02SDimitry Andric OS.indent(getIndentLevel() * 2);
1814ba319b5SDimitry Andric OS << ')';
1824ba319b5SDimitry Andric setNegatePredicate(OldValue);
1834ba319b5SDimitry Andric }
1844ba319b5SDimitry Andric
expandTIIFunctionCall(raw_ostream & OS,StringRef MethodName)185*b5893f02SDimitry Andric void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS,
1864ba319b5SDimitry Andric StringRef MethodName) {
1874ba319b5SDimitry Andric OS << (shouldNegate() ? "!" : "");
188*b5893f02SDimitry Andric OS << TargetName << (shouldExpandForMC() ? "_MC::" : "InstrInfo::");
1894ba319b5SDimitry Andric OS << MethodName << (isByRef() ? "(MI)" : "(*MI)");
1904ba319b5SDimitry Andric }
1914ba319b5SDimitry Andric
expandCheckIsRegOperand(raw_ostream & OS,int OpIndex)192*b5893f02SDimitry Andric void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) {
1934ba319b5SDimitry Andric OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
1944ba319b5SDimitry Andric << "getOperand(" << OpIndex << ").isReg() ";
1954ba319b5SDimitry Andric }
1964ba319b5SDimitry Andric
expandCheckIsImmOperand(raw_ostream & OS,int OpIndex)197*b5893f02SDimitry Andric void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) {
1984ba319b5SDimitry Andric OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
1994ba319b5SDimitry Andric << "getOperand(" << OpIndex << ").isImm() ";
2004ba319b5SDimitry Andric }
2014ba319b5SDimitry Andric
expandCheckFunctionPredicate(raw_ostream & OS,StringRef MCInstFn,StringRef MachineInstrFn)202*b5893f02SDimitry Andric void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS,
2034ba319b5SDimitry Andric StringRef MCInstFn,
2044ba319b5SDimitry Andric StringRef MachineInstrFn) {
2054ba319b5SDimitry Andric OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn)
2064ba319b5SDimitry Andric << (isByRef() ? "(MI)" : "(*MI)");
2074ba319b5SDimitry Andric }
2084ba319b5SDimitry Andric
expandCheckNonPortable(raw_ostream & OS,StringRef Code)209*b5893f02SDimitry Andric void PredicateExpander::expandCheckNonPortable(raw_ostream &OS,
2104ba319b5SDimitry Andric StringRef Code) {
2114ba319b5SDimitry Andric if (shouldExpandForMC())
2124ba319b5SDimitry Andric return expandFalse(OS);
2134ba319b5SDimitry Andric
2144ba319b5SDimitry Andric OS << '(' << Code << ')';
2154ba319b5SDimitry Andric }
2164ba319b5SDimitry Andric
expandReturnStatement(raw_ostream & OS,const Record * Rec)217*b5893f02SDimitry Andric void PredicateExpander::expandReturnStatement(raw_ostream &OS,
2184ba319b5SDimitry Andric const Record *Rec) {
219*b5893f02SDimitry Andric std::string Buffer;
220*b5893f02SDimitry Andric raw_string_ostream SS(Buffer);
2214ba319b5SDimitry Andric
222*b5893f02SDimitry Andric SS << "return ";
223*b5893f02SDimitry Andric expandPredicate(SS, Rec);
224*b5893f02SDimitry Andric SS << ";";
225*b5893f02SDimitry Andric SS.flush();
226*b5893f02SDimitry Andric OS << Buffer;
227*b5893f02SDimitry Andric }
228*b5893f02SDimitry Andric
expandOpcodeSwitchCase(raw_ostream & OS,const Record * Rec)229*b5893f02SDimitry Andric void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS,
230*b5893f02SDimitry Andric const Record *Rec) {
231*b5893f02SDimitry Andric const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes");
232*b5893f02SDimitry Andric for (const Record *Opcode : Opcodes) {
233*b5893f02SDimitry Andric OS.indent(getIndentLevel() * 2);
234*b5893f02SDimitry Andric OS << "case " << Opcode->getValueAsString("Namespace")
235*b5893f02SDimitry Andric << "::" << Opcode->getName() << ":\n";
236*b5893f02SDimitry Andric }
237*b5893f02SDimitry Andric
238*b5893f02SDimitry Andric increaseIndentLevel();
239*b5893f02SDimitry Andric OS.indent(getIndentLevel() * 2);
240*b5893f02SDimitry Andric expandStatement(OS, Rec->getValueAsDef("CaseStmt"));
241*b5893f02SDimitry Andric decreaseIndentLevel();
242*b5893f02SDimitry Andric }
243*b5893f02SDimitry Andric
expandOpcodeSwitchStatement(raw_ostream & OS,const RecVec & Cases,const Record * Default)244*b5893f02SDimitry Andric void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS,
245*b5893f02SDimitry Andric const RecVec &Cases,
246*b5893f02SDimitry Andric const Record *Default) {
247*b5893f02SDimitry Andric std::string Buffer;
248*b5893f02SDimitry Andric raw_string_ostream SS(Buffer);
249*b5893f02SDimitry Andric
250*b5893f02SDimitry Andric SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
251*b5893f02SDimitry Andric for (const Record *Rec : Cases) {
252*b5893f02SDimitry Andric expandOpcodeSwitchCase(SS, Rec);
253*b5893f02SDimitry Andric SS << '\n';
254*b5893f02SDimitry Andric }
255*b5893f02SDimitry Andric
256*b5893f02SDimitry Andric // Expand the default case.
257*b5893f02SDimitry Andric SS.indent(getIndentLevel() * 2);
258*b5893f02SDimitry Andric SS << "default:\n";
259*b5893f02SDimitry Andric
260*b5893f02SDimitry Andric increaseIndentLevel();
261*b5893f02SDimitry Andric SS.indent(getIndentLevel() * 2);
262*b5893f02SDimitry Andric expandStatement(SS, Default);
263*b5893f02SDimitry Andric decreaseIndentLevel();
264*b5893f02SDimitry Andric SS << '\n';
265*b5893f02SDimitry Andric
266*b5893f02SDimitry Andric SS.indent(getIndentLevel() * 2);
267*b5893f02SDimitry Andric SS << "} // end of switch-stmt";
268*b5893f02SDimitry Andric SS.flush();
269*b5893f02SDimitry Andric OS << Buffer;
270*b5893f02SDimitry Andric }
271*b5893f02SDimitry Andric
expandStatement(raw_ostream & OS,const Record * Rec)272*b5893f02SDimitry Andric void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) {
273*b5893f02SDimitry Andric // Assume that padding has been added by the caller.
274*b5893f02SDimitry Andric if (Rec->isSubClassOf("MCOpcodeSwitchStatement")) {
275*b5893f02SDimitry Andric expandOpcodeSwitchStatement(OS, Rec->getValueAsListOfDefs("Cases"),
276*b5893f02SDimitry Andric Rec->getValueAsDef("DefaultCase"));
277*b5893f02SDimitry Andric return;
278*b5893f02SDimitry Andric }
279*b5893f02SDimitry Andric
280*b5893f02SDimitry Andric if (Rec->isSubClassOf("MCReturnStatement")) {
281*b5893f02SDimitry Andric expandReturnStatement(OS, Rec->getValueAsDef("Pred"));
282*b5893f02SDimitry Andric return;
283*b5893f02SDimitry Andric }
284*b5893f02SDimitry Andric
285*b5893f02SDimitry Andric llvm_unreachable("No known rules to expand this MCStatement");
286*b5893f02SDimitry Andric }
287*b5893f02SDimitry Andric
expandPredicate(raw_ostream & OS,const Record * Rec)288*b5893f02SDimitry Andric void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) {
289*b5893f02SDimitry Andric // Assume that padding has been added by the caller.
2904ba319b5SDimitry Andric if (Rec->isSubClassOf("MCTrue")) {
2914ba319b5SDimitry Andric if (shouldNegate())
2924ba319b5SDimitry Andric return expandFalse(OS);
2934ba319b5SDimitry Andric return expandTrue(OS);
2944ba319b5SDimitry Andric }
2954ba319b5SDimitry Andric
2964ba319b5SDimitry Andric if (Rec->isSubClassOf("MCFalse")) {
2974ba319b5SDimitry Andric if (shouldNegate())
2984ba319b5SDimitry Andric return expandTrue(OS);
2994ba319b5SDimitry Andric return expandFalse(OS);
3004ba319b5SDimitry Andric }
3014ba319b5SDimitry Andric
3024ba319b5SDimitry Andric if (Rec->isSubClassOf("CheckNot")) {
3034ba319b5SDimitry Andric flipNegatePredicate();
3044ba319b5SDimitry Andric expandPredicate(OS, Rec->getValueAsDef("Pred"));
3054ba319b5SDimitry Andric flipNegatePredicate();
3064ba319b5SDimitry Andric return;
3074ba319b5SDimitry Andric }
3084ba319b5SDimitry Andric
3094ba319b5SDimitry Andric if (Rec->isSubClassOf("CheckIsRegOperand"))
3104ba319b5SDimitry Andric return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex"));
3114ba319b5SDimitry Andric
3124ba319b5SDimitry Andric if (Rec->isSubClassOf("CheckIsImmOperand"))
3134ba319b5SDimitry Andric return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex"));
3144ba319b5SDimitry Andric
3154ba319b5SDimitry Andric if (Rec->isSubClassOf("CheckRegOperand"))
3164ba319b5SDimitry Andric return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"),
317*b5893f02SDimitry Andric Rec->getValueAsDef("Reg"),
318*b5893f02SDimitry Andric Rec->getValueAsString("FunctionMapper"));
319*b5893f02SDimitry Andric
320*b5893f02SDimitry Andric if (Rec->isSubClassOf("CheckRegOperandSimple"))
321*b5893f02SDimitry Andric return expandCheckRegOperandSimple(OS, Rec->getValueAsInt("OpIndex"),
322*b5893f02SDimitry Andric Rec->getValueAsString("FunctionMapper"));
3234ba319b5SDimitry Andric
3244ba319b5SDimitry Andric if (Rec->isSubClassOf("CheckInvalidRegOperand"))
3254ba319b5SDimitry Andric return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex"));
3264ba319b5SDimitry Andric
3274ba319b5SDimitry Andric if (Rec->isSubClassOf("CheckImmOperand"))
3284ba319b5SDimitry Andric return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
329*b5893f02SDimitry Andric Rec->getValueAsInt("ImmVal"),
330*b5893f02SDimitry Andric Rec->getValueAsString("FunctionMapper"));
3314ba319b5SDimitry Andric
3324ba319b5SDimitry Andric if (Rec->isSubClassOf("CheckImmOperand_s"))
3334ba319b5SDimitry Andric return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
334*b5893f02SDimitry Andric Rec->getValueAsString("ImmVal"),
335*b5893f02SDimitry Andric Rec->getValueAsString("FunctionMapper"));
336*b5893f02SDimitry Andric
337*b5893f02SDimitry Andric if (Rec->isSubClassOf("CheckImmOperandSimple"))
338*b5893f02SDimitry Andric return expandCheckImmOperandSimple(OS, Rec->getValueAsInt("OpIndex"),
339*b5893f02SDimitry Andric Rec->getValueAsString("FunctionMapper"));
3404ba319b5SDimitry Andric
3414ba319b5SDimitry Andric if (Rec->isSubClassOf("CheckSameRegOperand"))
3424ba319b5SDimitry Andric return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"),
3434ba319b5SDimitry Andric Rec->getValueAsInt("SecondIndex"));
3444ba319b5SDimitry Andric
3454ba319b5SDimitry Andric if (Rec->isSubClassOf("CheckNumOperands"))
3464ba319b5SDimitry Andric return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps"));
3474ba319b5SDimitry Andric
3484ba319b5SDimitry Andric if (Rec->isSubClassOf("CheckPseudo"))
3494ba319b5SDimitry Andric return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
3504ba319b5SDimitry Andric
3514ba319b5SDimitry Andric if (Rec->isSubClassOf("CheckOpcode"))
3524ba319b5SDimitry Andric return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
3534ba319b5SDimitry Andric
3544ba319b5SDimitry Andric if (Rec->isSubClassOf("CheckAll"))
3554ba319b5SDimitry Andric return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
3564ba319b5SDimitry Andric /* AllOf */ true);
3574ba319b5SDimitry Andric
3584ba319b5SDimitry Andric if (Rec->isSubClassOf("CheckAny"))
3594ba319b5SDimitry Andric return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
3604ba319b5SDimitry Andric /* AllOf */ false);
3614ba319b5SDimitry Andric
3624ba319b5SDimitry Andric if (Rec->isSubClassOf("CheckFunctionPredicate"))
3634ba319b5SDimitry Andric return expandCheckFunctionPredicate(
3644ba319b5SDimitry Andric OS, Rec->getValueAsString("MCInstFnName"),
3654ba319b5SDimitry Andric Rec->getValueAsString("MachineInstrFnName"));
3664ba319b5SDimitry Andric
3674ba319b5SDimitry Andric if (Rec->isSubClassOf("CheckNonPortable"))
3684ba319b5SDimitry Andric return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock"));
3694ba319b5SDimitry Andric
3704ba319b5SDimitry Andric if (Rec->isSubClassOf("TIIPredicate"))
371*b5893f02SDimitry Andric return expandTIIFunctionCall(OS, Rec->getValueAsString("FunctionName"));
3724ba319b5SDimitry Andric
3734ba319b5SDimitry Andric llvm_unreachable("No known rules to expand this MCInstPredicate");
3744ba319b5SDimitry Andric }
3754ba319b5SDimitry Andric
expandHeader(raw_ostream & OS,const STIPredicateFunction & Fn)376*b5893f02SDimitry Andric void STIPredicateExpander::expandHeader(raw_ostream &OS,
377*b5893f02SDimitry Andric const STIPredicateFunction &Fn) {
378*b5893f02SDimitry Andric const Record *Rec = Fn.getDeclaration();
379*b5893f02SDimitry Andric StringRef FunctionName = Rec->getValueAsString("Name");
380*b5893f02SDimitry Andric
381*b5893f02SDimitry Andric OS.indent(getIndentLevel() * 2);
382*b5893f02SDimitry Andric OS << "bool ";
383*b5893f02SDimitry Andric if (shouldExpandDefinition())
384*b5893f02SDimitry Andric OS << getClassPrefix() << "::";
385*b5893f02SDimitry Andric OS << FunctionName << "(";
386*b5893f02SDimitry Andric if (shouldExpandForMC())
387*b5893f02SDimitry Andric OS << "const MCInst " << (isByRef() ? "&" : "*") << "MI";
388*b5893f02SDimitry Andric else
389*b5893f02SDimitry Andric OS << "const MachineInstr " << (isByRef() ? "&" : "*") << "MI";
390*b5893f02SDimitry Andric if (Rec->getValueAsBit("UpdatesOpcodeMask"))
391*b5893f02SDimitry Andric OS << ", APInt &Mask";
392*b5893f02SDimitry Andric OS << (shouldExpandForMC() ? ", unsigned ProcessorID) const " : ") const ");
393*b5893f02SDimitry Andric if (shouldExpandDefinition()) {
394*b5893f02SDimitry Andric OS << "{\n";
395*b5893f02SDimitry Andric return;
396*b5893f02SDimitry Andric }
397*b5893f02SDimitry Andric
398*b5893f02SDimitry Andric if (Rec->getValueAsBit("OverridesBaseClassMember"))
399*b5893f02SDimitry Andric OS << "override";
400*b5893f02SDimitry Andric OS << ";\n";
401*b5893f02SDimitry Andric }
402*b5893f02SDimitry Andric
expandPrologue(raw_ostream & OS,const STIPredicateFunction & Fn)403*b5893f02SDimitry Andric void STIPredicateExpander::expandPrologue(raw_ostream &OS,
404*b5893f02SDimitry Andric const STIPredicateFunction &Fn) {
405*b5893f02SDimitry Andric RecVec Delegates = Fn.getDeclaration()->getValueAsListOfDefs("Delegates");
406*b5893f02SDimitry Andric bool UpdatesOpcodeMask =
407*b5893f02SDimitry Andric Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
408*b5893f02SDimitry Andric
409*b5893f02SDimitry Andric increaseIndentLevel();
410*b5893f02SDimitry Andric unsigned IndentLevel = getIndentLevel();
411*b5893f02SDimitry Andric for (const Record *Delegate : Delegates) {
412*b5893f02SDimitry Andric OS.indent(IndentLevel * 2);
413*b5893f02SDimitry Andric OS << "if (" << Delegate->getValueAsString("Name") << "(MI";
414*b5893f02SDimitry Andric if (UpdatesOpcodeMask)
415*b5893f02SDimitry Andric OS << ", Mask";
416*b5893f02SDimitry Andric if (shouldExpandForMC())
417*b5893f02SDimitry Andric OS << ", ProcessorID";
418*b5893f02SDimitry Andric OS << "))\n";
419*b5893f02SDimitry Andric OS.indent((1 + IndentLevel) * 2);
420*b5893f02SDimitry Andric OS << "return true;\n\n";
421*b5893f02SDimitry Andric }
422*b5893f02SDimitry Andric
423*b5893f02SDimitry Andric if (shouldExpandForMC())
424*b5893f02SDimitry Andric return;
425*b5893f02SDimitry Andric
426*b5893f02SDimitry Andric OS.indent(IndentLevel * 2);
427*b5893f02SDimitry Andric OS << "unsigned ProcessorID = getSchedModel().getProcessorID();\n";
428*b5893f02SDimitry Andric }
429*b5893f02SDimitry Andric
expandOpcodeGroup(raw_ostream & OS,const OpcodeGroup & Group,bool ShouldUpdateOpcodeMask)430*b5893f02SDimitry Andric void STIPredicateExpander::expandOpcodeGroup(raw_ostream &OS, const OpcodeGroup &Group,
431*b5893f02SDimitry Andric bool ShouldUpdateOpcodeMask) {
432*b5893f02SDimitry Andric const OpcodeInfo &OI = Group.getOpcodeInfo();
433*b5893f02SDimitry Andric for (const PredicateInfo &PI : OI.getPredicates()) {
434*b5893f02SDimitry Andric const APInt &ProcModelMask = PI.ProcModelMask;
435*b5893f02SDimitry Andric bool FirstProcID = true;
436*b5893f02SDimitry Andric for (unsigned I = 0, E = ProcModelMask.getActiveBits(); I < E; ++I) {
437*b5893f02SDimitry Andric if (!ProcModelMask[I])
438*b5893f02SDimitry Andric continue;
439*b5893f02SDimitry Andric
440*b5893f02SDimitry Andric if (FirstProcID) {
441*b5893f02SDimitry Andric OS.indent(getIndentLevel() * 2);
442*b5893f02SDimitry Andric OS << "if (ProcessorID == " << I;
443*b5893f02SDimitry Andric } else {
444*b5893f02SDimitry Andric OS << " || ProcessorID == " << I;
445*b5893f02SDimitry Andric }
446*b5893f02SDimitry Andric FirstProcID = false;
447*b5893f02SDimitry Andric }
448*b5893f02SDimitry Andric
449*b5893f02SDimitry Andric OS << ") {\n";
450*b5893f02SDimitry Andric
451*b5893f02SDimitry Andric increaseIndentLevel();
452*b5893f02SDimitry Andric OS.indent(getIndentLevel() * 2);
453*b5893f02SDimitry Andric if (ShouldUpdateOpcodeMask) {
454*b5893f02SDimitry Andric if (PI.OperandMask.isNullValue())
455*b5893f02SDimitry Andric OS << "Mask.clearAllBits();\n";
456*b5893f02SDimitry Andric else
457*b5893f02SDimitry Andric OS << "Mask = " << PI.OperandMask << ";\n";
458*b5893f02SDimitry Andric OS.indent(getIndentLevel() * 2);
459*b5893f02SDimitry Andric }
460*b5893f02SDimitry Andric OS << "return ";
461*b5893f02SDimitry Andric expandPredicate(OS, PI.Predicate);
462*b5893f02SDimitry Andric OS << ";\n";
463*b5893f02SDimitry Andric decreaseIndentLevel();
464*b5893f02SDimitry Andric OS.indent(getIndentLevel() * 2);
465*b5893f02SDimitry Andric OS << "}\n";
466*b5893f02SDimitry Andric }
467*b5893f02SDimitry Andric }
468*b5893f02SDimitry Andric
expandBody(raw_ostream & OS,const STIPredicateFunction & Fn)469*b5893f02SDimitry Andric void STIPredicateExpander::expandBody(raw_ostream &OS,
470*b5893f02SDimitry Andric const STIPredicateFunction &Fn) {
471*b5893f02SDimitry Andric bool UpdatesOpcodeMask =
472*b5893f02SDimitry Andric Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
473*b5893f02SDimitry Andric
474*b5893f02SDimitry Andric unsigned IndentLevel = getIndentLevel();
475*b5893f02SDimitry Andric OS.indent(IndentLevel * 2);
476*b5893f02SDimitry Andric OS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
477*b5893f02SDimitry Andric OS.indent(IndentLevel * 2);
478*b5893f02SDimitry Andric OS << "default:\n";
479*b5893f02SDimitry Andric OS.indent(IndentLevel * 2);
480*b5893f02SDimitry Andric OS << " break;";
481*b5893f02SDimitry Andric
482*b5893f02SDimitry Andric for (const OpcodeGroup &Group : Fn.getGroups()) {
483*b5893f02SDimitry Andric for (const Record *Opcode : Group.getOpcodes()) {
484*b5893f02SDimitry Andric OS << '\n';
485*b5893f02SDimitry Andric OS.indent(IndentLevel * 2);
486*b5893f02SDimitry Andric OS << "case " << getTargetName() << "::" << Opcode->getName() << ":";
487*b5893f02SDimitry Andric }
488*b5893f02SDimitry Andric
489*b5893f02SDimitry Andric OS << '\n';
490*b5893f02SDimitry Andric increaseIndentLevel();
491*b5893f02SDimitry Andric expandOpcodeGroup(OS, Group, UpdatesOpcodeMask);
492*b5893f02SDimitry Andric
493*b5893f02SDimitry Andric OS.indent(getIndentLevel() * 2);
494*b5893f02SDimitry Andric OS << "break;\n";
495*b5893f02SDimitry Andric decreaseIndentLevel();
496*b5893f02SDimitry Andric }
497*b5893f02SDimitry Andric
498*b5893f02SDimitry Andric OS.indent(IndentLevel * 2);
499*b5893f02SDimitry Andric OS << "}\n";
500*b5893f02SDimitry Andric }
501*b5893f02SDimitry Andric
expandEpilogue(raw_ostream & OS,const STIPredicateFunction & Fn)502*b5893f02SDimitry Andric void STIPredicateExpander::expandEpilogue(raw_ostream &OS,
503*b5893f02SDimitry Andric const STIPredicateFunction &Fn) {
504*b5893f02SDimitry Andric OS << '\n';
505*b5893f02SDimitry Andric OS.indent(getIndentLevel() * 2);
506*b5893f02SDimitry Andric OS << "return ";
507*b5893f02SDimitry Andric expandPredicate(OS, Fn.getDefaultReturnPredicate());
508*b5893f02SDimitry Andric OS << ";\n";
509*b5893f02SDimitry Andric
510*b5893f02SDimitry Andric decreaseIndentLevel();
511*b5893f02SDimitry Andric OS.indent(getIndentLevel() * 2);
512*b5893f02SDimitry Andric StringRef FunctionName = Fn.getDeclaration()->getValueAsString("Name");
513*b5893f02SDimitry Andric OS << "} // " << ClassPrefix << "::" << FunctionName << "\n\n";
514*b5893f02SDimitry Andric }
515*b5893f02SDimitry Andric
expandSTIPredicate(raw_ostream & OS,const STIPredicateFunction & Fn)516*b5893f02SDimitry Andric void STIPredicateExpander::expandSTIPredicate(raw_ostream &OS,
517*b5893f02SDimitry Andric const STIPredicateFunction &Fn) {
518*b5893f02SDimitry Andric const Record *Rec = Fn.getDeclaration();
519*b5893f02SDimitry Andric if (shouldExpandForMC() && !Rec->getValueAsBit("ExpandForMC"))
520*b5893f02SDimitry Andric return;
521*b5893f02SDimitry Andric
522*b5893f02SDimitry Andric expandHeader(OS, Fn);
523*b5893f02SDimitry Andric if (shouldExpandDefinition()) {
524*b5893f02SDimitry Andric expandPrologue(OS, Fn);
525*b5893f02SDimitry Andric expandBody(OS, Fn);
526*b5893f02SDimitry Andric expandEpilogue(OS, Fn);
527*b5893f02SDimitry Andric }
528*b5893f02SDimitry Andric }
529*b5893f02SDimitry Andric
5304ba319b5SDimitry Andric } // namespace llvm
531