blob: ab0e67abbbde00cc33512eb73e912faeb1610187 [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 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
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000148void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) {
Andrea Di Biagio95140022018-05-25 15:55:37 +0000149 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
150 << "getOperand(" << OpIndex << ").isReg() ";
151}
152
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000153void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) {
Andrea Di Biagio95140022018-05-25 15:55:37 +0000154 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
155 << "getOperand(" << OpIndex << ").isImm() ";
156}
157
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000158void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS,
Andrea Di Biagio95140022018-05-25 15:55:37 +0000159 StringRef MCInstFn,
160 StringRef MachineInstrFn) {
161 OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn)
162 << (isByRef() ? "(MI)" : "(*MI)");
163}
164
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000165void PredicateExpander::expandCheckNonPortable(raw_ostream &OS,
Andrea Di Biagio95140022018-05-25 15:55:37 +0000166 StringRef Code) {
167 if (shouldExpandForMC())
168 return expandFalse(OS);
169
170 OS << '(' << Code << ')';
171}
172
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000173void PredicateExpander::expandReturnStatement(raw_ostream &OS,
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000174 const Record *Rec) {
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000175 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;
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000183}
184
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000185void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS,
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000186 const Record *Rec) {
187 const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes");
188 for (const Record *Opcode : Opcodes) {
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000189 OS.indent(getIndentLevel() * 2);
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000190 OS << "case " << Opcode->getValueAsString("Namespace")
191 << "::" << Opcode->getName() << " :\n";
192 }
193
194 increaseIndentLevel();
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000195 OS.indent(getIndentLevel() * 2);
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000196 expandStatement(OS, Rec->getValueAsDef("CaseStmt"));
197 decreaseIndentLevel();
198}
199
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000200void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS,
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000201 const RecVec &Cases,
202 const Record *Default) {
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000203 std::string Buffer;
204 raw_string_ostream SS(Buffer);
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000205
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000206 SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000207 for (const Record *Rec : Cases) {
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000208 expandOpcodeSwitchCase(SS, Rec);
209 SS << '\n';
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000210 }
211
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000212 // Expand the default case.
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000213 SS.indent(getIndentLevel() * 2);
214 SS << "default :\n";
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000215
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000216 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;
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000226}
227
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000228void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) {
229 // Assume that padding has been added by the caller.
Andrea Di Biagiof3bde042018-08-09 15:32:48 +0000230 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
Andrea Di Biagio2c6cbc8b2018-08-13 15:13:35 +0000244void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) {
245 // Assume that padding has been added by the caller.
Andrea Di Biagio95140022018-05-25 15:55:37 +0000246 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
Andrea Di Biagio9a2e9db2018-07-18 11:03:22 +0000275 if (Rec->isSubClassOf("CheckInvalidRegOperand"))
276 return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex"));
277
Andrea Di Biagio95140022018-05-25 15:55:37 +0000278 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