OSDN Git Service

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