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::expandCheckInvalidRegOperand(formatted_raw_ostream &OS, 48 int OpIndex) { 49 OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 50 << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0"; 51 } 52 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 60 void PredicateExpander::expandCheckNumOperands(formatted_raw_ostream &OS, 61 int NumOps) { 62 OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() " 63 << (shouldNegate() ? "!= " : "== ") << NumOps; 64 } 65 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 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 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 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 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 152 void PredicateExpander::expandCheckIsRegOperand(formatted_raw_ostream &OS, 153 int OpIndex) { 154 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->") 155 << "getOperand(" << OpIndex << ").isReg() "; 156 } 157 158 void PredicateExpander::expandCheckIsImmOperand(formatted_raw_ostream &OS, 159 int OpIndex) { 160 OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->") 161 << "getOperand(" << OpIndex << ").isImm() "; 162 } 163 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 171 void PredicateExpander::expandCheckNonPortable(formatted_raw_ostream &OS, 172 StringRef Code) { 173 if (shouldExpandForMC()) 174 return expandFalse(OS); 175 176 OS << '(' << Code << ')'; 177 } 178 179 void PredicateExpander::expandReturnStatement(formatted_raw_ostream &OS, 180 const Record *Rec) { 181 OS << "return "; 182 expandPredicate(OS, Rec); 183 OS << ";"; 184 } 185 186 void PredicateExpander::expandOpcodeSwitchCase(formatted_raw_ostream &OS, 187 const Record *Rec) { 188 const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes"); 189 for (const Record *Opcode : Opcodes) { 190 OS.PadToColumn(getIndentLevel() * 2); 191 OS << "case " << Opcode->getValueAsString("Namespace") 192 << "::" << Opcode->getName() << " :\n"; 193 } 194 195 increaseIndentLevel(); 196 expandStatement(OS, Rec->getValueAsDef("CaseStmt")); 197 decreaseIndentLevel(); 198 } 199 200 void PredicateExpander::expandOpcodeSwitchStatement(formatted_raw_ostream &OS, 201 const RecVec &Cases, 202 const Record *Default) { 203 OS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n"; 204 205 for (const Record *Rec : Cases) { 206 expandOpcodeSwitchCase(OS, Rec); 207 OS << '\n'; 208 } 209 210 unsigned ColNum = getIndentLevel() * 2; 211 OS.PadToColumn(ColNum); 212 213 // Expand the default case. 214 OS << "default :\n"; 215 increaseIndentLevel(); 216 expandStatement(OS, Default); 217 decreaseIndentLevel(); 218 OS << '\n'; 219 220 OS.PadToColumn(ColNum); 221 OS << "} // end of switch-stmt"; 222 } 223 224 void PredicateExpander::expandStatement(formatted_raw_ostream &OS, 225 const Record *Rec) { 226 OS.flush(); 227 unsigned ColNum = getIndentLevel() * 2; 228 if (OS.getColumn() < ColNum) 229 OS.PadToColumn(ColNum); 230 231 if (Rec->isSubClassOf("MCOpcodeSwitchStatement")) { 232 expandOpcodeSwitchStatement(OS, Rec->getValueAsListOfDefs("Cases"), 233 Rec->getValueAsDef("DefaultCase")); 234 return; 235 } 236 237 if (Rec->isSubClassOf("MCReturnStatement")) { 238 expandReturnStatement(OS, Rec->getValueAsDef("Pred")); 239 return; 240 } 241 242 llvm_unreachable("No known rules to expand this MCStatement"); 243 } 244 245 void PredicateExpander::expandPredicate(formatted_raw_ostream &OS, 246 const Record *Rec) { 247 OS.flush(); 248 unsigned ColNum = getIndentLevel() * 2; 249 if (OS.getColumn() < ColNum) 250 OS.PadToColumn(ColNum); 251 252 if (Rec->isSubClassOf("MCTrue")) { 253 if (shouldNegate()) 254 return expandFalse(OS); 255 return expandTrue(OS); 256 } 257 258 if (Rec->isSubClassOf("MCFalse")) { 259 if (shouldNegate()) 260 return expandTrue(OS); 261 return expandFalse(OS); 262 } 263 264 if (Rec->isSubClassOf("CheckNot")) { 265 flipNegatePredicate(); 266 expandPredicate(OS, Rec->getValueAsDef("Pred")); 267 flipNegatePredicate(); 268 return; 269 } 270 271 if (Rec->isSubClassOf("CheckIsRegOperand")) 272 return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex")); 273 274 if (Rec->isSubClassOf("CheckIsImmOperand")) 275 return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex")); 276 277 if (Rec->isSubClassOf("CheckRegOperand")) 278 return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"), 279 Rec->getValueAsDef("Reg")); 280 281 if (Rec->isSubClassOf("CheckInvalidRegOperand")) 282 return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex")); 283 284 if (Rec->isSubClassOf("CheckImmOperand")) 285 return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), 286 Rec->getValueAsInt("ImmVal")); 287 288 if (Rec->isSubClassOf("CheckImmOperand_s")) 289 return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), 290 Rec->getValueAsString("ImmVal")); 291 292 if (Rec->isSubClassOf("CheckSameRegOperand")) 293 return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"), 294 Rec->getValueAsInt("SecondIndex")); 295 296 if (Rec->isSubClassOf("CheckNumOperands")) 297 return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps")); 298 299 if (Rec->isSubClassOf("CheckPseudo")) 300 return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes")); 301 302 if (Rec->isSubClassOf("CheckOpcode")) 303 return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes")); 304 305 if (Rec->isSubClassOf("CheckAll")) 306 return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"), 307 /* AllOf */ true); 308 309 if (Rec->isSubClassOf("CheckAny")) 310 return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"), 311 /* AllOf */ false); 312 313 if (Rec->isSubClassOf("CheckFunctionPredicate")) 314 return expandCheckFunctionPredicate( 315 OS, Rec->getValueAsString("MCInstFnName"), 316 Rec->getValueAsString("MachineInstrFnName")); 317 318 if (Rec->isSubClassOf("CheckNonPortable")) 319 return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock")); 320 321 if (Rec->isSubClassOf("TIIPredicate")) 322 return expandTIIFunctionCall(OS, Rec->getValueAsString("TargetName"), 323 Rec->getValueAsString("FunctionName")); 324 325 llvm_unreachable("No known rules to expand this MCInstPredicate"); 326 } 327 328 } // namespace llvm 329