blob: 0882ab84b984b3401adde1293e68f6d728019564 [file] [log] [blame]
Andrea Di Biagio95140022018-05-25 15:55:37 +00001//===--------------------- 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
16namespace llvm {
17
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000018void PredicateExpander::expandTrue(raw_ostream &OS) { OS << "true"; }
19void PredicateExpander::expandFalse(raw_ostream &OS) { OS << "false"; }
Andrea Di Biagio95140022018-05-25 15:55:37 +000020
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000021void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
22 int ImmVal) {
Andrea Di Biagioad0293c2018-07-17 16:11:37 +000023 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
24 << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal;
Andrea Di Biagio95140022018-05-25 15:55:37 +000025}
26
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000027void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
28 StringRef ImmVal) {
Andrea Di Biagioad0293c2018-07-17 16:11:37 +000029 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
30 << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal;
Andrea Di Biagio95140022018-05-25 15:55:37 +000031}
32
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000033void PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex,
34 const Record *Reg) {
Andrea Di Biagio95140022018-05-25 15:55:37 +000035 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
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000045void PredicateExpander::expandCheckInvalidRegOperand(raw_ostream &OS,
Andrea Di Biagio9a2e9db2018-07-18 11:03:22 +000046 int OpIndex) {
47 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
48 << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0";
49}
50
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000051void PredicateExpander::expandCheckSameRegOperand(raw_ostream &OS, int First,
52 int Second) {
Andrea Di Biagio95140022018-05-25 15:55:37 +000053 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First
54 << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI"
55 << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()";
56}
57
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000058void PredicateExpander::expandCheckNumOperands(raw_ostream &OS, int NumOps) {
Andrea Di Biagio95140022018-05-25 15:55:37 +000059 OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() "
60 << (shouldNegate() ? "!= " : "== ") << NumOps;
61}
62
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000063void PredicateExpander::expandCheckOpcode(raw_ostream &OS, const Record *Inst) {
Andrea Di Biagio95140022018-05-25 15:55:37 +000064 OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() "
65 << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace")
66 << "::" << Inst->getName();
67}
68
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000069void PredicateExpander::expandCheckOpcode(raw_ostream &OS,
Andrea Di Biagio95140022018-05-25 15:55:37 +000070 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';
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000085 OS.indent(getIndentLevel() * 2);
Andrea Di Biagio95140022018-05-25 15:55:37 +000086 if (!First)
87 OS << (shouldNegate() ? "&& " : "|| ");
88
89 expandCheckOpcode(OS, Rec);
90 First = false;
91 }
92
93 OS << '\n';
94 decreaseIndentLevel();
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000095 OS.indent(getIndentLevel() * 2);
Andrea Di Biagio95140022018-05-25 15:55:37 +000096 OS << ')';
97}
98
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +000099void PredicateExpander::expandCheckPseudo(raw_ostream &OS,
Andrea Di Biagio95140022018-05-25 15:55:37 +0000100 const RecVec &Opcodes) {
101 if (shouldExpandForMC())
102 expandFalse(OS);
103 else
104 expandCheckOpcode(OS, Opcodes);
105}
106
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000107void PredicateExpander::expandPredicateSequence(raw_ostream &OS,
Andrea Di Biagio95140022018-05-25 15:55:37 +0000108 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';
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000123 OS.indent(getIndentLevel() * 2);
Andrea Di Biagio95140022018-05-25 15:55:37 +0000124 if (!First)
125 OS << (IsCheckAll ? "&& " : "|| ");
126 expandPredicate(OS, Rec);
127 First = false;
128 }
129 OS << '\n';
130 decreaseIndentLevel();
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000131 OS.indent(getIndentLevel() * 2);
Andrea Di Biagio95140022018-05-25 15:55:37 +0000132 OS << ')';
133 setNegatePredicate(OldValue);
134}
135
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000136void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS,
Andrea Di Biagio95140022018-05-25 15:55:37 +0000137 StringRef MethodName) {
138 OS << (shouldNegate() ? "!" : "");
Andrea Di Biagio9eaf5aa2018-08-14 18:36:54 +0000139 OS << TargetName << (shouldExpandForMC() ? "_MC::" : "GenInstrInfo::");
Andrea Di Biagio95140022018-05-25 15:55:37 +0000140 OS << MethodName << (isByRef() ? "(MI)" : "(*MI)");
141}
142
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000143void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) {
Andrea Di Biagio95140022018-05-25 15:55:37 +0000144 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
145 << "getOperand(" << OpIndex << ").isReg() ";
146}
147
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000148void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) {
Andrea Di Biagio95140022018-05-25 15:55:37 +0000149 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
150 << "getOperand(" << OpIndex << ").isImm() ";
151}
152
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000153void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS,
Andrea Di Biagio95140022018-05-25 15:55:37 +0000154 StringRef MCInstFn,
155 StringRef MachineInstrFn) {
156 OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn)
157 << (isByRef() ? "(MI)" : "(*MI)");
158}
159
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000160void PredicateExpander::expandCheckNonPortable(raw_ostream &OS,
Andrea Di Biagio95140022018-05-25 15:55:37 +0000161 StringRef Code) {
162 if (shouldExpandForMC())
163 return expandFalse(OS);
164
165 OS << '(' << Code << ')';
166}
167
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000168void PredicateExpander::expandReturnStatement(raw_ostream &OS,
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000169 const Record *Rec) {
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000170 std::string Buffer;
171 raw_string_ostream SS(Buffer);
172
173 SS << "return ";
174 expandPredicate(SS, Rec);
175 SS << ";";
176 SS.flush();
177 OS << Buffer;
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000178}
179
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000180void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS,
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000181 const Record *Rec) {
182 const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes");
183 for (const Record *Opcode : Opcodes) {
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000184 OS.indent(getIndentLevel() * 2);
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000185 OS << "case " << Opcode->getValueAsString("Namespace")
186 << "::" << Opcode->getName() << " :\n";
187 }
188
189 increaseIndentLevel();
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000190 OS.indent(getIndentLevel() * 2);
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000191 expandStatement(OS, Rec->getValueAsDef("CaseStmt"));
192 decreaseIndentLevel();
193}
194
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000195void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS,
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000196 const RecVec &Cases,
197 const Record *Default) {
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000198 std::string Buffer;
199 raw_string_ostream SS(Buffer);
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000200
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000201 SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000202 for (const Record *Rec : Cases) {
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000203 expandOpcodeSwitchCase(SS, Rec);
204 SS << '\n';
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000205 }
206
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000207 // Expand the default case.
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000208 SS.indent(getIndentLevel() * 2);
209 SS << "default :\n";
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000210
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000211 increaseIndentLevel();
212 SS.indent(getIndentLevel() * 2);
213 expandStatement(SS, Default);
214 decreaseIndentLevel();
215 SS << '\n';
216
217 SS.indent(getIndentLevel() * 2);
218 SS << "} // end of switch-stmt";
219 SS.flush();
220 OS << Buffer;
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000221}
222
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000223void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) {
224 // Assume that padding has been added by the caller.
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000225 if (Rec->isSubClassOf("MCOpcodeSwitchStatement")) {
226 expandOpcodeSwitchStatement(OS, Rec->getValueAsListOfDefs("Cases"),
227 Rec->getValueAsDef("DefaultCase"));
228 return;
229 }
230
231 if (Rec->isSubClassOf("MCReturnStatement")) {
232 expandReturnStatement(OS, Rec->getValueAsDef("Pred"));
233 return;
234 }
235
236 llvm_unreachable("No known rules to expand this MCStatement");
237}
238
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000239void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) {
240 // Assume that padding has been added by the caller.
Andrea Di Biagio95140022018-05-25 15:55:37 +0000241 if (Rec->isSubClassOf("MCTrue")) {
242 if (shouldNegate())
243 return expandFalse(OS);
244 return expandTrue(OS);
245 }
246
247 if (Rec->isSubClassOf("MCFalse")) {
248 if (shouldNegate())
249 return expandTrue(OS);
250 return expandFalse(OS);
251 }
252
253 if (Rec->isSubClassOf("CheckNot")) {
254 flipNegatePredicate();
255 expandPredicate(OS, Rec->getValueAsDef("Pred"));
256 flipNegatePredicate();
257 return;
258 }
259
260 if (Rec->isSubClassOf("CheckIsRegOperand"))
261 return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex"));
262
263 if (Rec->isSubClassOf("CheckIsImmOperand"))
264 return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex"));
265
266 if (Rec->isSubClassOf("CheckRegOperand"))
267 return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"),
268 Rec->getValueAsDef("Reg"));
269
Andrea Di Biagio9a2e9db2018-07-18 11:03:22 +0000270 if (Rec->isSubClassOf("CheckInvalidRegOperand"))
271 return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex"));
272
Andrea Di Biagio95140022018-05-25 15:55:37 +0000273 if (Rec->isSubClassOf("CheckImmOperand"))
274 return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
275 Rec->getValueAsInt("ImmVal"));
276
277 if (Rec->isSubClassOf("CheckImmOperand_s"))
278 return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
279 Rec->getValueAsString("ImmVal"));
280
281 if (Rec->isSubClassOf("CheckSameRegOperand"))
282 return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"),
283 Rec->getValueAsInt("SecondIndex"));
284
285 if (Rec->isSubClassOf("CheckNumOperands"))
286 return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps"));
287
288 if (Rec->isSubClassOf("CheckPseudo"))
289 return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
290
291 if (Rec->isSubClassOf("CheckOpcode"))
292 return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
293
294 if (Rec->isSubClassOf("CheckAll"))
295 return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
296 /* AllOf */ true);
297
298 if (Rec->isSubClassOf("CheckAny"))
299 return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
300 /* AllOf */ false);
301
302 if (Rec->isSubClassOf("CheckFunctionPredicate"))
303 return expandCheckFunctionPredicate(
304 OS, Rec->getValueAsString("MCInstFnName"),
305 Rec->getValueAsString("MachineInstrFnName"));
306
307 if (Rec->isSubClassOf("CheckNonPortable"))
308 return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock"));
309
310 if (Rec->isSubClassOf("TIIPredicate"))
Andrea Di Biagio9eaf5aa2018-08-14 18:36:54 +0000311 return expandTIIFunctionCall(OS, Rec->getValueAsString("FunctionName"));
Andrea Di Biagio95140022018-05-25 15:55:37 +0000312
313 llvm_unreachable("No known rules to expand this MCInstPredicate");
314}
315
316} // namespace llvm