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::expandCheckInvalidRegOperand(formatted_raw_ostream &OS,
49 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
50 << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0";
53 void PredicateExpander::expandCheckSameRegOperand(formatted_raw_ostream &OS,
54 int First, int Second) {
55 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First
56 << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI"
57 << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()";
60 void PredicateExpander::expandCheckNumOperands(formatted_raw_ostream &OS,
62 OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() "
63 << (shouldNegate() ? "!= " : "== ") << NumOps;
66 void PredicateExpander::expandCheckOpcode(formatted_raw_ostream &OS,
68 OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() "
69 << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace")
70 << "::" << Inst->getName();
73 void PredicateExpander::expandCheckOpcode(formatted_raw_ostream &OS,
74 const RecVec &Opcodes) {
75 assert(!Opcodes.empty() && "Expected at least one opcode to check!");
78 if (Opcodes.size() == 1) {
80 expandCheckOpcode(OS, Opcodes[0]);
86 increaseIndentLevel();
87 for (const Record *Rec : Opcodes) {
89 OS.PadToColumn(getIndentLevel() * 2);
91 OS << (shouldNegate() ? "&& " : "|| ");
93 expandCheckOpcode(OS, Rec);
98 decreaseIndentLevel();
99 OS.PadToColumn(getIndentLevel() * 2);
103 void PredicateExpander::expandCheckPseudo(formatted_raw_ostream &OS,
104 const RecVec &Opcodes) {
105 if (shouldExpandForMC())
108 expandCheckOpcode(OS, Opcodes);
111 void PredicateExpander::expandPredicateSequence(formatted_raw_ostream &OS,
112 const RecVec &Sequence,
114 assert(!Sequence.empty() && "Found an invalid empty predicate set!");
115 if (Sequence.size() == 1)
116 return expandPredicate(OS, Sequence[0]);
118 // Okay, there is more than one predicate in the set.
120 OS << (shouldNegate() ? "!(" : "(");
121 increaseIndentLevel();
123 bool OldValue = shouldNegate();
124 setNegatePredicate(false);
125 for (const Record *Rec : Sequence) {
127 OS.PadToColumn(getIndentLevel() * 2);
129 OS << (IsCheckAll ? "&& " : "|| ");
130 expandPredicate(OS, Rec);
134 decreaseIndentLevel();
135 OS.PadToColumn(getIndentLevel() * 2);
137 setNegatePredicate(OldValue);
140 void PredicateExpander::expandTIIFunctionCall(formatted_raw_ostream &OS,
141 StringRef TargetName,
142 StringRef MethodName) {
143 OS << (shouldNegate() ? "!" : "");
144 if (shouldExpandForMC())
145 OS << TargetName << "_MC::";
147 OS << TargetName << "Gen"
149 OS << MethodName << (isByRef() ? "(MI)" : "(*MI)");
152 void PredicateExpander::expandCheckIsRegOperand(formatted_raw_ostream &OS,
154 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
155 << "getOperand(" << OpIndex << ").isReg() ";
158 void PredicateExpander::expandCheckIsImmOperand(formatted_raw_ostream &OS,
160 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
161 << "getOperand(" << OpIndex << ").isImm() ";
164 void PredicateExpander::expandCheckFunctionPredicate(formatted_raw_ostream &OS,
166 StringRef MachineInstrFn) {
167 OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn)
168 << (isByRef() ? "(MI)" : "(*MI)");
171 void PredicateExpander::expandCheckNonPortable(formatted_raw_ostream &OS,
173 if (shouldExpandForMC())
174 return expandFalse(OS);
176 OS << '(' << Code << ')';
179 void PredicateExpander::expandPredicate(formatted_raw_ostream &OS,
182 unsigned ColNum = getIndentLevel() * 2;
183 if (OS.getColumn() < ColNum)
184 OS.PadToColumn(ColNum);
186 if (Rec->isSubClassOf("MCTrue")) {
188 return expandFalse(OS);
189 return expandTrue(OS);
192 if (Rec->isSubClassOf("MCFalse")) {
194 return expandTrue(OS);
195 return expandFalse(OS);
198 if (Rec->isSubClassOf("CheckNot")) {
199 flipNegatePredicate();
200 expandPredicate(OS, Rec->getValueAsDef("Pred"));
201 flipNegatePredicate();
205 if (Rec->isSubClassOf("CheckIsRegOperand"))
206 return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex"));
208 if (Rec->isSubClassOf("CheckIsImmOperand"))
209 return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex"));
211 if (Rec->isSubClassOf("CheckRegOperand"))
212 return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"),
213 Rec->getValueAsDef("Reg"));
215 if (Rec->isSubClassOf("CheckInvalidRegOperand"))
216 return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex"));
218 if (Rec->isSubClassOf("CheckImmOperand"))
219 return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
220 Rec->getValueAsInt("ImmVal"));
222 if (Rec->isSubClassOf("CheckImmOperand_s"))
223 return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
224 Rec->getValueAsString("ImmVal"));
226 if (Rec->isSubClassOf("CheckSameRegOperand"))
227 return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"),
228 Rec->getValueAsInt("SecondIndex"));
230 if (Rec->isSubClassOf("CheckNumOperands"))
231 return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps"));
233 if (Rec->isSubClassOf("CheckPseudo"))
234 return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
236 if (Rec->isSubClassOf("CheckOpcode"))
237 return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
239 if (Rec->isSubClassOf("CheckAll"))
240 return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
243 if (Rec->isSubClassOf("CheckAny"))
244 return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
247 if (Rec->isSubClassOf("CheckFunctionPredicate"))
248 return expandCheckFunctionPredicate(
249 OS, Rec->getValueAsString("MCInstFnName"),
250 Rec->getValueAsString("MachineInstrFnName"));
252 if (Rec->isSubClassOf("CheckNonPortable"))
253 return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock"));
255 if (Rec->isSubClassOf("TIIPredicate"))
256 return expandTIIFunctionCall(OS, Rec->getValueAsString("TargetName"),
257 Rec->getValueAsString("FunctionName"));
259 llvm_unreachable("No known rules to expand this MCInstPredicate");