195140023SAndrea Di Biagio //===--------------------- PredicateExpander.cpp --------------------------===// 295140023SAndrea Di Biagio // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler 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 201*8a7ca143SEvgeny Leviant void PredicateExpander::expandCheckFunctionPredicateWithTII( 202*8a7ca143SEvgeny Leviant raw_ostream &OS, StringRef MCInstFn, StringRef MachineInstrFn, 203*8a7ca143SEvgeny Leviant StringRef TIIPtr) { 204*8a7ca143SEvgeny Leviant if (!shouldExpandForMC()) { 205*8a7ca143SEvgeny Leviant OS << (TIIPtr.empty() ? "TII" : TIIPtr) << "->" << MachineInstrFn; 206*8a7ca143SEvgeny Leviant OS << (isByRef() ? "(MI)" : "(*MI)"); 207*8a7ca143SEvgeny Leviant return; 208*8a7ca143SEvgeny Leviant } 209*8a7ca143SEvgeny Leviant 210*8a7ca143SEvgeny Leviant OS << MCInstFn << (isByRef() ? "(MI" : "(*MI") << ", MCII)"; 211*8a7ca143SEvgeny Leviant } 212*8a7ca143SEvgeny Leviant 2132c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS, 21495140023SAndrea Di Biagio StringRef MCInstFn, 21595140023SAndrea Di Biagio StringRef MachineInstrFn) { 21695140023SAndrea Di Biagio OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn) 21795140023SAndrea Di Biagio << (isByRef() ? "(MI)" : "(*MI)"); 21895140023SAndrea Di Biagio } 21995140023SAndrea Di Biagio 2202c6cbc8bSAndrea Di Biagio void PredicateExpander::expandCheckNonPortable(raw_ostream &OS, 22195140023SAndrea Di Biagio StringRef Code) { 22295140023SAndrea Di Biagio if (shouldExpandForMC()) 22395140023SAndrea Di Biagio return expandFalse(OS); 22495140023SAndrea Di Biagio 22595140023SAndrea Di Biagio OS << '(' << Code << ')'; 22695140023SAndrea Di Biagio } 22795140023SAndrea Di Biagio 2282c6cbc8bSAndrea Di Biagio void PredicateExpander::expandReturnStatement(raw_ostream &OS, 229f3bde048SAndrea Di Biagio const Record *Rec) { 2302c6cbc8bSAndrea Di Biagio std::string Buffer; 2312c6cbc8bSAndrea Di Biagio raw_string_ostream SS(Buffer); 2322c6cbc8bSAndrea Di Biagio 2332c6cbc8bSAndrea Di Biagio SS << "return "; 2342c6cbc8bSAndrea Di Biagio expandPredicate(SS, Rec); 2352c6cbc8bSAndrea Di Biagio SS << ";"; 2362c6cbc8bSAndrea Di Biagio SS.flush(); 2372c6cbc8bSAndrea Di Biagio OS << Buffer; 238f3bde048SAndrea Di Biagio } 239f3bde048SAndrea Di Biagio 2402c6cbc8bSAndrea Di Biagio void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS, 241f3bde048SAndrea Di Biagio const Record *Rec) { 242f3bde048SAndrea Di Biagio const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes"); 243f3bde048SAndrea Di Biagio for (const Record *Opcode : Opcodes) { 2442c6cbc8bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 245f3bde048SAndrea Di Biagio OS << "case " << Opcode->getValueAsString("Namespace") 246f3bde048SAndrea Di Biagio << "::" << Opcode->getName() << ":\n"; 247f3bde048SAndrea Di Biagio } 248f3bde048SAndrea Di Biagio 249f3bde048SAndrea Di Biagio increaseIndentLevel(); 2502c6cbc8bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 251f3bde048SAndrea Di Biagio expandStatement(OS, Rec->getValueAsDef("CaseStmt")); 252f3bde048SAndrea Di Biagio decreaseIndentLevel(); 253f3bde048SAndrea Di Biagio } 254f3bde048SAndrea Di Biagio 2552c6cbc8bSAndrea Di Biagio void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS, 256f3bde048SAndrea Di Biagio const RecVec &Cases, 257f3bde048SAndrea Di Biagio const Record *Default) { 2582c6cbc8bSAndrea Di Biagio std::string Buffer; 2592c6cbc8bSAndrea Di Biagio raw_string_ostream SS(Buffer); 260f3bde048SAndrea Di Biagio 2612c6cbc8bSAndrea Di Biagio SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n"; 262f3bde048SAndrea Di Biagio for (const Record *Rec : Cases) { 2632c6cbc8bSAndrea Di Biagio expandOpcodeSwitchCase(SS, Rec); 2642c6cbc8bSAndrea Di Biagio SS << '\n'; 265f3bde048SAndrea Di Biagio } 266f3bde048SAndrea Di Biagio 267f3bde048SAndrea Di Biagio // Expand the default case. 2682c6cbc8bSAndrea Di Biagio SS.indent(getIndentLevel() * 2); 2692c6cbc8bSAndrea Di Biagio SS << "default:\n"; 270f3bde048SAndrea Di Biagio 2712c6cbc8bSAndrea Di Biagio increaseIndentLevel(); 2722c6cbc8bSAndrea Di Biagio SS.indent(getIndentLevel() * 2); 2732c6cbc8bSAndrea Di Biagio expandStatement(SS, Default); 2742c6cbc8bSAndrea Di Biagio decreaseIndentLevel(); 2752c6cbc8bSAndrea Di Biagio SS << '\n'; 2762c6cbc8bSAndrea Di Biagio 2772c6cbc8bSAndrea Di Biagio SS.indent(getIndentLevel() * 2); 2782c6cbc8bSAndrea Di Biagio SS << "} // end of switch-stmt"; 2792c6cbc8bSAndrea Di Biagio SS.flush(); 2802c6cbc8bSAndrea Di Biagio OS << Buffer; 281f3bde048SAndrea Di Biagio } 282f3bde048SAndrea Di Biagio 2832c6cbc8bSAndrea Di Biagio void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) { 2842c6cbc8bSAndrea Di Biagio // Assume that padding has been added by the caller. 285f3bde048SAndrea Di Biagio if (Rec->isSubClassOf("MCOpcodeSwitchStatement")) { 286f3bde048SAndrea Di Biagio expandOpcodeSwitchStatement(OS, Rec->getValueAsListOfDefs("Cases"), 287f3bde048SAndrea Di Biagio Rec->getValueAsDef("DefaultCase")); 288f3bde048SAndrea Di Biagio return; 289f3bde048SAndrea Di Biagio } 290f3bde048SAndrea Di Biagio 291f3bde048SAndrea Di Biagio if (Rec->isSubClassOf("MCReturnStatement")) { 292f3bde048SAndrea Di Biagio expandReturnStatement(OS, Rec->getValueAsDef("Pred")); 293f3bde048SAndrea Di Biagio return; 294f3bde048SAndrea Di Biagio } 295f3bde048SAndrea Di Biagio 296f3bde048SAndrea Di Biagio llvm_unreachable("No known rules to expand this MCStatement"); 297f3bde048SAndrea Di Biagio } 298f3bde048SAndrea Di Biagio 2992c6cbc8bSAndrea Di Biagio void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) { 3002c6cbc8bSAndrea Di Biagio // Assume that padding has been added by the caller. 30195140023SAndrea Di Biagio if (Rec->isSubClassOf("MCTrue")) { 30295140023SAndrea Di Biagio if (shouldNegate()) 30395140023SAndrea Di Biagio return expandFalse(OS); 30495140023SAndrea Di Biagio return expandTrue(OS); 30595140023SAndrea Di Biagio } 30695140023SAndrea Di Biagio 30795140023SAndrea Di Biagio if (Rec->isSubClassOf("MCFalse")) { 30895140023SAndrea Di Biagio if (shouldNegate()) 30995140023SAndrea Di Biagio return expandTrue(OS); 31095140023SAndrea Di Biagio return expandFalse(OS); 31195140023SAndrea Di Biagio } 31295140023SAndrea Di Biagio 31395140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckNot")) { 31495140023SAndrea Di Biagio flipNegatePredicate(); 31595140023SAndrea Di Biagio expandPredicate(OS, Rec->getValueAsDef("Pred")); 31695140023SAndrea Di Biagio flipNegatePredicate(); 31795140023SAndrea Di Biagio return; 31895140023SAndrea Di Biagio } 31995140023SAndrea Di Biagio 32095140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckIsRegOperand")) 32195140023SAndrea Di Biagio return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex")); 32295140023SAndrea Di Biagio 32395140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckIsImmOperand")) 32495140023SAndrea Di Biagio return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex")); 32595140023SAndrea Di Biagio 32695140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckRegOperand")) 32795140023SAndrea Di Biagio return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"), 3283d2b7176SAndrea Di Biagio Rec->getValueAsDef("Reg"), 3293d2b7176SAndrea Di Biagio Rec->getValueAsString("FunctionMapper")); 3303d2b7176SAndrea Di Biagio 3313d2b7176SAndrea Di Biagio if (Rec->isSubClassOf("CheckRegOperandSimple")) 33258e94f91SEvandro Menezes return expandCheckRegOperandSimple(OS, Rec->getValueAsInt("OpIndex"), 3333d2b7176SAndrea Di Biagio Rec->getValueAsString("FunctionMapper")); 33495140023SAndrea Di Biagio 3359a2e9db7SAndrea Di Biagio if (Rec->isSubClassOf("CheckInvalidRegOperand")) 3369a2e9db7SAndrea Di Biagio return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex")); 3379a2e9db7SAndrea Di Biagio 33895140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckImmOperand")) 33995140023SAndrea Di Biagio return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), 3403d2b7176SAndrea Di Biagio Rec->getValueAsInt("ImmVal"), 3413d2b7176SAndrea Di Biagio Rec->getValueAsString("FunctionMapper")); 34295140023SAndrea Di Biagio 34395140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckImmOperand_s")) 34495140023SAndrea Di Biagio return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), 3453d2b7176SAndrea Di Biagio Rec->getValueAsString("ImmVal"), 3463d2b7176SAndrea Di Biagio Rec->getValueAsString("FunctionMapper")); 3473d2b7176SAndrea Di Biagio 3483d2b7176SAndrea Di Biagio if (Rec->isSubClassOf("CheckImmOperandSimple")) 34958e94f91SEvandro Menezes return expandCheckImmOperandSimple(OS, Rec->getValueAsInt("OpIndex"), 3503d2b7176SAndrea Di Biagio Rec->getValueAsString("FunctionMapper")); 35195140023SAndrea Di Biagio 35295140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckSameRegOperand")) 35395140023SAndrea Di Biagio return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"), 35495140023SAndrea Di Biagio Rec->getValueAsInt("SecondIndex")); 35595140023SAndrea Di Biagio 35695140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckNumOperands")) 35795140023SAndrea Di Biagio return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps")); 35895140023SAndrea Di Biagio 35995140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckPseudo")) 36095140023SAndrea Di Biagio return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes")); 36195140023SAndrea Di Biagio 36295140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckOpcode")) 36395140023SAndrea Di Biagio return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes")); 36495140023SAndrea Di Biagio 36595140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckAll")) 36695140023SAndrea Di Biagio return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"), 36795140023SAndrea Di Biagio /* AllOf */ true); 36895140023SAndrea Di Biagio 36995140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckAny")) 37095140023SAndrea Di Biagio return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"), 37195140023SAndrea Di Biagio /* AllOf */ false); 37295140023SAndrea Di Biagio 373*8a7ca143SEvgeny Leviant if (Rec->isSubClassOf("CheckFunctionPredicate")) { 37495140023SAndrea Di Biagio return expandCheckFunctionPredicate( 37595140023SAndrea Di Biagio OS, Rec->getValueAsString("MCInstFnName"), 37695140023SAndrea Di Biagio Rec->getValueAsString("MachineInstrFnName")); 377*8a7ca143SEvgeny Leviant } 378*8a7ca143SEvgeny Leviant 379*8a7ca143SEvgeny Leviant if (Rec->isSubClassOf("CheckFunctionPredicateWithTII")) { 380*8a7ca143SEvgeny Leviant return expandCheckFunctionPredicateWithTII( 381*8a7ca143SEvgeny Leviant OS, Rec->getValueAsString("MCInstFnName"), 382*8a7ca143SEvgeny Leviant Rec->getValueAsString("MachineInstrFnName"), 383*8a7ca143SEvgeny Leviant Rec->getValueAsString("TIIPtrName")); 384*8a7ca143SEvgeny Leviant } 38595140023SAndrea Di Biagio 38695140023SAndrea Di Biagio if (Rec->isSubClassOf("CheckNonPortable")) 38795140023SAndrea Di Biagio return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock")); 38895140023SAndrea Di Biagio 38995140023SAndrea Di Biagio if (Rec->isSubClassOf("TIIPredicate")) 3909eaf5aa0SAndrea Di Biagio return expandTIIFunctionCall(OS, Rec->getValueAsString("FunctionName")); 39195140023SAndrea Di Biagio 39295140023SAndrea Di Biagio llvm_unreachable("No known rules to expand this MCInstPredicate"); 39395140023SAndrea Di Biagio } 39495140023SAndrea Di Biagio 3958b6c314bSAndrea Di Biagio void STIPredicateExpander::expandHeader(raw_ostream &OS, 3968b6c314bSAndrea Di Biagio const STIPredicateFunction &Fn) { 3978b6c314bSAndrea Di Biagio const Record *Rec = Fn.getDeclaration(); 3988b6c314bSAndrea Di Biagio StringRef FunctionName = Rec->getValueAsString("Name"); 3998b6c314bSAndrea Di Biagio 4008b6c314bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 4018b6c314bSAndrea Di Biagio OS << "bool "; 4028b6c314bSAndrea Di Biagio if (shouldExpandDefinition()) 4038b6c314bSAndrea Di Biagio OS << getClassPrefix() << "::"; 4048b6c314bSAndrea Di Biagio OS << FunctionName << "("; 4058b6c314bSAndrea Di Biagio if (shouldExpandForMC()) 4068b6c314bSAndrea Di Biagio OS << "const MCInst " << (isByRef() ? "&" : "*") << "MI"; 4078b6c314bSAndrea Di Biagio else 4088b6c314bSAndrea Di Biagio OS << "const MachineInstr " << (isByRef() ? "&" : "*") << "MI"; 4098b6c314bSAndrea Di Biagio if (Rec->getValueAsBit("UpdatesOpcodeMask")) 4108b6c314bSAndrea Di Biagio OS << ", APInt &Mask"; 4118b6c314bSAndrea Di Biagio OS << (shouldExpandForMC() ? ", unsigned ProcessorID) const " : ") const "); 4128b6c314bSAndrea Di Biagio if (shouldExpandDefinition()) { 4138b6c314bSAndrea Di Biagio OS << "{\n"; 4148b6c314bSAndrea Di Biagio return; 4158b6c314bSAndrea Di Biagio } 4168b6c314bSAndrea Di Biagio 4178b6c314bSAndrea Di Biagio if (Rec->getValueAsBit("OverridesBaseClassMember")) 4188b6c314bSAndrea Di Biagio OS << "override"; 4198b6c314bSAndrea Di Biagio OS << ";\n"; 4208b6c314bSAndrea Di Biagio } 4218b6c314bSAndrea Di Biagio 4228b6c314bSAndrea Di Biagio void STIPredicateExpander::expandPrologue(raw_ostream &OS, 4238b6c314bSAndrea Di Biagio const STIPredicateFunction &Fn) { 4248b6c314bSAndrea Di Biagio RecVec Delegates = Fn.getDeclaration()->getValueAsListOfDefs("Delegates"); 4258b6c314bSAndrea Di Biagio bool UpdatesOpcodeMask = 4268b6c314bSAndrea Di Biagio Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask"); 4278b6c314bSAndrea Di Biagio 4288b6c314bSAndrea Di Biagio increaseIndentLevel(); 4298b6c314bSAndrea Di Biagio unsigned IndentLevel = getIndentLevel(); 4308b6c314bSAndrea Di Biagio for (const Record *Delegate : Delegates) { 4318b6c314bSAndrea Di Biagio OS.indent(IndentLevel * 2); 4328b6c314bSAndrea Di Biagio OS << "if (" << Delegate->getValueAsString("Name") << "(MI"; 4338b6c314bSAndrea Di Biagio if (UpdatesOpcodeMask) 4348b6c314bSAndrea Di Biagio OS << ", Mask"; 4358b6c314bSAndrea Di Biagio if (shouldExpandForMC()) 4368b6c314bSAndrea Di Biagio OS << ", ProcessorID"; 4378b6c314bSAndrea Di Biagio OS << "))\n"; 4388b6c314bSAndrea Di Biagio OS.indent((1 + IndentLevel) * 2); 4398b6c314bSAndrea Di Biagio OS << "return true;\n\n"; 4408b6c314bSAndrea Di Biagio } 4418b6c314bSAndrea Di Biagio 4428b6c314bSAndrea Di Biagio if (shouldExpandForMC()) 4438b6c314bSAndrea Di Biagio return; 4448b6c314bSAndrea Di Biagio 4458b6c314bSAndrea Di Biagio OS.indent(IndentLevel * 2); 4468b6c314bSAndrea Di Biagio OS << "unsigned ProcessorID = getSchedModel().getProcessorID();\n"; 4478b6c314bSAndrea Di Biagio } 4488b6c314bSAndrea Di Biagio 4498b6c314bSAndrea Di Biagio void STIPredicateExpander::expandOpcodeGroup(raw_ostream &OS, const OpcodeGroup &Group, 4508b6c314bSAndrea Di Biagio bool ShouldUpdateOpcodeMask) { 4518b6c314bSAndrea Di Biagio const OpcodeInfo &OI = Group.getOpcodeInfo(); 4528b6c314bSAndrea Di Biagio for (const PredicateInfo &PI : OI.getPredicates()) { 4538b6c314bSAndrea Di Biagio const APInt &ProcModelMask = PI.ProcModelMask; 4548b6c314bSAndrea Di Biagio bool FirstProcID = true; 4558b6c314bSAndrea Di Biagio for (unsigned I = 0, E = ProcModelMask.getActiveBits(); I < E; ++I) { 4568b6c314bSAndrea Di Biagio if (!ProcModelMask[I]) 4578b6c314bSAndrea Di Biagio continue; 4588b6c314bSAndrea Di Biagio 4598b6c314bSAndrea Di Biagio if (FirstProcID) { 4608b6c314bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 4618b6c314bSAndrea Di Biagio OS << "if (ProcessorID == " << I; 4628b6c314bSAndrea Di Biagio } else { 4638b6c314bSAndrea Di Biagio OS << " || ProcessorID == " << I; 4648b6c314bSAndrea Di Biagio } 4658b6c314bSAndrea Di Biagio FirstProcID = false; 4668b6c314bSAndrea Di Biagio } 4678b6c314bSAndrea Di Biagio 4688b6c314bSAndrea Di Biagio OS << ") {\n"; 4698b6c314bSAndrea Di Biagio 4708b6c314bSAndrea Di Biagio increaseIndentLevel(); 4718b6c314bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 4728b6c314bSAndrea Di Biagio if (ShouldUpdateOpcodeMask) { 4738b6c314bSAndrea Di Biagio if (PI.OperandMask.isNullValue()) 4748b6c314bSAndrea Di Biagio OS << "Mask.clearAllBits();\n"; 4758b6c314bSAndrea Di Biagio else 4768b6c314bSAndrea Di Biagio OS << "Mask = " << PI.OperandMask << ";\n"; 4778b6c314bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 4788b6c314bSAndrea Di Biagio } 4798b6c314bSAndrea Di Biagio OS << "return "; 4808b6c314bSAndrea Di Biagio expandPredicate(OS, PI.Predicate); 4818b6c314bSAndrea Di Biagio OS << ";\n"; 4828b6c314bSAndrea Di Biagio decreaseIndentLevel(); 4838b6c314bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 4848b6c314bSAndrea Di Biagio OS << "}\n"; 4858b6c314bSAndrea Di Biagio } 4868b6c314bSAndrea Di Biagio } 4878b6c314bSAndrea Di Biagio 4888b6c314bSAndrea Di Biagio void STIPredicateExpander::expandBody(raw_ostream &OS, 4898b6c314bSAndrea Di Biagio const STIPredicateFunction &Fn) { 4908b6c314bSAndrea Di Biagio bool UpdatesOpcodeMask = 4918b6c314bSAndrea Di Biagio Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask"); 4928b6c314bSAndrea Di Biagio 4938b6c314bSAndrea Di Biagio unsigned IndentLevel = getIndentLevel(); 4948b6c314bSAndrea Di Biagio OS.indent(IndentLevel * 2); 4958b6c314bSAndrea Di Biagio OS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n"; 4968b6c314bSAndrea Di Biagio OS.indent(IndentLevel * 2); 4978b6c314bSAndrea Di Biagio OS << "default:\n"; 4988b6c314bSAndrea Di Biagio OS.indent(IndentLevel * 2); 4998b6c314bSAndrea Di Biagio OS << " break;"; 5008b6c314bSAndrea Di Biagio 5018b6c314bSAndrea Di Biagio for (const OpcodeGroup &Group : Fn.getGroups()) { 5028b6c314bSAndrea Di Biagio for (const Record *Opcode : Group.getOpcodes()) { 5038b6c314bSAndrea Di Biagio OS << '\n'; 5048b6c314bSAndrea Di Biagio OS.indent(IndentLevel * 2); 5058b6c314bSAndrea Di Biagio OS << "case " << getTargetName() << "::" << Opcode->getName() << ":"; 5068b6c314bSAndrea Di Biagio } 5078b6c314bSAndrea Di Biagio 5088b6c314bSAndrea Di Biagio OS << '\n'; 5098b6c314bSAndrea Di Biagio increaseIndentLevel(); 5108b6c314bSAndrea Di Biagio expandOpcodeGroup(OS, Group, UpdatesOpcodeMask); 5118b6c314bSAndrea Di Biagio 5128b6c314bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 5138b6c314bSAndrea Di Biagio OS << "break;\n"; 5148b6c314bSAndrea Di Biagio decreaseIndentLevel(); 5158b6c314bSAndrea Di Biagio } 5168b6c314bSAndrea Di Biagio 5178b6c314bSAndrea Di Biagio OS.indent(IndentLevel * 2); 5188b6c314bSAndrea Di Biagio OS << "}\n"; 5198b6c314bSAndrea Di Biagio } 5208b6c314bSAndrea Di Biagio 5218b6c314bSAndrea Di Biagio void STIPredicateExpander::expandEpilogue(raw_ostream &OS, 5228b6c314bSAndrea Di Biagio const STIPredicateFunction &Fn) { 5238b6c314bSAndrea Di Biagio OS << '\n'; 5248b6c314bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 5258b6c314bSAndrea Di Biagio OS << "return "; 5268b6c314bSAndrea Di Biagio expandPredicate(OS, Fn.getDefaultReturnPredicate()); 5278b6c314bSAndrea Di Biagio OS << ";\n"; 5288b6c314bSAndrea Di Biagio 5298b6c314bSAndrea Di Biagio decreaseIndentLevel(); 5308b6c314bSAndrea Di Biagio OS.indent(getIndentLevel() * 2); 5318b6c314bSAndrea Di Biagio StringRef FunctionName = Fn.getDeclaration()->getValueAsString("Name"); 5328b6c314bSAndrea Di Biagio OS << "} // " << ClassPrefix << "::" << FunctionName << "\n\n"; 5338b6c314bSAndrea Di Biagio } 5348b6c314bSAndrea Di Biagio 5358b6c314bSAndrea Di Biagio void STIPredicateExpander::expandSTIPredicate(raw_ostream &OS, 5368b6c314bSAndrea Di Biagio const STIPredicateFunction &Fn) { 5378b6c314bSAndrea Di Biagio const Record *Rec = Fn.getDeclaration(); 5388b6c314bSAndrea Di Biagio if (shouldExpandForMC() && !Rec->getValueAsBit("ExpandForMC")) 5398b6c314bSAndrea Di Biagio return; 5408b6c314bSAndrea Di Biagio 5418b6c314bSAndrea Di Biagio expandHeader(OS, Fn); 5428b6c314bSAndrea Di Biagio if (shouldExpandDefinition()) { 5438b6c314bSAndrea Di Biagio expandPrologue(OS, Fn); 5448b6c314bSAndrea Di Biagio expandBody(OS, Fn); 5458b6c314bSAndrea Di Biagio expandEpilogue(OS, Fn); 5468b6c314bSAndrea Di Biagio } 5478b6c314bSAndrea Di Biagio } 5488b6c314bSAndrea Di Biagio 54995140023SAndrea Di Biagio } // namespace llvm 550