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 MethodName) { 138 OS << (shouldNegate() ? "!" : ""); 139 OS << TargetName << (shouldExpandForMC() ? "_MC::" : "GenInstrInfo::"); 140 OS << MethodName << (isByRef() ? "(MI)" : "(*MI)"); 141 } 142 143 void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) { 144 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->") 145 << "getOperand(" << OpIndex << ").isReg() "; 146 } 147 148 void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) { 149 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->") 150 << "getOperand(" << OpIndex << ").isImm() "; 151 } 152 153 void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS, 154 StringRef MCInstFn, 155 StringRef MachineInstrFn) { 156 OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn) 157 << (isByRef() ? "(MI)" : "(*MI)"); 158 } 159 160 void PredicateExpander::expandCheckNonPortable(raw_ostream &OS, 161 StringRef Code) { 162 if (shouldExpandForMC()) 163 return expandFalse(OS); 164 165 OS << '(' << Code << ')'; 166 } 167 168 void PredicateExpander::expandReturnStatement(raw_ostream &OS, 169 const Record *Rec) { 170 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; 178 } 179 180 void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS, 181 const Record *Rec) { 182 const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes"); 183 for (const Record *Opcode : Opcodes) { 184 OS.indent(getIndentLevel() * 2); 185 OS << "case " << Opcode->getValueAsString("Namespace") 186 << "::" << Opcode->getName() << " :\n"; 187 } 188 189 increaseIndentLevel(); 190 OS.indent(getIndentLevel() * 2); 191 expandStatement(OS, Rec->getValueAsDef("CaseStmt")); 192 decreaseIndentLevel(); 193 } 194 195 void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS, 196 const RecVec &Cases, 197 const Record *Default) { 198 std::string Buffer; 199 raw_string_ostream SS(Buffer); 200 201 SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n"; 202 for (const Record *Rec : Cases) { 203 expandOpcodeSwitchCase(SS, Rec); 204 SS << '\n'; 205 } 206 207 // Expand the default case. 208 SS.indent(getIndentLevel() * 2); 209 SS << "default :\n"; 210 211 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; 221 } 222 223 void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) { 224 // Assume that padding has been added by the caller. 225 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 239 void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) { 240 // Assume that padding has been added by the caller. 241 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 270 if (Rec->isSubClassOf("CheckInvalidRegOperand")) 271 return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex")); 272 273 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")) 311 return expandTIIFunctionCall(OS, Rec->getValueAsString("FunctionName")); 312 313 llvm_unreachable("No known rules to expand this MCInstPredicate"); 314 } 315 316 } // namespace llvm 317