1 //===--------------------- PredicateExpander.cpp --------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 /// Functionalities used by the Tablegen backends to expand machine predicates.
12 //===----------------------------------------------------------------------===//
14 #include "PredicateExpander.h"
18 void PredicateExpander::expandTrue(formatted_raw_ostream &OS) { OS << "true"; }
19 void PredicateExpander::expandFalse(formatted_raw_ostream &OS) {
23 void PredicateExpander::expandCheckImmOperand(formatted_raw_ostream &OS,
24 int OpIndex, int ImmVal) {
25 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
26 << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal;
29 void PredicateExpander::expandCheckImmOperand(formatted_raw_ostream &OS,
30 int OpIndex, StringRef ImmVal) {
31 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
32 << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal;
35 void PredicateExpander::expandCheckRegOperand(formatted_raw_ostream &OS,
36 int OpIndex, const Record *Reg) {
37 assert(Reg->isSubClassOf("Register") && "Expected a register Record!");
39 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
40 << ").getReg() " << (shouldNegate() ? "!= " : "== ");
41 const StringRef Str = Reg->getValueAsString("Namespace");
47 void PredicateExpander::expandCheckSameRegOperand(formatted_raw_ostream &OS,
48 int First, int Second) {
49 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First
50 << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI"
51 << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()";
54 void PredicateExpander::expandCheckNumOperands(formatted_raw_ostream &OS,
56 OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() "
57 << (shouldNegate() ? "!= " : "== ") << NumOps;
60 void PredicateExpander::expandCheckOpcode(formatted_raw_ostream &OS,
62 OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() "
63 << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace")
64 << "::" << Inst->getName();
67 void PredicateExpander::expandCheckOpcode(formatted_raw_ostream &OS,
68 const RecVec &Opcodes) {
69 assert(!Opcodes.empty() && "Expected at least one opcode to check!");
72 if (Opcodes.size() == 1) {
74 expandCheckOpcode(OS, Opcodes[0]);
80 increaseIndentLevel();
81 for (const Record *Rec : Opcodes) {
83 OS.PadToColumn(getIndentLevel() * 2);
85 OS << (shouldNegate() ? "&& " : "|| ");
87 expandCheckOpcode(OS, Rec);
92 decreaseIndentLevel();
93 OS.PadToColumn(getIndentLevel() * 2);
97 void PredicateExpander::expandCheckPseudo(formatted_raw_ostream &OS,
98 const RecVec &Opcodes) {
99 if (shouldExpandForMC())
102 expandCheckOpcode(OS, Opcodes);
105 void PredicateExpander::expandPredicateSequence(formatted_raw_ostream &OS,
106 const RecVec &Sequence,
108 assert(!Sequence.empty() && "Found an invalid empty predicate set!");
109 if (Sequence.size() == 1)
110 return expandPredicate(OS, Sequence[0]);
112 // Okay, there is more than one predicate in the set.
114 OS << (shouldNegate() ? "!(" : "(");
115 increaseIndentLevel();
117 bool OldValue = shouldNegate();
118 setNegatePredicate(false);
119 for (const Record *Rec : Sequence) {
121 OS.PadToColumn(getIndentLevel() * 2);
123 OS << (IsCheckAll ? "&& " : "|| ");
124 expandPredicate(OS, Rec);
128 decreaseIndentLevel();
129 OS.PadToColumn(getIndentLevel() * 2);
131 setNegatePredicate(OldValue);
134 void PredicateExpander::expandTIIFunctionCall(formatted_raw_ostream &OS,
135 StringRef TargetName,
136 StringRef MethodName) {
137 OS << (shouldNegate() ? "!" : "");
138 if (shouldExpandForMC())
139 OS << TargetName << "_MC::";
141 OS << TargetName << "Gen"
143 OS << MethodName << (isByRef() ? "(MI)" : "(*MI)");
146 void PredicateExpander::expandCheckIsRegOperand(formatted_raw_ostream &OS,
148 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
149 << "getOperand(" << OpIndex << ").isReg() ";
152 void PredicateExpander::expandCheckIsImmOperand(formatted_raw_ostream &OS,
154 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
155 << "getOperand(" << OpIndex << ").isImm() ";
158 void PredicateExpander::expandCheckFunctionPredicate(formatted_raw_ostream &OS,
160 StringRef MachineInstrFn) {
161 OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn)
162 << (isByRef() ? "(MI)" : "(*MI)");
165 void PredicateExpander::expandCheckNonPortable(formatted_raw_ostream &OS,
167 if (shouldExpandForMC())
168 return expandFalse(OS);
170 OS << '(' << Code << ')';
173 void PredicateExpander::expandPredicate(formatted_raw_ostream &OS,
176 unsigned ColNum = getIndentLevel() * 2;
177 if (OS.getColumn() < ColNum)
178 OS.PadToColumn(ColNum);
180 if (Rec->isSubClassOf("MCTrue")) {
182 return expandFalse(OS);
183 return expandTrue(OS);
186 if (Rec->isSubClassOf("MCFalse")) {
188 return expandTrue(OS);
189 return expandFalse(OS);
192 if (Rec->isSubClassOf("CheckNot")) {
193 flipNegatePredicate();
194 expandPredicate(OS, Rec->getValueAsDef("Pred"));
195 flipNegatePredicate();
199 if (Rec->isSubClassOf("CheckIsRegOperand"))
200 return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex"));
202 if (Rec->isSubClassOf("CheckIsImmOperand"))
203 return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex"));
205 if (Rec->isSubClassOf("CheckRegOperand"))
206 return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"),
207 Rec->getValueAsDef("Reg"));
209 if (Rec->isSubClassOf("CheckImmOperand"))
210 return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
211 Rec->getValueAsInt("ImmVal"));
213 if (Rec->isSubClassOf("CheckImmOperand_s"))
214 return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
215 Rec->getValueAsString("ImmVal"));
217 if (Rec->isSubClassOf("CheckSameRegOperand"))
218 return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"),
219 Rec->getValueAsInt("SecondIndex"));
221 if (Rec->isSubClassOf("CheckNumOperands"))
222 return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps"));
224 if (Rec->isSubClassOf("CheckPseudo"))
225 return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
227 if (Rec->isSubClassOf("CheckOpcode"))
228 return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
230 if (Rec->isSubClassOf("CheckAll"))
231 return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
234 if (Rec->isSubClassOf("CheckAny"))
235 return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
238 if (Rec->isSubClassOf("CheckFunctionPredicate"))
239 return expandCheckFunctionPredicate(
240 OS, Rec->getValueAsString("MCInstFnName"),
241 Rec->getValueAsString("MachineInstrFnName"));
243 if (Rec->isSubClassOf("CheckNonPortable"))
244 return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock"));
246 if (Rec->isSubClassOf("TIIPredicate"))
247 return expandTIIFunctionCall(OS, Rec->getValueAsString("TargetName"),
248 Rec->getValueAsString("FunctionName"));
250 llvm_unreachable("No known rules to expand this MCInstPredicate");