195140023SAndrea Di Biagio //===--------------------- PredicateExpander.cpp --------------------------===// 295140023SAndrea Di Biagio // 3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 695140023SAndrea Di Biagio // 795140023SAndrea Di Biagio //===----------------------------------------------------------------------===// 895140023SAndrea Di Biagio /// \file 995140023SAndrea Di Biagio /// Functionalities used by the Tablegen backends to expand machine predicates. 1095140023SAndrea Di Biagio // 1195140023SAndrea Di Biagio //===----------------------------------------------------------------------===// 1295140023SAndrea Di Biagio 1395140023SAndrea Di Biagio #include "PredicateExpander.h" 148b6c314bSAndrea Di Biagio #include "CodeGenSchedule.h" // Definition of STIPredicateFunction. 1595140023SAndrea Di Biagio 1695140023SAndrea Di Biagio namespace llvm { 1795140023SAndrea Di Biagio 182c6cbc8bSAndrea Di Biagio void PredicateExpander::expandTrue(raw_ostream &OS) { OS << "true"; } 192c6cbc8bSAndrea Di Biagio void PredicateExpander::expandFalse(raw_ostream &OS) { OS << "false"; } 2095140023SAndrea Di Biagio 212c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex, 223d2b7176SAndrea Di Biagio int ImmVal, 233d2b7176SAndrea Di Biagio StringRef FunctionMapper) { 243d2b7176SAndrea Di Biagio if (!FunctionMapper.empty()) 253d2b7176SAndrea Di Biagio OS << FunctionMapper << "("; 26ad0293caSAndrea Di Biagio OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 273d2b7176SAndrea Di Biagio << ").getImm()"; 2858e94f91SEvandro Menezes if (!FunctionMapper.empty()) 2958e94f91SEvandro Menezes OS << ")"; 303d2b7176SAndrea Di Biagio OS << (shouldNegate() ? " != " : " == ") << ImmVal; 3195140023SAndrea Di Biagio } 3295140023SAndrea Di Biagio 332c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex, 343d2b7176SAndrea Di Biagio StringRef ImmVal, 353d2b7176SAndrea Di Biagio StringRef FunctionMapper) { 3658e94f91SEvandro Menezes if (ImmVal.empty()) 3758e94f91SEvandro Menezes expandCheckImmOperandSimple(OS, OpIndex, FunctionMapper); 3858e94f91SEvandro Menezes 393d2b7176SAndrea Di Biagio if (!FunctionMapper.empty()) 403d2b7176SAndrea Di Biagio OS << FunctionMapper << "("; 41ad0293caSAndrea Di Biagio OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 423d2b7176SAndrea Di Biagio << ").getImm()"; 4358e94f91SEvandro Menezes if (!FunctionMapper.empty()) 4458e94f91SEvandro Menezes OS << ")"; 453d2b7176SAndrea Di Biagio OS << (shouldNegate() ? " != " : " == ") << ImmVal; 4695140023SAndrea Di Biagio } 4795140023SAndrea Di Biagio 4858e94f91SEvandro Menezes void PredicateExpander::expandCheckImmOperandSimple(raw_ostream &OS, 4958e94f91SEvandro Menezes int OpIndex, 5058e94f91SEvandro Menezes StringRef FunctionMapper) { 5158e94f91SEvandro Menezes if (shouldNegate()) 5258e94f91SEvandro Menezes OS << "!"; 5358e94f91SEvandro Menezes if (!FunctionMapper.empty()) 5458e94f91SEvandro Menezes OS << FunctionMapper << "("; 5558e94f91SEvandro Menezes OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 5658e94f91SEvandro Menezes << ").getImm()"; 5758e94f91SEvandro Menezes if (!FunctionMapper.empty()) 5858e94f91SEvandro Menezes OS << ")"; 5958e94f91SEvandro Menezes } 6058e94f91SEvandro Menezes 612c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex, 623d2b7176SAndrea Di Biagio const Record *Reg, 633d2b7176SAndrea Di Biagio StringRef FunctionMapper) { 6495140023SAndrea Di Biagio assert(Reg->isSubClassOf("Register") && "Expected a register Record!"); 6595140023SAndrea Di Biagio 663d2b7176SAndrea Di Biagio if (!FunctionMapper.empty()) 673d2b7176SAndrea Di Biagio OS << FunctionMapper << "("; 6895140023SAndrea Di Biagio OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 693d2b7176SAndrea Di Biagio << ").getReg()"; 7058e94f91SEvandro Menezes if (!FunctionMapper.empty()) 7158e94f91SEvandro Menezes OS << ")"; 723d2b7176SAndrea Di Biagio OS << (shouldNegate() ? " != " : " == "); 7395140023SAndrea Di Biagio const StringRef Str = Reg->getValueAsString("Namespace"); 7495140023SAndrea Di Biagio if (!Str.empty()) 7595140023SAndrea Di Biagio OS << Str << "::"; 7695140023SAndrea Di Biagio OS << Reg->getName(); 7795140023SAndrea Di Biagio } 7895140023SAndrea Di Biagio 7958e94f91SEvandro Menezes 8058e94f91SEvandro Menezes void PredicateExpander::expandCheckRegOperandSimple(raw_ostream &OS, 8158e94f91SEvandro Menezes int OpIndex, 8258e94f91SEvandro Menezes StringRef FunctionMapper) { 8358e94f91SEvandro Menezes if (shouldNegate()) 8458e94f91SEvandro Menezes OS << "!"; 8558e94f91SEvandro Menezes if (!FunctionMapper.empty()) 8658e94f91SEvandro Menezes OS << FunctionMapper << "("; 8758e94f91SEvandro Menezes OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 8858e94f91SEvandro Menezes << ").getReg()"; 8958e94f91SEvandro Menezes if (!FunctionMapper.empty()) 9058e94f91SEvandro Menezes OS << ")"; 9158e94f91SEvandro Menezes } 9258e94f91SEvandro Menezes 932c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckInvalidRegOperand(raw_ostream &OS, 949a2e9db7SAndrea Di Biagio int OpIndex) { 959a2e9db7SAndrea Di Biagio OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 969a2e9db7SAndrea Di Biagio << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0"; 979a2e9db7SAndrea Di Biagio } 989a2e9db7SAndrea Di Biagio 992c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckSameRegOperand(raw_ostream &OS, int First, 1002c6cbc8bSAndrea Di Biagio int Second) { 10195140023SAndrea Di Biagio OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First 10295140023SAndrea Di Biagio << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI" 10395140023SAndrea Di Biagio << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()"; 10495140023SAndrea Di Biagio } 10595140023SAndrea Di Biagio 1062c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckNumOperands(raw_ostream &OS, int NumOps) { 10795140023SAndrea Di Biagio OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() " 10895140023SAndrea Di Biagio << (shouldNegate() ? "!= " : "== ") << NumOps; 10995140023SAndrea Di Biagio } 11095140023SAndrea Di Biagio 1112c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckOpcode(raw_ostream &OS, const Record *Inst) { 11295140023SAndrea Di Biagio OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() " 11395140023SAndrea Di Biagio << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace") 11495140023SAndrea Di Biagio << "::" << Inst->getName(); 11595140023SAndrea Di Biagio } 11695140023SAndrea Di Biagio 1172c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckOpcode(raw_ostream &OS, 11895140023SAndrea Di Biagio const RecVec &Opcodes) { 11995140023SAndrea Di Biagio assert(!Opcodes.empty() && "Expected at least one opcode to check!"); 12095140023SAndrea Di Biagio bool First = true; 12195140023SAndrea Di Biagio 12295140023SAndrea Di Biagio if (Opcodes.size() == 1) { 12395140023SAndrea Di Biagio OS << "( "; 12495140023SAndrea Di Biagio expandCheckOpcode(OS, Opcodes[0]); 12595140023SAndrea Di Biagio OS << " )"; 12695140023SAndrea Di Biagio return; 12795140023SAndrea Di Biagio } 12895140023SAndrea Di Biagio 12995140023SAndrea Di Biagio OS << '('; 13095140023SAndrea Di Biagio increaseIndentLevel(); 13195140023SAndrea Di Biagio for (const Record *Rec : Opcodes) { 13295140023SAndrea Di Biagio OS << '\n'; 1332c6cbc8bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 13495140023SAndrea Di Biagio if (!First) 13595140023SAndrea Di Biagio OS << (shouldNegate() ? "&& " : "|| "); 13695140023SAndrea Di Biagio 13795140023SAndrea Di Biagio expandCheckOpcode(OS, Rec); 13895140023SAndrea Di Biagio First = false; 13995140023SAndrea Di Biagio } 14095140023SAndrea Di Biagio 14195140023SAndrea Di Biagio OS << '\n'; 14295140023SAndrea Di Biagio decreaseIndentLevel(); 1432c6cbc8bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 14495140023SAndrea Di Biagio OS << ')'; 14595140023SAndrea Di Biagio } 14695140023SAndrea Di Biagio 1472c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckPseudo(raw_ostream &OS, 14895140023SAndrea Di Biagio const RecVec &Opcodes) { 14995140023SAndrea Di Biagio if (shouldExpandForMC()) 15095140023SAndrea Di Biagio expandFalse(OS); 15195140023SAndrea Di Biagio else 15295140023SAndrea Di Biagio expandCheckOpcode(OS, Opcodes); 15395140023SAndrea Di Biagio } 15495140023SAndrea Di Biagio 1552c6cbc8bSAndrea Di Biagio void PredicateExpander::expandPredicateSequence(raw_ostream &OS, 15695140023SAndrea Di Biagio const RecVec &Sequence, 15795140023SAndrea Di Biagio bool IsCheckAll) { 15895140023SAndrea Di Biagio assert(!Sequence.empty() && "Found an invalid empty predicate set!"); 15995140023SAndrea Di Biagio if (Sequence.size() == 1) 16095140023SAndrea Di Biagio return expandPredicate(OS, Sequence[0]); 16195140023SAndrea Di Biagio 16295140023SAndrea Di Biagio // Okay, there is more than one predicate in the set. 16395140023SAndrea Di Biagio bool First = true; 16495140023SAndrea Di Biagio OS << (shouldNegate() ? "!(" : "("); 16595140023SAndrea Di Biagio increaseIndentLevel(); 16695140023SAndrea Di Biagio 16795140023SAndrea Di Biagio bool OldValue = shouldNegate(); 16895140023SAndrea Di Biagio setNegatePredicate(false); 16995140023SAndrea Di Biagio for (const Record *Rec : Sequence) { 17095140023SAndrea Di Biagio OS << '\n'; 1712c6cbc8bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 17295140023SAndrea Di Biagio if (!First) 17395140023SAndrea Di Biagio OS << (IsCheckAll ? "&& " : "|| "); 17495140023SAndrea Di Biagio expandPredicate(OS, Rec); 17595140023SAndrea Di Biagio First = false; 17695140023SAndrea Di Biagio } 17795140023SAndrea Di Biagio OS << '\n'; 17895140023SAndrea Di Biagio decreaseIndentLevel(); 1792c6cbc8bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 18095140023SAndrea Di Biagio OS << ')'; 18195140023SAndrea Di Biagio setNegatePredicate(OldValue); 18295140023SAndrea Di Biagio } 18395140023SAndrea Di Biagio 1842c6cbc8bSAndrea Di Biagio void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS, 18595140023SAndrea Di Biagio StringRef MethodName) { 18695140023SAndrea Di Biagio OS << (shouldNegate() ? "!" : ""); 1873d2b7176SAndrea Di Biagio OS << TargetName << (shouldExpandForMC() ? "_MC::" : "InstrInfo::"); 18895140023SAndrea Di Biagio OS << MethodName << (isByRef() ? "(MI)" : "(*MI)"); 18995140023SAndrea Di Biagio } 19095140023SAndrea Di Biagio 1912c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) { 19295140023SAndrea Di Biagio OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->") 19395140023SAndrea Di Biagio << "getOperand(" << OpIndex << ").isReg() "; 19495140023SAndrea Di Biagio } 19595140023SAndrea Di Biagio 1962c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) { 19795140023SAndrea Di Biagio OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->") 19895140023SAndrea Di Biagio << "getOperand(" << OpIndex << ").isImm() "; 19995140023SAndrea Di Biagio } 20095140023SAndrea Di Biagio 2012c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS, 20295140023SAndrea Di Biagio StringRef MCInstFn, 20395140023SAndrea Di Biagio StringRef MachineInstrFn) { 20495140023SAndrea Di Biagio OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn) 20595140023SAndrea Di Biagio << (isByRef() ? "(MI)" : "(*MI)"); 20695140023SAndrea Di Biagio } 20795140023SAndrea Di Biagio 2082c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckNonPortable(raw_ostream &OS, 20995140023SAndrea Di Biagio StringRef Code) { 21095140023SAndrea Di Biagio if (shouldExpandForMC()) 21195140023SAndrea Di Biagio return expandFalse(OS); 21295140023SAndrea Di Biagio 21395140023SAndrea Di Biagio OS << '(' << Code << ')'; 21495140023SAndrea Di Biagio } 21595140023SAndrea Di Biagio 2162c6cbc8bSAndrea Di Biagio void PredicateExpander::expandReturnStatement(raw_ostream &OS, 217f3bde048SAndrea Di Biagio const Record *Rec) { 2182c6cbc8bSAndrea Di Biagio std::string Buffer; 2192c6cbc8bSAndrea Di Biagio raw_string_ostream SS(Buffer); 2202c6cbc8bSAndrea Di Biagio 2212c6cbc8bSAndrea Di Biagio SS << "return "; 2222c6cbc8bSAndrea Di Biagio expandPredicate(SS, Rec); 2232c6cbc8bSAndrea Di Biagio SS << ";"; 2242c6cbc8bSAndrea Di Biagio SS.flush(); 2252c6cbc8bSAndrea Di Biagio OS << Buffer; 226f3bde048SAndrea Di Biagio } 227f3bde048SAndrea Di Biagio 2282c6cbc8bSAndrea Di Biagio void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS, 229f3bde048SAndrea Di Biagio const Record *Rec) { 230f3bde048SAndrea Di Biagio const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes"); 231f3bde048SAndrea Di Biagio for (const Record *Opcode : Opcodes) { 2322c6cbc8bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 233f3bde048SAndrea Di Biagio OS << "case " << Opcode->getValueAsString("Namespace") 234f3bde048SAndrea Di Biagio << "::" << Opcode->getName() << ":\n"; 235f3bde048SAndrea Di Biagio } 236f3bde048SAndrea Di Biagio 237f3bde048SAndrea Di Biagio increaseIndentLevel(); 2382c6cbc8bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 239f3bde048SAndrea Di Biagio expandStatement(OS, Rec->getValueAsDef("CaseStmt")); 240f3bde048SAndrea Di Biagio decreaseIndentLevel(); 241f3bde048SAndrea Di Biagio } 242f3bde048SAndrea Di Biagio 2432c6cbc8bSAndrea Di Biagio void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS, 244f3bde048SAndrea Di Biagio const RecVec &Cases, 245f3bde048SAndrea Di Biagio const Record *Default) { 2462c6cbc8bSAndrea Di Biagio std::string Buffer; 2472c6cbc8bSAndrea Di Biagio raw_string_ostream SS(Buffer); 248f3bde048SAndrea Di Biagio 2492c6cbc8bSAndrea Di Biagio SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n"; 250f3bde048SAndrea Di Biagio for (const Record *Rec : Cases) { 2512c6cbc8bSAndrea Di Biagio expandOpcodeSwitchCase(SS, Rec); 2522c6cbc8bSAndrea Di Biagio SS << '\n'; 253f3bde048SAndrea Di Biagio } 254f3bde048SAndrea Di Biagio 255f3bde048SAndrea Di Biagio // Expand the default case. 2562c6cbc8bSAndrea Di Biagio SS.indent(getIndentLevel() * 2); 2572c6cbc8bSAndrea Di Biagio SS << "default:\n"; 258f3bde048SAndrea Di Biagio 2592c6cbc8bSAndrea Di Biagio increaseIndentLevel(); 2602c6cbc8bSAndrea Di Biagio SS.indent(getIndentLevel() * 2); 2612c6cbc8bSAndrea Di Biagio expandStatement(SS, Default); 2622c6cbc8bSAndrea Di Biagio decreaseIndentLevel(); 2632c6cbc8bSAndrea Di Biagio SS << '\n'; 2642c6cbc8bSAndrea Di Biagio 2652c6cbc8bSAndrea Di Biagio SS.indent(getIndentLevel() * 2); 2662c6cbc8bSAndrea Di Biagio SS << "} // end of switch-stmt"; 2672c6cbc8bSAndrea Di Biagio SS.flush(); 2682c6cbc8bSAndrea Di Biagio OS << Buffer; 269f3bde048SAndrea Di Biagio } 270f3bde048SAndrea Di Biagio 2712c6cbc8bSAndrea Di Biagio void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) { 2722c6cbc8bSAndrea Di Biagio // Assume that padding has been added by the caller. 273f3bde048SAndrea Di Biagio if (Rec->isSubClassOf("MCOpcodeSwitchStatement")) { 274f3bde048SAndrea Di Biagio expandOpcodeSwitchStatement(OS, Rec->getValueAsListOfDefs("Cases"), 275f3bde048SAndrea Di Biagio Rec->getValueAsDef("DefaultCase")); 276f3bde048SAndrea Di Biagio return; 277f3bde048SAndrea Di Biagio } 278f3bde048SAndrea Di Biagio 279f3bde048SAndrea Di Biagio if (Rec->isSubClassOf("MCReturnStatement")) { 280f3bde048SAndrea Di Biagio expandReturnStatement(OS, Rec->getValueAsDef("Pred")); 281f3bde048SAndrea Di Biagio return; 282f3bde048SAndrea Di Biagio } 283f3bde048SAndrea Di Biagio 284f3bde048SAndrea Di Biagio llvm_unreachable("No known rules to expand this MCStatement"); 285f3bde048SAndrea Di Biagio } 286f3bde048SAndrea Di Biagio 2872c6cbc8bSAndrea Di Biagio void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) { 2882c6cbc8bSAndrea Di Biagio // Assume that padding has been added by the caller. 28995140023SAndrea Di Biagio if (Rec->isSubClassOf("MCTrue")) { 29095140023SAndrea Di Biagio if (shouldNegate()) 29195140023SAndrea Di Biagio return expandFalse(OS); 29295140023SAndrea Di Biagio return expandTrue(OS); 29395140023SAndrea Di Biagio } 29495140023SAndrea Di Biagio 29595140023SAndrea Di Biagio if (Rec->isSubClassOf("MCFalse")) { 29695140023SAndrea Di Biagio if (shouldNegate()) 29795140023SAndrea Di Biagio return expandTrue(OS); 29895140023SAndrea Di Biagio return expandFalse(OS); 29995140023SAndrea Di Biagio } 30095140023SAndrea Di Biagio 30195140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckNot")) { 30295140023SAndrea Di Biagio flipNegatePredicate(); 30395140023SAndrea Di Biagio expandPredicate(OS, Rec->getValueAsDef("Pred")); 30495140023SAndrea Di Biagio flipNegatePredicate(); 30595140023SAndrea Di Biagio return; 30695140023SAndrea Di Biagio } 30795140023SAndrea Di Biagio 30895140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckIsRegOperand")) 30995140023SAndrea Di Biagio return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex")); 31095140023SAndrea Di Biagio 31195140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckIsImmOperand")) 31295140023SAndrea Di Biagio return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex")); 31395140023SAndrea Di Biagio 31495140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckRegOperand")) 31595140023SAndrea Di Biagio return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"), 3163d2b7176SAndrea Di Biagio Rec->getValueAsDef("Reg"), 3173d2b7176SAndrea Di Biagio Rec->getValueAsString("FunctionMapper")); 3183d2b7176SAndrea Di Biagio 3193d2b7176SAndrea Di Biagio if (Rec->isSubClassOf("CheckRegOperandSimple")) 32058e94f91SEvandro Menezes return expandCheckRegOperandSimple(OS, Rec->getValueAsInt("OpIndex"), 3213d2b7176SAndrea Di Biagio Rec->getValueAsString("FunctionMapper")); 32295140023SAndrea Di Biagio 3239a2e9db7SAndrea Di Biagio if (Rec->isSubClassOf("CheckInvalidRegOperand")) 3249a2e9db7SAndrea Di Biagio return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex")); 3259a2e9db7SAndrea Di Biagio 32695140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckImmOperand")) 32795140023SAndrea Di Biagio return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), 3283d2b7176SAndrea Di Biagio Rec->getValueAsInt("ImmVal"), 3293d2b7176SAndrea Di Biagio Rec->getValueAsString("FunctionMapper")); 33095140023SAndrea Di Biagio 33195140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckImmOperand_s")) 33295140023SAndrea Di Biagio return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), 3333d2b7176SAndrea Di Biagio Rec->getValueAsString("ImmVal"), 3343d2b7176SAndrea Di Biagio Rec->getValueAsString("FunctionMapper")); 3353d2b7176SAndrea Di Biagio 3363d2b7176SAndrea Di Biagio if (Rec->isSubClassOf("CheckImmOperandSimple")) 33758e94f91SEvandro Menezes return expandCheckImmOperandSimple(OS, Rec->getValueAsInt("OpIndex"), 3383d2b7176SAndrea Di Biagio Rec->getValueAsString("FunctionMapper")); 33995140023SAndrea Di Biagio 34095140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckSameRegOperand")) 34195140023SAndrea Di Biagio return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"), 34295140023SAndrea Di Biagio Rec->getValueAsInt("SecondIndex")); 34395140023SAndrea Di Biagio 34495140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckNumOperands")) 34595140023SAndrea Di Biagio return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps")); 34695140023SAndrea Di Biagio 34795140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckPseudo")) 34895140023SAndrea Di Biagio return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes")); 34995140023SAndrea Di Biagio 35095140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckOpcode")) 35195140023SAndrea Di Biagio return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes")); 35295140023SAndrea Di Biagio 35395140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckAll")) 35495140023SAndrea Di Biagio return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"), 35595140023SAndrea Di Biagio /* AllOf */ true); 35695140023SAndrea Di Biagio 35795140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckAny")) 35895140023SAndrea Di Biagio return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"), 35995140023SAndrea Di Biagio /* AllOf */ false); 36095140023SAndrea Di Biagio 36195140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckFunctionPredicate")) 36295140023SAndrea Di Biagio return expandCheckFunctionPredicate( 36395140023SAndrea Di Biagio OS, Rec->getValueAsString("MCInstFnName"), 36495140023SAndrea Di Biagio Rec->getValueAsString("MachineInstrFnName")); 36595140023SAndrea Di Biagio 36695140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckNonPortable")) 36795140023SAndrea Di Biagio return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock")); 36895140023SAndrea Di Biagio 36995140023SAndrea Di Biagio if (Rec->isSubClassOf("TIIPredicate")) 3709eaf5aa0SAndrea Di Biagio return expandTIIFunctionCall(OS, Rec->getValueAsString("FunctionName")); 37195140023SAndrea Di Biagio 37295140023SAndrea Di Biagio llvm_unreachable("No known rules to expand this MCInstPredicate"); 37395140023SAndrea Di Biagio } 37495140023SAndrea Di Biagio 3758b6c314bSAndrea Di Biagio void STIPredicateExpander::expandHeader(raw_ostream &OS, 3768b6c314bSAndrea Di Biagio const STIPredicateFunction &Fn) { 3778b6c314bSAndrea Di Biagio const Record *Rec = Fn.getDeclaration(); 3788b6c314bSAndrea Di Biagio StringRef FunctionName = Rec->getValueAsString("Name"); 3798b6c314bSAndrea Di Biagio 3808b6c314bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 3818b6c314bSAndrea Di Biagio OS << "bool "; 3828b6c314bSAndrea Di Biagio if (shouldExpandDefinition()) 3838b6c314bSAndrea Di Biagio OS << getClassPrefix() << "::"; 3848b6c314bSAndrea Di Biagio OS << FunctionName << "("; 3858b6c314bSAndrea Di Biagio if (shouldExpandForMC()) 3868b6c314bSAndrea Di Biagio OS << "const MCInst " << (isByRef() ? "&" : "*") << "MI"; 3878b6c314bSAndrea Di Biagio else 3888b6c314bSAndrea Di Biagio OS << "const MachineInstr " << (isByRef() ? "&" : "*") << "MI"; 3898b6c314bSAndrea Di Biagio if (Rec->getValueAsBit("UpdatesOpcodeMask")) 3908b6c314bSAndrea Di Biagio OS << ", APInt &Mask"; 3918b6c314bSAndrea Di Biagio OS << (shouldExpandForMC() ? ", unsigned ProcessorID) const " : ") const "); 3928b6c314bSAndrea Di Biagio if (shouldExpandDefinition()) { 3938b6c314bSAndrea Di Biagio OS << "{\n"; 3948b6c314bSAndrea Di Biagio return; 3958b6c314bSAndrea Di Biagio } 3968b6c314bSAndrea Di Biagio 3978b6c314bSAndrea Di Biagio if (Rec->getValueAsBit("OverridesBaseClassMember")) 3988b6c314bSAndrea Di Biagio OS << "override"; 3998b6c314bSAndrea Di Biagio OS << ";\n"; 4008b6c314bSAndrea Di Biagio } 4018b6c314bSAndrea Di Biagio 4028b6c314bSAndrea Di Biagio void STIPredicateExpander::expandPrologue(raw_ostream &OS, 4038b6c314bSAndrea Di Biagio const STIPredicateFunction &Fn) { 4048b6c314bSAndrea Di Biagio RecVec Delegates = Fn.getDeclaration()->getValueAsListOfDefs("Delegates"); 4058b6c314bSAndrea Di Biagio bool UpdatesOpcodeMask = 4068b6c314bSAndrea Di Biagio Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask"); 4078b6c314bSAndrea Di Biagio 4088b6c314bSAndrea Di Biagio increaseIndentLevel(); 4098b6c314bSAndrea Di Biagio unsigned IndentLevel = getIndentLevel(); 4108b6c314bSAndrea Di Biagio for (const Record *Delegate : Delegates) { 4118b6c314bSAndrea Di Biagio OS.indent(IndentLevel * 2); 4128b6c314bSAndrea Di Biagio OS << "if (" << Delegate->getValueAsString("Name") << "(MI"; 4138b6c314bSAndrea Di Biagio if (UpdatesOpcodeMask) 4148b6c314bSAndrea Di Biagio OS << ", Mask"; 4158b6c314bSAndrea Di Biagio if (shouldExpandForMC()) 4168b6c314bSAndrea Di Biagio OS << ", ProcessorID"; 4178b6c314bSAndrea Di Biagio OS << "))\n"; 4188b6c314bSAndrea Di Biagio OS.indent((1 + IndentLevel) * 2); 4198b6c314bSAndrea Di Biagio OS << "return true;\n\n"; 4208b6c314bSAndrea Di Biagio } 4218b6c314bSAndrea Di Biagio 4228b6c314bSAndrea Di Biagio if (shouldExpandForMC()) 4238b6c314bSAndrea Di Biagio return; 4248b6c314bSAndrea Di Biagio 4258b6c314bSAndrea Di Biagio OS.indent(IndentLevel * 2); 4268b6c314bSAndrea Di Biagio OS << "unsigned ProcessorID = getSchedModel().getProcessorID();\n"; 4278b6c314bSAndrea Di Biagio } 4288b6c314bSAndrea Di Biagio 4298b6c314bSAndrea Di Biagio void STIPredicateExpander::expandOpcodeGroup(raw_ostream &OS, const OpcodeGroup &Group, 4308b6c314bSAndrea Di Biagio bool ShouldUpdateOpcodeMask) { 4318b6c314bSAndrea Di Biagio const OpcodeInfo &OI = Group.getOpcodeInfo(); 4328b6c314bSAndrea Di Biagio for (const PredicateInfo &PI : OI.getPredicates()) { 4338b6c314bSAndrea Di Biagio const APInt &ProcModelMask = PI.ProcModelMask; 4348b6c314bSAndrea Di Biagio bool FirstProcID = true; 4358b6c314bSAndrea Di Biagio for (unsigned I = 0, E = ProcModelMask.getActiveBits(); I < E; ++I) { 4368b6c314bSAndrea Di Biagio if (!ProcModelMask[I]) 4378b6c314bSAndrea Di Biagio continue; 4388b6c314bSAndrea Di Biagio 4398b6c314bSAndrea Di Biagio if (FirstProcID) { 4408b6c314bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 4418b6c314bSAndrea Di Biagio OS << "if (ProcessorID == " << I; 4428b6c314bSAndrea Di Biagio } else { 4438b6c314bSAndrea Di Biagio OS << " || ProcessorID == " << I; 4448b6c314bSAndrea Di Biagio } 4458b6c314bSAndrea Di Biagio FirstProcID = false; 4468b6c314bSAndrea Di Biagio } 4478b6c314bSAndrea Di Biagio 4488b6c314bSAndrea Di Biagio OS << ") {\n"; 4498b6c314bSAndrea Di Biagio 4508b6c314bSAndrea Di Biagio increaseIndentLevel(); 4518b6c314bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 4528b6c314bSAndrea Di Biagio if (ShouldUpdateOpcodeMask) { 4538b6c314bSAndrea Di Biagio if (PI.OperandMask.isNullValue()) 4548b6c314bSAndrea Di Biagio OS << "Mask.clearAllBits();\n"; 4558b6c314bSAndrea Di Biagio else 4568b6c314bSAndrea Di Biagio OS << "Mask = " << PI.OperandMask << ";\n"; 4578b6c314bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 4588b6c314bSAndrea Di Biagio } 4598b6c314bSAndrea Di Biagio OS << "return "; 4608b6c314bSAndrea Di Biagio expandPredicate(OS, PI.Predicate); 4618b6c314bSAndrea Di Biagio OS << ";\n"; 4628b6c314bSAndrea Di Biagio decreaseIndentLevel(); 4638b6c314bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 4648b6c314bSAndrea Di Biagio OS << "}\n"; 4658b6c314bSAndrea Di Biagio } 4668b6c314bSAndrea Di Biagio } 4678b6c314bSAndrea Di Biagio 4688b6c314bSAndrea Di Biagio void STIPredicateExpander::expandBody(raw_ostream &OS, 4698b6c314bSAndrea Di Biagio const STIPredicateFunction &Fn) { 4708b6c314bSAndrea Di Biagio bool UpdatesOpcodeMask = 4718b6c314bSAndrea Di Biagio Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask"); 4728b6c314bSAndrea Di Biagio 4738b6c314bSAndrea Di Biagio unsigned IndentLevel = getIndentLevel(); 4748b6c314bSAndrea Di Biagio OS.indent(IndentLevel * 2); 4758b6c314bSAndrea Di Biagio OS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n"; 4768b6c314bSAndrea Di Biagio OS.indent(IndentLevel * 2); 4778b6c314bSAndrea Di Biagio OS << "default:\n"; 4788b6c314bSAndrea Di Biagio OS.indent(IndentLevel * 2); 4798b6c314bSAndrea Di Biagio OS << " break;"; 4808b6c314bSAndrea Di Biagio 4818b6c314bSAndrea Di Biagio for (const OpcodeGroup &Group : Fn.getGroups()) { 4828b6c314bSAndrea Di Biagio for (const Record *Opcode : Group.getOpcodes()) { 4838b6c314bSAndrea Di Biagio OS << '\n'; 4848b6c314bSAndrea Di Biagio OS.indent(IndentLevel * 2); 4858b6c314bSAndrea Di Biagio OS << "case " << getTargetName() << "::" << Opcode->getName() << ":"; 4868b6c314bSAndrea Di Biagio } 4878b6c314bSAndrea Di Biagio 4888b6c314bSAndrea Di Biagio OS << '\n'; 4898b6c314bSAndrea Di Biagio increaseIndentLevel(); 4908b6c314bSAndrea Di Biagio expandOpcodeGroup(OS, Group, UpdatesOpcodeMask); 4918b6c314bSAndrea Di Biagio 4928b6c314bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 4938b6c314bSAndrea Di Biagio OS << "break;\n"; 4948b6c314bSAndrea Di Biagio decreaseIndentLevel(); 4958b6c314bSAndrea Di Biagio } 4968b6c314bSAndrea Di Biagio 4978b6c314bSAndrea Di Biagio OS.indent(IndentLevel * 2); 4988b6c314bSAndrea Di Biagio OS << "}\n"; 4998b6c314bSAndrea Di Biagio } 5008b6c314bSAndrea Di Biagio 5018b6c314bSAndrea Di Biagio void STIPredicateExpander::expandEpilogue(raw_ostream &OS, 5028b6c314bSAndrea Di Biagio const STIPredicateFunction &Fn) { 5038b6c314bSAndrea Di Biagio OS << '\n'; 5048b6c314bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 5058b6c314bSAndrea Di Biagio OS << "return "; 5068b6c314bSAndrea Di Biagio expandPredicate(OS, Fn.getDefaultReturnPredicate()); 5078b6c314bSAndrea Di Biagio OS << ";\n"; 5088b6c314bSAndrea Di Biagio 5098b6c314bSAndrea Di Biagio decreaseIndentLevel(); 5108b6c314bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 5118b6c314bSAndrea Di Biagio StringRef FunctionName = Fn.getDeclaration()->getValueAsString("Name"); 5128b6c314bSAndrea Di Biagio OS << "} // " << ClassPrefix << "::" << FunctionName << "\n\n"; 5138b6c314bSAndrea Di Biagio } 5148b6c314bSAndrea Di Biagio 5158b6c314bSAndrea Di Biagio void STIPredicateExpander::expandSTIPredicate(raw_ostream &OS, 5168b6c314bSAndrea Di Biagio const STIPredicateFunction &Fn) { 5178b6c314bSAndrea Di Biagio const Record *Rec = Fn.getDeclaration(); 5188b6c314bSAndrea Di Biagio if (shouldExpandForMC() && !Rec->getValueAsBit("ExpandForMC")) 5198b6c314bSAndrea Di Biagio return; 5208b6c314bSAndrea Di Biagio 5218b6c314bSAndrea Di Biagio expandHeader(OS, Fn); 5228b6c314bSAndrea Di Biagio if (shouldExpandDefinition()) { 5238b6c314bSAndrea Di Biagio expandPrologue(OS, Fn); 5248b6c314bSAndrea Di Biagio expandBody(OS, Fn); 5258b6c314bSAndrea Di Biagio expandEpilogue(OS, Fn); 5268b6c314bSAndrea Di Biagio } 5278b6c314bSAndrea Di Biagio } 5288b6c314bSAndrea Di Biagio 52995140023SAndrea Di Biagio } // namespace llvm 530