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 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 148 void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) { 149 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->") 150 << "getOperand(" << OpIndex << ").isReg() "; 151 } 152 153 void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) { 154 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->") 155 << "getOperand(" << OpIndex << ").isImm() "; 156 } 157 158 void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS, 159 StringRef MCInstFn, 160 StringRef MachineInstrFn) { 161 OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn) 162 << (isByRef() ? "(MI)" : "(*MI)"); 163 } 164 165 void PredicateExpander::expandCheckNonPortable(raw_ostream &OS, 166 StringRef Code) { 167 if (shouldExpandForMC()) 168 return expandFalse(OS); 169 170 OS << '(' << Code << ')'; 171 } 172 173 void PredicateExpander::expandReturnStatement(raw_ostream &OS, 174 const Record *Rec) { 175 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; 183 } 184 185 void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS, 186 const Record *Rec) { 187 const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes"); 188 for (const Record *Opcode : Opcodes) { 189 OS.indent(getIndentLevel() * 2); 190 OS << "case " << Opcode->getValueAsString("Namespace") 191 << "::" << Opcode->getName() << " :\n"; 192 } 193 194 increaseIndentLevel(); 195 OS.indent(getIndentLevel() * 2); 196 expandStatement(OS, Rec->getValueAsDef("CaseStmt")); 197 decreaseIndentLevel(); 198 } 199 200 void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS, 201 const RecVec &Cases, 202 const Record *Default) { 203 std::string Buffer; 204 raw_string_ostream SS(Buffer); 205 206 SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n"; 207 for (const Record *Rec : Cases) { 208 expandOpcodeSwitchCase(SS, Rec); 209 SS << '\n'; 210 } 211 212 // Expand the default case. 213 SS.indent(getIndentLevel() * 2); 214 SS << "default :\n"; 215 216 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; 226 } 227 228 void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) { 229 // Assume that padding has been added by the caller. 230 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 244 void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) { 245 // Assume that padding has been added by the caller. 246 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 275 if (Rec->isSubClassOf("CheckInvalidRegOperand")) 276 return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex")); 277 278 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 323