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
expandTrue(formatted_raw_ostream & OS)18 void PredicateExpander::expandTrue(formatted_raw_ostream &OS) { OS << "true"; }
expandFalse(formatted_raw_ostream & OS)19 void PredicateExpander::expandFalse(formatted_raw_ostream &OS) {
20 OS << "false";
21 }
22
expandCheckImmOperand(formatted_raw_ostream & OS,int OpIndex,int ImmVal)23 void PredicateExpander::expandCheckImmOperand(formatted_raw_ostream &OS,
24 int OpIndex, int ImmVal) {
25 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
26 << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal;
27 }
28
expandCheckImmOperand(formatted_raw_ostream & OS,int OpIndex,StringRef ImmVal)29 void PredicateExpander::expandCheckImmOperand(formatted_raw_ostream &OS,
30 int OpIndex, StringRef ImmVal) {
31 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
32 << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal;
33 }
34
expandCheckRegOperand(formatted_raw_ostream & OS,int OpIndex,const Record * Reg)35 void PredicateExpander::expandCheckRegOperand(formatted_raw_ostream &OS,
36 int OpIndex, const Record *Reg) {
37 assert(Reg->isSubClassOf("Register") && "Expected a register Record!");
38
39 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
40 << ").getReg() " << (shouldNegate() ? "!= " : "== ");
41 const StringRef Str = Reg->getValueAsString("Namespace");
42 if (!Str.empty())
43 OS << Str << "::";
44 OS << Reg->getName();
45 }
46
expandCheckInvalidRegOperand(formatted_raw_ostream & OS,int OpIndex)47 void PredicateExpander::expandCheckInvalidRegOperand(formatted_raw_ostream &OS,
48 int OpIndex) {
49 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
50 << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0";
51 }
52
expandCheckSameRegOperand(formatted_raw_ostream & OS,int First,int Second)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()";
58 }
59
expandCheckNumOperands(formatted_raw_ostream & OS,int NumOps)60 void PredicateExpander::expandCheckNumOperands(formatted_raw_ostream &OS,
61 int NumOps) {
62 OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() "
63 << (shouldNegate() ? "!= " : "== ") << NumOps;
64 }
65
expandCheckOpcode(formatted_raw_ostream & OS,const Record * Inst)66 void PredicateExpander::expandCheckOpcode(formatted_raw_ostream &OS,
67 const Record *Inst) {
68 OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() "
69 << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace")
70 << "::" << Inst->getName();
71 }
72
expandCheckOpcode(formatted_raw_ostream & OS,const RecVec & Opcodes)73 void PredicateExpander::expandCheckOpcode(formatted_raw_ostream &OS,
74 const RecVec &Opcodes) {
75 assert(!Opcodes.empty() && "Expected at least one opcode to check!");
76 bool First = true;
77
78 if (Opcodes.size() == 1) {
79 OS << "( ";
80 expandCheckOpcode(OS, Opcodes[0]);
81 OS << " )";
82 return;
83 }
84
85 OS << '(';
86 increaseIndentLevel();
87 for (const Record *Rec : Opcodes) {
88 OS << '\n';
89 OS.PadToColumn(getIndentLevel() * 2);
90 if (!First)
91 OS << (shouldNegate() ? "&& " : "|| ");
92
93 expandCheckOpcode(OS, Rec);
94 First = false;
95 }
96
97 OS << '\n';
98 decreaseIndentLevel();
99 OS.PadToColumn(getIndentLevel() * 2);
100 OS << ')';
101 }
102
expandCheckPseudo(formatted_raw_ostream & OS,const RecVec & Opcodes)103 void PredicateExpander::expandCheckPseudo(formatted_raw_ostream &OS,
104 const RecVec &Opcodes) {
105 if (shouldExpandForMC())
106 expandFalse(OS);
107 else
108 expandCheckOpcode(OS, Opcodes);
109 }
110
expandPredicateSequence(formatted_raw_ostream & OS,const RecVec & Sequence,bool IsCheckAll)111 void PredicateExpander::expandPredicateSequence(formatted_raw_ostream &OS,
112 const RecVec &Sequence,
113 bool IsCheckAll) {
114 assert(!Sequence.empty() && "Found an invalid empty predicate set!");
115 if (Sequence.size() == 1)
116 return expandPredicate(OS, Sequence[0]);
117
118 // Okay, there is more than one predicate in the set.
119 bool First = true;
120 OS << (shouldNegate() ? "!(" : "(");
121 increaseIndentLevel();
122
123 bool OldValue = shouldNegate();
124 setNegatePredicate(false);
125 for (const Record *Rec : Sequence) {
126 OS << '\n';
127 OS.PadToColumn(getIndentLevel() * 2);
128 if (!First)
129 OS << (IsCheckAll ? "&& " : "|| ");
130 expandPredicate(OS, Rec);
131 First = false;
132 }
133 OS << '\n';
134 decreaseIndentLevel();
135 OS.PadToColumn(getIndentLevel() * 2);
136 OS << ')';
137 setNegatePredicate(OldValue);
138 }
139
expandTIIFunctionCall(formatted_raw_ostream & OS,StringRef TargetName,StringRef MethodName)140 void PredicateExpander::expandTIIFunctionCall(formatted_raw_ostream &OS,
141 StringRef TargetName,
142 StringRef MethodName) {
143 OS << (shouldNegate() ? "!" : "");
144 if (shouldExpandForMC())
145 OS << TargetName << "_MC::";
146 else
147 OS << TargetName << "Gen"
148 << "InstrInfo::";
149 OS << MethodName << (isByRef() ? "(MI)" : "(*MI)");
150 }
151
expandCheckIsRegOperand(formatted_raw_ostream & OS,int OpIndex)152 void PredicateExpander::expandCheckIsRegOperand(formatted_raw_ostream &OS,
153 int OpIndex) {
154 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
155 << "getOperand(" << OpIndex << ").isReg() ";
156 }
157
expandCheckIsImmOperand(formatted_raw_ostream & OS,int OpIndex)158 void PredicateExpander::expandCheckIsImmOperand(formatted_raw_ostream &OS,
159 int OpIndex) {
160 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
161 << "getOperand(" << OpIndex << ").isImm() ";
162 }
163
expandCheckFunctionPredicate(formatted_raw_ostream & OS,StringRef MCInstFn,StringRef MachineInstrFn)164 void PredicateExpander::expandCheckFunctionPredicate(formatted_raw_ostream &OS,
165 StringRef MCInstFn,
166 StringRef MachineInstrFn) {
167 OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn)
168 << (isByRef() ? "(MI)" : "(*MI)");
169 }
170
expandCheckNonPortable(formatted_raw_ostream & OS,StringRef Code)171 void PredicateExpander::expandCheckNonPortable(formatted_raw_ostream &OS,
172 StringRef Code) {
173 if (shouldExpandForMC())
174 return expandFalse(OS);
175
176 OS << '(' << Code << ')';
177 }
178
expandPredicate(formatted_raw_ostream & OS,const Record * Rec)179 void PredicateExpander::expandPredicate(formatted_raw_ostream &OS,
180 const Record *Rec) {
181 OS.flush();
182 unsigned ColNum = getIndentLevel() * 2;
183 if (OS.getColumn() < ColNum)
184 OS.PadToColumn(ColNum);
185
186 if (Rec->isSubClassOf("MCTrue")) {
187 if (shouldNegate())
188 return expandFalse(OS);
189 return expandTrue(OS);
190 }
191
192 if (Rec->isSubClassOf("MCFalse")) {
193 if (shouldNegate())
194 return expandTrue(OS);
195 return expandFalse(OS);
196 }
197
198 if (Rec->isSubClassOf("CheckNot")) {
199 flipNegatePredicate();
200 expandPredicate(OS, Rec->getValueAsDef("Pred"));
201 flipNegatePredicate();
202 return;
203 }
204
205 if (Rec->isSubClassOf("CheckIsRegOperand"))
206 return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex"));
207
208 if (Rec->isSubClassOf("CheckIsImmOperand"))
209 return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex"));
210
211 if (Rec->isSubClassOf("CheckRegOperand"))
212 return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"),
213 Rec->getValueAsDef("Reg"));
214
215 if (Rec->isSubClassOf("CheckInvalidRegOperand"))
216 return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex"));
217
218 if (Rec->isSubClassOf("CheckImmOperand"))
219 return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
220 Rec->getValueAsInt("ImmVal"));
221
222 if (Rec->isSubClassOf("CheckImmOperand_s"))
223 return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
224 Rec->getValueAsString("ImmVal"));
225
226 if (Rec->isSubClassOf("CheckSameRegOperand"))
227 return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"),
228 Rec->getValueAsInt("SecondIndex"));
229
230 if (Rec->isSubClassOf("CheckNumOperands"))
231 return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps"));
232
233 if (Rec->isSubClassOf("CheckPseudo"))
234 return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
235
236 if (Rec->isSubClassOf("CheckOpcode"))
237 return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
238
239 if (Rec->isSubClassOf("CheckAll"))
240 return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
241 /* AllOf */ true);
242
243 if (Rec->isSubClassOf("CheckAny"))
244 return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
245 /* AllOf */ false);
246
247 if (Rec->isSubClassOf("CheckFunctionPredicate"))
248 return expandCheckFunctionPredicate(
249 OS, Rec->getValueAsString("MCInstFnName"),
250 Rec->getValueAsString("MachineInstrFnName"));
251
252 if (Rec->isSubClassOf("CheckNonPortable"))
253 return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock"));
254
255 if (Rec->isSubClassOf("TIIPredicate"))
256 return expandTIIFunctionCall(OS, Rec->getValueAsString("TargetName"),
257 Rec->getValueAsString("FunctionName"));
258
259 llvm_unreachable("No known rules to expand this MCInstPredicate");
260 }
261
262 } // namespace llvm
263