195140023SAndrea Di Biagio //===--------------------- PredicateExpander.cpp --------------------------===// 295140023SAndrea Di Biagio // 395140023SAndrea Di Biagio // The LLVM Compiler Infrastructure 495140023SAndrea Di Biagio // 595140023SAndrea Di Biagio // This file is distributed under the University of Illinois Open Source 695140023SAndrea Di Biagio // License. See LICENSE.TXT for details. 795140023SAndrea Di Biagio // 895140023SAndrea Di Biagio //===----------------------------------------------------------------------===// 995140023SAndrea Di Biagio /// \file 1095140023SAndrea Di Biagio /// Functionalities used by the Tablegen backends to expand machine predicates. 1195140023SAndrea Di Biagio // 1295140023SAndrea Di Biagio //===----------------------------------------------------------------------===// 1395140023SAndrea Di Biagio 1495140023SAndrea Di Biagio #include "PredicateExpander.h" 1595140023SAndrea Di Biagio 1695140023SAndrea Di Biagio namespace llvm { 1795140023SAndrea Di Biagio 18*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandTrue(raw_ostream &OS) { OS << "true"; } 19*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandFalse(raw_ostream &OS) { OS << "false"; } 2095140023SAndrea Di Biagio 21*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex, 22*2c6cbc8bSAndrea Di Biagio int ImmVal) { 23ad0293caSAndrea Di Biagio OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 24ad0293caSAndrea Di Biagio << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal; 2595140023SAndrea Di Biagio } 2695140023SAndrea Di Biagio 27*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex, 28*2c6cbc8bSAndrea Di Biagio StringRef ImmVal) { 29ad0293caSAndrea Di Biagio OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 30ad0293caSAndrea Di Biagio << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal; 3195140023SAndrea Di Biagio } 3295140023SAndrea Di Biagio 33*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex, 34*2c6cbc8bSAndrea Di Biagio const Record *Reg) { 3595140023SAndrea Di Biagio assert(Reg->isSubClassOf("Register") && "Expected a register Record!"); 3695140023SAndrea Di Biagio 3795140023SAndrea Di Biagio OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 3895140023SAndrea Di Biagio << ").getReg() " << (shouldNegate() ? "!= " : "== "); 3995140023SAndrea Di Biagio const StringRef Str = Reg->getValueAsString("Namespace"); 4095140023SAndrea Di Biagio if (!Str.empty()) 4195140023SAndrea Di Biagio OS << Str << "::"; 4295140023SAndrea Di Biagio OS << Reg->getName(); 4395140023SAndrea Di Biagio } 4495140023SAndrea Di Biagio 45*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckInvalidRegOperand(raw_ostream &OS, 469a2e9db7SAndrea Di Biagio int OpIndex) { 479a2e9db7SAndrea Di Biagio OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 489a2e9db7SAndrea Di Biagio << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0"; 499a2e9db7SAndrea Di Biagio } 509a2e9db7SAndrea Di Biagio 51*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckSameRegOperand(raw_ostream &OS, int First, 52*2c6cbc8bSAndrea Di Biagio int Second) { 5395140023SAndrea Di Biagio OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First 5495140023SAndrea Di Biagio << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI" 5595140023SAndrea Di Biagio << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()"; 5695140023SAndrea Di Biagio } 5795140023SAndrea Di Biagio 58*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckNumOperands(raw_ostream &OS, int NumOps) { 5995140023SAndrea Di Biagio OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() " 6095140023SAndrea Di Biagio << (shouldNegate() ? "!= " : "== ") << NumOps; 6195140023SAndrea Di Biagio } 6295140023SAndrea Di Biagio 63*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckOpcode(raw_ostream &OS, const Record *Inst) { 6495140023SAndrea Di Biagio OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() " 6595140023SAndrea Di Biagio << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace") 6695140023SAndrea Di Biagio << "::" << Inst->getName(); 6795140023SAndrea Di Biagio } 6895140023SAndrea Di Biagio 69*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckOpcode(raw_ostream &OS, 7095140023SAndrea Di Biagio const RecVec &Opcodes) { 7195140023SAndrea Di Biagio assert(!Opcodes.empty() && "Expected at least one opcode to check!"); 7295140023SAndrea Di Biagio bool First = true; 7395140023SAndrea Di Biagio 7495140023SAndrea Di Biagio if (Opcodes.size() == 1) { 7595140023SAndrea Di Biagio OS << "( "; 7695140023SAndrea Di Biagio expandCheckOpcode(OS, Opcodes[0]); 7795140023SAndrea Di Biagio OS << " )"; 7895140023SAndrea Di Biagio return; 7995140023SAndrea Di Biagio } 8095140023SAndrea Di Biagio 8195140023SAndrea Di Biagio OS << '('; 8295140023SAndrea Di Biagio increaseIndentLevel(); 8395140023SAndrea Di Biagio for (const Record *Rec : Opcodes) { 8495140023SAndrea Di Biagio OS << '\n'; 85*2c6cbc8bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 8695140023SAndrea Di Biagio if (!First) 8795140023SAndrea Di Biagio OS << (shouldNegate() ? "&& " : "|| "); 8895140023SAndrea Di Biagio 8995140023SAndrea Di Biagio expandCheckOpcode(OS, Rec); 9095140023SAndrea Di Biagio First = false; 9195140023SAndrea Di Biagio } 9295140023SAndrea Di Biagio 9395140023SAndrea Di Biagio OS << '\n'; 9495140023SAndrea Di Biagio decreaseIndentLevel(); 95*2c6cbc8bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 9695140023SAndrea Di Biagio OS << ')'; 9795140023SAndrea Di Biagio } 9895140023SAndrea Di Biagio 99*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckPseudo(raw_ostream &OS, 10095140023SAndrea Di Biagio const RecVec &Opcodes) { 10195140023SAndrea Di Biagio if (shouldExpandForMC()) 10295140023SAndrea Di Biagio expandFalse(OS); 10395140023SAndrea Di Biagio else 10495140023SAndrea Di Biagio expandCheckOpcode(OS, Opcodes); 10595140023SAndrea Di Biagio } 10695140023SAndrea Di Biagio 107*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandPredicateSequence(raw_ostream &OS, 10895140023SAndrea Di Biagio const RecVec &Sequence, 10995140023SAndrea Di Biagio bool IsCheckAll) { 11095140023SAndrea Di Biagio assert(!Sequence.empty() && "Found an invalid empty predicate set!"); 11195140023SAndrea Di Biagio if (Sequence.size() == 1) 11295140023SAndrea Di Biagio return expandPredicate(OS, Sequence[0]); 11395140023SAndrea Di Biagio 11495140023SAndrea Di Biagio // Okay, there is more than one predicate in the set. 11595140023SAndrea Di Biagio bool First = true; 11695140023SAndrea Di Biagio OS << (shouldNegate() ? "!(" : "("); 11795140023SAndrea Di Biagio increaseIndentLevel(); 11895140023SAndrea Di Biagio 11995140023SAndrea Di Biagio bool OldValue = shouldNegate(); 12095140023SAndrea Di Biagio setNegatePredicate(false); 12195140023SAndrea Di Biagio for (const Record *Rec : Sequence) { 12295140023SAndrea Di Biagio OS << '\n'; 123*2c6cbc8bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 12495140023SAndrea Di Biagio if (!First) 12595140023SAndrea Di Biagio OS << (IsCheckAll ? "&& " : "|| "); 12695140023SAndrea Di Biagio expandPredicate(OS, Rec); 12795140023SAndrea Di Biagio First = false; 12895140023SAndrea Di Biagio } 12995140023SAndrea Di Biagio OS << '\n'; 13095140023SAndrea Di Biagio decreaseIndentLevel(); 131*2c6cbc8bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 13295140023SAndrea Di Biagio OS << ')'; 13395140023SAndrea Di Biagio setNegatePredicate(OldValue); 13495140023SAndrea Di Biagio } 13595140023SAndrea Di Biagio 136*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS, 13795140023SAndrea Di Biagio StringRef TargetName, 13895140023SAndrea Di Biagio StringRef MethodName) { 13995140023SAndrea Di Biagio OS << (shouldNegate() ? "!" : ""); 14095140023SAndrea Di Biagio if (shouldExpandForMC()) 14195140023SAndrea Di Biagio OS << TargetName << "_MC::"; 14295140023SAndrea Di Biagio else 14395140023SAndrea Di Biagio OS << TargetName << "Gen" 14495140023SAndrea Di Biagio << "InstrInfo::"; 14595140023SAndrea Di Biagio OS << MethodName << (isByRef() ? "(MI)" : "(*MI)"); 14695140023SAndrea Di Biagio } 14795140023SAndrea Di Biagio 148*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) { 14995140023SAndrea Di Biagio OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->") 15095140023SAndrea Di Biagio << "getOperand(" << OpIndex << ").isReg() "; 15195140023SAndrea Di Biagio } 15295140023SAndrea Di Biagio 153*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) { 15495140023SAndrea Di Biagio OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->") 15595140023SAndrea Di Biagio << "getOperand(" << OpIndex << ").isImm() "; 15695140023SAndrea Di Biagio } 15795140023SAndrea Di Biagio 158*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS, 15995140023SAndrea Di Biagio StringRef MCInstFn, 16095140023SAndrea Di Biagio StringRef MachineInstrFn) { 16195140023SAndrea Di Biagio OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn) 16295140023SAndrea Di Biagio << (isByRef() ? "(MI)" : "(*MI)"); 16395140023SAndrea Di Biagio } 16495140023SAndrea Di Biagio 165*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckNonPortable(raw_ostream &OS, 16695140023SAndrea Di Biagio StringRef Code) { 16795140023SAndrea Di Biagio if (shouldExpandForMC()) 16895140023SAndrea Di Biagio return expandFalse(OS); 16995140023SAndrea Di Biagio 17095140023SAndrea Di Biagio OS << '(' << Code << ')'; 17195140023SAndrea Di Biagio } 17295140023SAndrea Di Biagio 173*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandReturnStatement(raw_ostream &OS, 174f3bde048SAndrea Di Biagio const Record *Rec) { 175*2c6cbc8bSAndrea Di Biagio std::string Buffer; 176*2c6cbc8bSAndrea Di Biagio raw_string_ostream SS(Buffer); 177*2c6cbc8bSAndrea Di Biagio 178*2c6cbc8bSAndrea Di Biagio SS << "return "; 179*2c6cbc8bSAndrea Di Biagio expandPredicate(SS, Rec); 180*2c6cbc8bSAndrea Di Biagio SS << ";"; 181*2c6cbc8bSAndrea Di Biagio SS.flush(); 182*2c6cbc8bSAndrea Di Biagio OS << Buffer; 183f3bde048SAndrea Di Biagio } 184f3bde048SAndrea Di Biagio 185*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS, 186f3bde048SAndrea Di Biagio const Record *Rec) { 187f3bde048SAndrea Di Biagio const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes"); 188f3bde048SAndrea Di Biagio for (const Record *Opcode : Opcodes) { 189*2c6cbc8bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 190f3bde048SAndrea Di Biagio OS << "case " << Opcode->getValueAsString("Namespace") 191f3bde048SAndrea Di Biagio << "::" << Opcode->getName() << " :\n"; 192f3bde048SAndrea Di Biagio } 193f3bde048SAndrea Di Biagio 194f3bde048SAndrea Di Biagio increaseIndentLevel(); 195*2c6cbc8bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 196f3bde048SAndrea Di Biagio expandStatement(OS, Rec->getValueAsDef("CaseStmt")); 197f3bde048SAndrea Di Biagio decreaseIndentLevel(); 198f3bde048SAndrea Di Biagio } 199f3bde048SAndrea Di Biagio 200*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS, 201f3bde048SAndrea Di Biagio const RecVec &Cases, 202f3bde048SAndrea Di Biagio const Record *Default) { 203*2c6cbc8bSAndrea Di Biagio std::string Buffer; 204*2c6cbc8bSAndrea Di Biagio raw_string_ostream SS(Buffer); 205f3bde048SAndrea Di Biagio 206*2c6cbc8bSAndrea Di Biagio SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n"; 207f3bde048SAndrea Di Biagio for (const Record *Rec : Cases) { 208*2c6cbc8bSAndrea Di Biagio expandOpcodeSwitchCase(SS, Rec); 209*2c6cbc8bSAndrea Di Biagio SS << '\n'; 210f3bde048SAndrea Di Biagio } 211f3bde048SAndrea Di Biagio 212f3bde048SAndrea Di Biagio // Expand the default case. 213*2c6cbc8bSAndrea Di Biagio SS.indent(getIndentLevel() * 2); 214*2c6cbc8bSAndrea Di Biagio SS << "default :\n"; 215f3bde048SAndrea Di Biagio 216*2c6cbc8bSAndrea Di Biagio increaseIndentLevel(); 217*2c6cbc8bSAndrea Di Biagio SS.indent(getIndentLevel() * 2); 218*2c6cbc8bSAndrea Di Biagio expandStatement(SS, Default); 219*2c6cbc8bSAndrea Di Biagio decreaseIndentLevel(); 220*2c6cbc8bSAndrea Di Biagio SS << '\n'; 221*2c6cbc8bSAndrea Di Biagio 222*2c6cbc8bSAndrea Di Biagio SS.indent(getIndentLevel() * 2); 223*2c6cbc8bSAndrea Di Biagio SS << "} // end of switch-stmt"; 224*2c6cbc8bSAndrea Di Biagio SS.flush(); 225*2c6cbc8bSAndrea Di Biagio OS << Buffer; 226f3bde048SAndrea Di Biagio } 227f3bde048SAndrea Di Biagio 228*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) { 229*2c6cbc8bSAndrea Di Biagio // Assume that padding has been added by the caller. 230f3bde048SAndrea Di Biagio if (Rec->isSubClassOf("MCOpcodeSwitchStatement")) { 231f3bde048SAndrea Di Biagio expandOpcodeSwitchStatement(OS, Rec->getValueAsListOfDefs("Cases"), 232f3bde048SAndrea Di Biagio Rec->getValueAsDef("DefaultCase")); 233f3bde048SAndrea Di Biagio return; 234f3bde048SAndrea Di Biagio } 235f3bde048SAndrea Di Biagio 236f3bde048SAndrea Di Biagio if (Rec->isSubClassOf("MCReturnStatement")) { 237f3bde048SAndrea Di Biagio expandReturnStatement(OS, Rec->getValueAsDef("Pred")); 238f3bde048SAndrea Di Biagio return; 239f3bde048SAndrea Di Biagio } 240f3bde048SAndrea Di Biagio 241f3bde048SAndrea Di Biagio llvm_unreachable("No known rules to expand this MCStatement"); 242f3bde048SAndrea Di Biagio } 243f3bde048SAndrea Di Biagio 244*2c6cbc8bSAndrea Di Biagio void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) { 245*2c6cbc8bSAndrea Di Biagio // Assume that padding has been added by the caller. 24695140023SAndrea Di Biagio if (Rec->isSubClassOf("MCTrue")) { 24795140023SAndrea Di Biagio if (shouldNegate()) 24895140023SAndrea Di Biagio return expandFalse(OS); 24995140023SAndrea Di Biagio return expandTrue(OS); 25095140023SAndrea Di Biagio } 25195140023SAndrea Di Biagio 25295140023SAndrea Di Biagio if (Rec->isSubClassOf("MCFalse")) { 25395140023SAndrea Di Biagio if (shouldNegate()) 25495140023SAndrea Di Biagio return expandTrue(OS); 25595140023SAndrea Di Biagio return expandFalse(OS); 25695140023SAndrea Di Biagio } 25795140023SAndrea Di Biagio 25895140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckNot")) { 25995140023SAndrea Di Biagio flipNegatePredicate(); 26095140023SAndrea Di Biagio expandPredicate(OS, Rec->getValueAsDef("Pred")); 26195140023SAndrea Di Biagio flipNegatePredicate(); 26295140023SAndrea Di Biagio return; 26395140023SAndrea Di Biagio } 26495140023SAndrea Di Biagio 26595140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckIsRegOperand")) 26695140023SAndrea Di Biagio return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex")); 26795140023SAndrea Di Biagio 26895140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckIsImmOperand")) 26995140023SAndrea Di Biagio return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex")); 27095140023SAndrea Di Biagio 27195140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckRegOperand")) 27295140023SAndrea Di Biagio return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"), 27395140023SAndrea Di Biagio Rec->getValueAsDef("Reg")); 27495140023SAndrea Di Biagio 2759a2e9db7SAndrea Di Biagio if (Rec->isSubClassOf("CheckInvalidRegOperand")) 2769a2e9db7SAndrea Di Biagio return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex")); 2779a2e9db7SAndrea Di Biagio 27895140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckImmOperand")) 27995140023SAndrea Di Biagio return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), 28095140023SAndrea Di Biagio Rec->getValueAsInt("ImmVal")); 28195140023SAndrea Di Biagio 28295140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckImmOperand_s")) 28395140023SAndrea Di Biagio return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), 28495140023SAndrea Di Biagio Rec->getValueAsString("ImmVal")); 28595140023SAndrea Di Biagio 28695140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckSameRegOperand")) 28795140023SAndrea Di Biagio return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"), 28895140023SAndrea Di Biagio Rec->getValueAsInt("SecondIndex")); 28995140023SAndrea Di Biagio 29095140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckNumOperands")) 29195140023SAndrea Di Biagio return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps")); 29295140023SAndrea Di Biagio 29395140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckPseudo")) 29495140023SAndrea Di Biagio return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes")); 29595140023SAndrea Di Biagio 29695140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckOpcode")) 29795140023SAndrea Di Biagio return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes")); 29895140023SAndrea Di Biagio 29995140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckAll")) 30095140023SAndrea Di Biagio return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"), 30195140023SAndrea Di Biagio /* AllOf */ true); 30295140023SAndrea Di Biagio 30395140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckAny")) 30495140023SAndrea Di Biagio return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"), 30595140023SAndrea Di Biagio /* AllOf */ false); 30695140023SAndrea Di Biagio 30795140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckFunctionPredicate")) 30895140023SAndrea Di Biagio return expandCheckFunctionPredicate( 30995140023SAndrea Di Biagio OS, Rec->getValueAsString("MCInstFnName"), 31095140023SAndrea Di Biagio Rec->getValueAsString("MachineInstrFnName")); 31195140023SAndrea Di Biagio 31295140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckNonPortable")) 31395140023SAndrea Di Biagio return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock")); 31495140023SAndrea Di Biagio 31595140023SAndrea Di Biagio if (Rec->isSubClassOf("TIIPredicate")) 31695140023SAndrea Di Biagio return expandTIIFunctionCall(OS, Rec->getValueAsString("TargetName"), 31795140023SAndrea Di Biagio Rec->getValueAsString("FunctionName")); 31895140023SAndrea Di Biagio 31995140023SAndrea Di Biagio llvm_unreachable("No known rules to expand this MCInstPredicate"); 32095140023SAndrea Di Biagio } 32195140023SAndrea Di Biagio 32295140023SAndrea Di Biagio } // namespace llvm 323