1 //===--------------------- PredicateExpander.cpp --------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 /// Functionalities used by the Tablegen backends to expand machine predicates.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "PredicateExpander.h"
15 
16 namespace llvm {
17 
18 void PredicateExpander::expandTrue(raw_ostream &OS) { OS << "true"; }
19 void PredicateExpander::expandFalse(raw_ostream &OS) { OS << "false"; }
20 
21 void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
22                                               int ImmVal) {
23   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
24      << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal;
25 }
26 
27 void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
28                                               StringRef ImmVal) {
29   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
30      << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal;
31 }
32 
33 void PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex,
34                                               const Record *Reg) {
35   assert(Reg->isSubClassOf("Register") && "Expected a register Record!");
36 
37   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
38      << ").getReg() " << (shouldNegate() ? "!= " : "== ");
39   const StringRef Str = Reg->getValueAsString("Namespace");
40   if (!Str.empty())
41     OS << Str << "::";
42   OS << Reg->getName();
43 }
44 
45 void PredicateExpander::expandCheckInvalidRegOperand(raw_ostream &OS,
46                                                      int OpIndex) {
47   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
48      << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0";
49 }
50 
51 void PredicateExpander::expandCheckSameRegOperand(raw_ostream &OS, int First,
52                                                   int Second) {
53   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First
54      << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI"
55      << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()";
56 }
57 
58 void PredicateExpander::expandCheckNumOperands(raw_ostream &OS, int NumOps) {
59   OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() "
60      << (shouldNegate() ? "!= " : "== ") << NumOps;
61 }
62 
63 void PredicateExpander::expandCheckOpcode(raw_ostream &OS, const Record *Inst) {
64   OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() "
65      << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace")
66      << "::" << Inst->getName();
67 }
68 
69 void PredicateExpander::expandCheckOpcode(raw_ostream &OS,
70                                           const RecVec &Opcodes) {
71   assert(!Opcodes.empty() && "Expected at least one opcode to check!");
72   bool First = true;
73 
74   if (Opcodes.size() == 1) {
75     OS << "( ";
76     expandCheckOpcode(OS, Opcodes[0]);
77     OS << " )";
78     return;
79   }
80 
81   OS << '(';
82   increaseIndentLevel();
83   for (const Record *Rec : Opcodes) {
84     OS << '\n';
85     OS.indent(getIndentLevel() * 2);
86     if (!First)
87       OS << (shouldNegate() ? "&& " : "|| ");
88 
89     expandCheckOpcode(OS, Rec);
90     First = false;
91   }
92 
93   OS << '\n';
94   decreaseIndentLevel();
95   OS.indent(getIndentLevel() * 2);
96   OS << ')';
97 }
98 
99 void PredicateExpander::expandCheckPseudo(raw_ostream &OS,
100                                           const RecVec &Opcodes) {
101   if (shouldExpandForMC())
102     expandFalse(OS);
103   else
104     expandCheckOpcode(OS, Opcodes);
105 }
106 
107 void PredicateExpander::expandPredicateSequence(raw_ostream &OS,
108                                                 const RecVec &Sequence,
109                                                 bool IsCheckAll) {
110   assert(!Sequence.empty() && "Found an invalid empty predicate set!");
111   if (Sequence.size() == 1)
112     return expandPredicate(OS, Sequence[0]);
113 
114   // Okay, there is more than one predicate in the set.
115   bool First = true;
116   OS << (shouldNegate() ? "!(" : "(");
117   increaseIndentLevel();
118 
119   bool OldValue = shouldNegate();
120   setNegatePredicate(false);
121   for (const Record *Rec : Sequence) {
122     OS << '\n';
123     OS.indent(getIndentLevel() * 2);
124     if (!First)
125       OS << (IsCheckAll ? "&& " : "|| ");
126     expandPredicate(OS, Rec);
127     First = false;
128   }
129   OS << '\n';
130   decreaseIndentLevel();
131   OS.indent(getIndentLevel() * 2);
132   OS << ')';
133   setNegatePredicate(OldValue);
134 }
135 
136 void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS,
137                                               StringRef TargetName,
138                                               StringRef MethodName) {
139   OS << (shouldNegate() ? "!" : "");
140   if (shouldExpandForMC())
141     OS << TargetName << "_MC::";
142   else
143     OS << TargetName << "Gen"
144        << "InstrInfo::";
145   OS << MethodName << (isByRef() ? "(MI)" : "(*MI)");
146 }
147 
148 void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) {
149   OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
150      << "getOperand(" << OpIndex << ").isReg() ";
151 }
152 
153 void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) {
154   OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
155      << "getOperand(" << OpIndex << ").isImm() ";
156 }
157 
158 void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS,
159                                                      StringRef MCInstFn,
160                                                      StringRef MachineInstrFn) {
161   OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn)
162      << (isByRef() ? "(MI)" : "(*MI)");
163 }
164 
165 void PredicateExpander::expandCheckNonPortable(raw_ostream &OS,
166                                                StringRef Code) {
167   if (shouldExpandForMC())
168     return expandFalse(OS);
169 
170   OS << '(' << Code << ')';
171 }
172 
173 void PredicateExpander::expandReturnStatement(raw_ostream &OS,
174                                               const Record *Rec) {
175   std::string Buffer;
176   raw_string_ostream SS(Buffer);
177 
178   SS << "return ";
179   expandPredicate(SS, Rec);
180   SS << ";";
181   SS.flush();
182   OS << Buffer;
183 }
184 
185 void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS,
186                                                const Record *Rec) {
187   const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes");
188   for (const Record *Opcode : Opcodes) {
189     OS.indent(getIndentLevel() * 2);
190     OS << "case " << Opcode->getValueAsString("Namespace")
191        << "::" << Opcode->getName() << " :\n";
192   }
193 
194   increaseIndentLevel();
195   OS.indent(getIndentLevel() * 2);
196   expandStatement(OS, Rec->getValueAsDef("CaseStmt"));
197   decreaseIndentLevel();
198 }
199 
200 void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS,
201                                                     const RecVec &Cases,
202                                                     const Record *Default) {
203   std::string Buffer;
204   raw_string_ostream SS(Buffer);
205 
206   SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
207   for (const Record *Rec : Cases) {
208     expandOpcodeSwitchCase(SS, Rec);
209     SS << '\n';
210   }
211 
212   // Expand the default case.
213   SS.indent(getIndentLevel() * 2);
214   SS << "default :\n";
215 
216   increaseIndentLevel();
217   SS.indent(getIndentLevel() * 2);
218   expandStatement(SS, Default);
219   decreaseIndentLevel();
220   SS << '\n';
221 
222   SS.indent(getIndentLevel() * 2);
223   SS << "} // end of switch-stmt";
224   SS.flush();
225   OS << Buffer;
226 }
227 
228 void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) {
229   // Assume that padding has been added by the caller.
230   if (Rec->isSubClassOf("MCOpcodeSwitchStatement")) {
231     expandOpcodeSwitchStatement(OS, Rec->getValueAsListOfDefs("Cases"),
232                                 Rec->getValueAsDef("DefaultCase"));
233     return;
234   }
235 
236   if (Rec->isSubClassOf("MCReturnStatement")) {
237     expandReturnStatement(OS, Rec->getValueAsDef("Pred"));
238     return;
239   }
240 
241   llvm_unreachable("No known rules to expand this MCStatement");
242 }
243 
244 void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) {
245   // Assume that padding has been added by the caller.
246   if (Rec->isSubClassOf("MCTrue")) {
247     if (shouldNegate())
248       return expandFalse(OS);
249     return expandTrue(OS);
250   }
251 
252   if (Rec->isSubClassOf("MCFalse")) {
253     if (shouldNegate())
254       return expandTrue(OS);
255     return expandFalse(OS);
256   }
257 
258   if (Rec->isSubClassOf("CheckNot")) {
259     flipNegatePredicate();
260     expandPredicate(OS, Rec->getValueAsDef("Pred"));
261     flipNegatePredicate();
262     return;
263   }
264 
265   if (Rec->isSubClassOf("CheckIsRegOperand"))
266     return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex"));
267 
268   if (Rec->isSubClassOf("CheckIsImmOperand"))
269     return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex"));
270 
271   if (Rec->isSubClassOf("CheckRegOperand"))
272     return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"),
273                                  Rec->getValueAsDef("Reg"));
274 
275   if (Rec->isSubClassOf("CheckInvalidRegOperand"))
276     return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex"));
277 
278   if (Rec->isSubClassOf("CheckImmOperand"))
279     return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
280                                  Rec->getValueAsInt("ImmVal"));
281 
282   if (Rec->isSubClassOf("CheckImmOperand_s"))
283     return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
284                                  Rec->getValueAsString("ImmVal"));
285 
286   if (Rec->isSubClassOf("CheckSameRegOperand"))
287     return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"),
288                                      Rec->getValueAsInt("SecondIndex"));
289 
290   if (Rec->isSubClassOf("CheckNumOperands"))
291     return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps"));
292 
293   if (Rec->isSubClassOf("CheckPseudo"))
294     return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
295 
296   if (Rec->isSubClassOf("CheckOpcode"))
297     return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
298 
299   if (Rec->isSubClassOf("CheckAll"))
300     return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
301                                    /* AllOf */ true);
302 
303   if (Rec->isSubClassOf("CheckAny"))
304     return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
305                                    /* AllOf */ false);
306 
307   if (Rec->isSubClassOf("CheckFunctionPredicate"))
308     return expandCheckFunctionPredicate(
309         OS, Rec->getValueAsString("MCInstFnName"),
310         Rec->getValueAsString("MachineInstrFnName"));
311 
312   if (Rec->isSubClassOf("CheckNonPortable"))
313     return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock"));
314 
315   if (Rec->isSubClassOf("TIIPredicate"))
316     return expandTIIFunctionCall(OS, Rec->getValueAsString("TargetName"),
317                                  Rec->getValueAsString("FunctionName"));
318 
319   llvm_unreachable("No known rules to expand this MCInstPredicate");
320 }
321 
322 } // namespace llvm
323