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 254