1fa3d789dSPierre van Houtryve //===--------------------- PredicateExpander.cpp --------------------------===// 2fa3d789dSPierre van Houtryve // 3fa3d789dSPierre van Houtryve // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fa3d789dSPierre van Houtryve // See https://llvm.org/LICENSE.txt for license information. 5fa3d789dSPierre van Houtryve // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fa3d789dSPierre van Houtryve // 7fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 8fa3d789dSPierre van Houtryve /// \file 9fa3d789dSPierre van Houtryve /// Functionalities used by the Tablegen backends to expand machine predicates. 10fa3d789dSPierre van Houtryve // 11fa3d789dSPierre van Houtryve //===----------------------------------------------------------------------===// 12fa3d789dSPierre van Houtryve 13fa3d789dSPierre van Houtryve #include "PredicateExpander.h" 14fa3d789dSPierre van Houtryve #include "CodeGenSchedule.h" // Definition of STIPredicateFunction. 15fa3d789dSPierre van Houtryve #include "llvm/TableGen/Record.h" 16fa3d789dSPierre van Houtryve 17fa3d789dSPierre van Houtryve namespace llvm { 18fa3d789dSPierre van Houtryve 19fa3d789dSPierre van Houtryve void PredicateExpander::expandTrue(raw_ostream &OS) { OS << "true"; } 20fa3d789dSPierre van Houtryve void PredicateExpander::expandFalse(raw_ostream &OS) { OS << "false"; } 21fa3d789dSPierre van Houtryve 22fa3d789dSPierre van Houtryve void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex, 23fa3d789dSPierre van Houtryve int ImmVal, 24fa3d789dSPierre van Houtryve StringRef FunctionMapper) { 25fa3d789dSPierre van Houtryve if (!FunctionMapper.empty()) 26fa3d789dSPierre van Houtryve OS << FunctionMapper << "("; 27fa3d789dSPierre van Houtryve OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 28fa3d789dSPierre van Houtryve << ").getImm()"; 29fa3d789dSPierre van Houtryve if (!FunctionMapper.empty()) 30fa3d789dSPierre van Houtryve OS << ")"; 31fa3d789dSPierre van Houtryve OS << (shouldNegate() ? " != " : " == ") << ImmVal; 32fa3d789dSPierre van Houtryve } 33fa3d789dSPierre van Houtryve 34fa3d789dSPierre van Houtryve void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex, 35fa3d789dSPierre van Houtryve StringRef ImmVal, 36fa3d789dSPierre van Houtryve StringRef FunctionMapper) { 37fa3d789dSPierre van Houtryve if (ImmVal.empty()) 38fa3d789dSPierre van Houtryve expandCheckImmOperandSimple(OS, OpIndex, FunctionMapper); 39fa3d789dSPierre van Houtryve 40fa3d789dSPierre van Houtryve if (!FunctionMapper.empty()) 41fa3d789dSPierre van Houtryve OS << FunctionMapper << "("; 42fa3d789dSPierre van Houtryve OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 43fa3d789dSPierre van Houtryve << ").getImm()"; 44fa3d789dSPierre van Houtryve if (!FunctionMapper.empty()) 45fa3d789dSPierre van Houtryve OS << ")"; 46fa3d789dSPierre van Houtryve OS << (shouldNegate() ? " != " : " == ") << ImmVal; 47fa3d789dSPierre van Houtryve } 48fa3d789dSPierre van Houtryve 49fa3d789dSPierre van Houtryve void PredicateExpander::expandCheckImmOperandSimple(raw_ostream &OS, 50fa3d789dSPierre van Houtryve int OpIndex, 51fa3d789dSPierre van Houtryve StringRef FunctionMapper) { 52fa3d789dSPierre van Houtryve if (shouldNegate()) 53fa3d789dSPierre van Houtryve OS << "!"; 54fa3d789dSPierre van Houtryve if (!FunctionMapper.empty()) 55fa3d789dSPierre van Houtryve OS << FunctionMapper << "("; 56fa3d789dSPierre van Houtryve OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 57fa3d789dSPierre van Houtryve << ").getImm()"; 58fa3d789dSPierre van Houtryve if (!FunctionMapper.empty()) 59fa3d789dSPierre van Houtryve OS << ")"; 60fa3d789dSPierre van Houtryve } 61fa3d789dSPierre van Houtryve 62fa3d789dSPierre van Houtryve void PredicateExpander::expandCheckImmOperandLT(raw_ostream &OS, int OpIndex, 63fa3d789dSPierre van Houtryve int ImmVal, 64fa3d789dSPierre van Houtryve StringRef FunctionMapper) { 65fa3d789dSPierre van Houtryve if (!FunctionMapper.empty()) 66fa3d789dSPierre van Houtryve OS << FunctionMapper << "("; 67fa3d789dSPierre van Houtryve OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 68fa3d789dSPierre van Houtryve << ").getImm()"; 69fa3d789dSPierre van Houtryve if (!FunctionMapper.empty()) 70fa3d789dSPierre van Houtryve OS << ")"; 71fa3d789dSPierre van Houtryve OS << (shouldNegate() ? " >= " : " < ") << ImmVal; 72fa3d789dSPierre van Houtryve } 73fa3d789dSPierre van Houtryve 74fa3d789dSPierre van Houtryve void PredicateExpander::expandCheckImmOperandGT(raw_ostream &OS, int OpIndex, 75fa3d789dSPierre van Houtryve int ImmVal, 76fa3d789dSPierre van Houtryve StringRef FunctionMapper) { 77fa3d789dSPierre van Houtryve if (!FunctionMapper.empty()) 78fa3d789dSPierre van Houtryve OS << FunctionMapper << "("; 79fa3d789dSPierre van Houtryve OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 80fa3d789dSPierre van Houtryve << ").getImm()"; 81fa3d789dSPierre van Houtryve if (!FunctionMapper.empty()) 82fa3d789dSPierre van Houtryve OS << ")"; 83fa3d789dSPierre van Houtryve OS << (shouldNegate() ? " <= " : " > ") << ImmVal; 84fa3d789dSPierre van Houtryve } 85fa3d789dSPierre van Houtryve 86fa3d789dSPierre van Houtryve void PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex, 87fa3d789dSPierre van Houtryve const Record *Reg, 88fa3d789dSPierre van Houtryve StringRef FunctionMapper) { 89fa3d789dSPierre van Houtryve assert(Reg->isSubClassOf("Register") && "Expected a register Record!"); 90fa3d789dSPierre van Houtryve 91fa3d789dSPierre van Houtryve if (!FunctionMapper.empty()) 92fa3d789dSPierre van Houtryve OS << FunctionMapper << "("; 93fa3d789dSPierre van Houtryve OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 94fa3d789dSPierre van Houtryve << ").getReg()"; 95fa3d789dSPierre van Houtryve if (!FunctionMapper.empty()) 96fa3d789dSPierre van Houtryve OS << ")"; 97fa3d789dSPierre van Houtryve OS << (shouldNegate() ? " != " : " == "); 98fa3d789dSPierre van Houtryve const StringRef Str = Reg->getValueAsString("Namespace"); 99fa3d789dSPierre van Houtryve if (!Str.empty()) 100fa3d789dSPierre van Houtryve OS << Str << "::"; 101fa3d789dSPierre van Houtryve OS << Reg->getName(); 102fa3d789dSPierre van Houtryve } 103fa3d789dSPierre van Houtryve 104fa3d789dSPierre van Houtryve void PredicateExpander::expandCheckRegOperandSimple(raw_ostream &OS, 105fa3d789dSPierre van Houtryve int OpIndex, 106fa3d789dSPierre van Houtryve StringRef FunctionMapper) { 107fa3d789dSPierre van Houtryve if (shouldNegate()) 108fa3d789dSPierre van Houtryve OS << "!"; 109fa3d789dSPierre van Houtryve if (!FunctionMapper.empty()) 110fa3d789dSPierre van Houtryve OS << FunctionMapper << "("; 111fa3d789dSPierre van Houtryve OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 112fa3d789dSPierre van Houtryve << ").getReg()"; 113fa3d789dSPierre van Houtryve if (!FunctionMapper.empty()) 114fa3d789dSPierre van Houtryve OS << ")"; 115fa3d789dSPierre van Houtryve } 116fa3d789dSPierre van Houtryve 117fa3d789dSPierre van Houtryve void PredicateExpander::expandCheckInvalidRegOperand(raw_ostream &OS, 118fa3d789dSPierre van Houtryve int OpIndex) { 119eb8d865cSCraig Topper if (!shouldNegate()) 120eb8d865cSCraig Topper OS << "!"; 121fa3d789dSPierre van Houtryve OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 122eb8d865cSCraig Topper << ").getReg().isValid()"; 123fa3d789dSPierre van Houtryve } 124fa3d789dSPierre van Houtryve 125fa3d789dSPierre van Houtryve void PredicateExpander::expandCheckSameRegOperand(raw_ostream &OS, int First, 126fa3d789dSPierre van Houtryve int Second) { 127fa3d789dSPierre van Houtryve OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First 128fa3d789dSPierre van Houtryve << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI" 129fa3d789dSPierre van Houtryve << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()"; 130fa3d789dSPierre van Houtryve } 131fa3d789dSPierre van Houtryve 132fa3d789dSPierre van Houtryve void PredicateExpander::expandCheckNumOperands(raw_ostream &OS, int NumOps) { 133fa3d789dSPierre van Houtryve OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() " 134fa3d789dSPierre van Houtryve << (shouldNegate() ? "!= " : "== ") << NumOps; 135fa3d789dSPierre van Houtryve } 136fa3d789dSPierre van Houtryve 137fa3d789dSPierre van Houtryve void PredicateExpander::expandCheckOpcode(raw_ostream &OS, const Record *Inst) { 138fa3d789dSPierre van Houtryve OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() " 139fa3d789dSPierre van Houtryve << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace") 140fa3d789dSPierre van Houtryve << "::" << Inst->getName(); 141fa3d789dSPierre van Houtryve } 142fa3d789dSPierre van Houtryve 143fa3d789dSPierre van Houtryve void PredicateExpander::expandCheckOpcode(raw_ostream &OS, 1442b01452cSRahul Joshi ArrayRef<const Record *> Opcodes) { 145fa3d789dSPierre van Houtryve assert(!Opcodes.empty() && "Expected at least one opcode to check!"); 146fa3d789dSPierre van Houtryve bool First = true; 147fa3d789dSPierre van Houtryve 148fa3d789dSPierre van Houtryve if (Opcodes.size() == 1) { 149fa3d789dSPierre van Houtryve OS << "( "; 150fa3d789dSPierre van Houtryve expandCheckOpcode(OS, Opcodes[0]); 151fa3d789dSPierre van Houtryve OS << " )"; 152fa3d789dSPierre van Houtryve return; 153fa3d789dSPierre van Houtryve } 154fa3d789dSPierre van Houtryve 155fa3d789dSPierre van Houtryve OS << '('; 156c92137e4SRahul Joshi ++Indent; 157fa3d789dSPierre van Houtryve for (const Record *Rec : Opcodes) { 158c92137e4SRahul Joshi OS << '\n' << Indent; 159fa3d789dSPierre van Houtryve if (!First) 160fa3d789dSPierre van Houtryve OS << (shouldNegate() ? "&& " : "|| "); 161fa3d789dSPierre van Houtryve 162fa3d789dSPierre van Houtryve expandCheckOpcode(OS, Rec); 163fa3d789dSPierre van Houtryve First = false; 164fa3d789dSPierre van Houtryve } 165fa3d789dSPierre van Houtryve 166c92137e4SRahul Joshi --Indent; 167c92137e4SRahul Joshi OS << '\n' << Indent << ')'; 168fa3d789dSPierre van Houtryve } 169fa3d789dSPierre van Houtryve 170fa3d789dSPierre van Houtryve void PredicateExpander::expandCheckPseudo(raw_ostream &OS, 1712b01452cSRahul Joshi ArrayRef<const Record *> Opcodes) { 172fa3d789dSPierre van Houtryve if (shouldExpandForMC()) 173fa3d789dSPierre van Houtryve expandFalse(OS); 174fa3d789dSPierre van Houtryve else 175fa3d789dSPierre van Houtryve expandCheckOpcode(OS, Opcodes); 176fa3d789dSPierre van Houtryve } 177fa3d789dSPierre van Houtryve 1782b01452cSRahul Joshi void PredicateExpander::expandPredicateSequence( 1792b01452cSRahul Joshi raw_ostream &OS, ArrayRef<const Record *> Sequence, bool IsCheckAll) { 180fa3d789dSPierre van Houtryve assert(!Sequence.empty() && "Found an invalid empty predicate set!"); 181fa3d789dSPierre van Houtryve if (Sequence.size() == 1) 182fa3d789dSPierre van Houtryve return expandPredicate(OS, Sequence[0]); 183fa3d789dSPierre van Houtryve 184fa3d789dSPierre van Houtryve // Okay, there is more than one predicate in the set. 185fa3d789dSPierre van Houtryve bool First = true; 186fa3d789dSPierre van Houtryve OS << (shouldNegate() ? "!(" : "("); 187c92137e4SRahul Joshi ++Indent; 188fa3d789dSPierre van Houtryve 189fa3d789dSPierre van Houtryve bool OldValue = shouldNegate(); 190fa3d789dSPierre van Houtryve setNegatePredicate(false); 191fa3d789dSPierre van Houtryve for (const Record *Rec : Sequence) { 192c92137e4SRahul Joshi OS << '\n' << Indent; 193fa3d789dSPierre van Houtryve if (!First) 194fa3d789dSPierre van Houtryve OS << (IsCheckAll ? "&& " : "|| "); 195fa3d789dSPierre van Houtryve expandPredicate(OS, Rec); 196fa3d789dSPierre van Houtryve First = false; 197fa3d789dSPierre van Houtryve } 198c92137e4SRahul Joshi --Indent; 199c92137e4SRahul Joshi OS << '\n' << Indent << ')'; 200fa3d789dSPierre van Houtryve setNegatePredicate(OldValue); 201fa3d789dSPierre van Houtryve } 202fa3d789dSPierre van Houtryve 203fa3d789dSPierre van Houtryve void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS, 204fa3d789dSPierre van Houtryve StringRef MethodName) { 205fa3d789dSPierre van Houtryve OS << (shouldNegate() ? "!" : ""); 206fa3d789dSPierre van Houtryve OS << TargetName << (shouldExpandForMC() ? "_MC::" : "InstrInfo::"); 207fa3d789dSPierre van Houtryve OS << MethodName << (isByRef() ? "(MI)" : "(*MI)"); 208fa3d789dSPierre van Houtryve } 209fa3d789dSPierre van Houtryve 210fa3d789dSPierre van Houtryve void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) { 211fa3d789dSPierre van Houtryve OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->") 212fa3d789dSPierre van Houtryve << "getOperand(" << OpIndex << ").isReg() "; 213fa3d789dSPierre van Houtryve } 214fa3d789dSPierre van Houtryve 215fa3d789dSPierre van Houtryve void PredicateExpander::expandCheckIsVRegOperand(raw_ostream &OS, int OpIndex) { 216fa3d789dSPierre van Houtryve OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->") 217fa3d789dSPierre van Houtryve << "getOperand(" << OpIndex << ").getReg().isVirtual()"; 218fa3d789dSPierre van Houtryve } 219fa3d789dSPierre van Houtryve 220fa3d789dSPierre van Houtryve void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) { 221fa3d789dSPierre van Houtryve OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->") 222fa3d789dSPierre van Houtryve << "getOperand(" << OpIndex << ").isImm() "; 223fa3d789dSPierre van Houtryve } 224fa3d789dSPierre van Houtryve 225fa3d789dSPierre van Houtryve void PredicateExpander::expandCheckFunctionPredicateWithTII( 226fa3d789dSPierre van Houtryve raw_ostream &OS, StringRef MCInstFn, StringRef MachineInstrFn, 227fa3d789dSPierre van Houtryve StringRef TIIPtr) { 228fa3d789dSPierre van Houtryve if (!shouldExpandForMC()) { 229fa3d789dSPierre van Houtryve OS << (TIIPtr.empty() ? "TII" : TIIPtr) << "->" << MachineInstrFn; 230fa3d789dSPierre van Houtryve OS << (isByRef() ? "(MI)" : "(*MI)"); 231fa3d789dSPierre van Houtryve return; 232fa3d789dSPierre van Houtryve } 233fa3d789dSPierre van Houtryve 234fa3d789dSPierre van Houtryve OS << MCInstFn << (isByRef() ? "(MI" : "(*MI") << ", MCII)"; 235fa3d789dSPierre van Houtryve } 236fa3d789dSPierre van Houtryve 237fa3d789dSPierre van Houtryve void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS, 238fa3d789dSPierre van Houtryve StringRef MCInstFn, 239fa3d789dSPierre van Houtryve StringRef MachineInstrFn) { 240fa3d789dSPierre van Houtryve OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn) 241fa3d789dSPierre van Houtryve << (isByRef() ? "(MI)" : "(*MI)"); 242fa3d789dSPierre van Houtryve } 243fa3d789dSPierre van Houtryve 244fa3d789dSPierre van Houtryve void PredicateExpander::expandCheckNonPortable(raw_ostream &OS, 245fa3d789dSPierre van Houtryve StringRef Code) { 246fa3d789dSPierre van Houtryve if (shouldExpandForMC()) 247fa3d789dSPierre van Houtryve return expandFalse(OS); 248fa3d789dSPierre van Houtryve 249fa3d789dSPierre van Houtryve OS << '(' << Code << ')'; 250fa3d789dSPierre van Houtryve } 251fa3d789dSPierre van Houtryve 252fa3d789dSPierre van Houtryve void PredicateExpander::expandReturnStatement(raw_ostream &OS, 253fa3d789dSPierre van Houtryve const Record *Rec) { 254fa3d789dSPierre van Houtryve std::string Buffer; 255fa3d789dSPierre van Houtryve raw_string_ostream SS(Buffer); 256fa3d789dSPierre van Houtryve 257fa3d789dSPierre van Houtryve SS << "return "; 258fa3d789dSPierre van Houtryve expandPredicate(SS, Rec); 259fa3d789dSPierre van Houtryve SS << ";"; 260fa3d789dSPierre van Houtryve OS << Buffer; 261fa3d789dSPierre van Houtryve } 262fa3d789dSPierre van Houtryve 263fa3d789dSPierre van Houtryve void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS, 264fa3d789dSPierre van Houtryve const Record *Rec) { 2652b01452cSRahul Joshi for (const Record *Opcode : Rec->getValueAsListOfDefs("Opcodes")) { 266c92137e4SRahul Joshi OS << Indent << "case " << Opcode->getValueAsString("Namespace") 267fa3d789dSPierre van Houtryve << "::" << Opcode->getName() << ":\n"; 268fa3d789dSPierre van Houtryve } 269fa3d789dSPierre van Houtryve 270c92137e4SRahul Joshi ++Indent; 271c92137e4SRahul Joshi OS << Indent; 272fa3d789dSPierre van Houtryve expandStatement(OS, Rec->getValueAsDef("CaseStmt")); 273c92137e4SRahul Joshi --Indent; 274fa3d789dSPierre van Houtryve } 275fa3d789dSPierre van Houtryve 2762b01452cSRahul Joshi void PredicateExpander::expandOpcodeSwitchStatement( 2772b01452cSRahul Joshi raw_ostream &OS, ArrayRef<const Record *> Cases, const Record *Default) { 278fa3d789dSPierre van Houtryve std::string Buffer; 279fa3d789dSPierre van Houtryve raw_string_ostream SS(Buffer); 280fa3d789dSPierre van Houtryve 281fa3d789dSPierre van Houtryve SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n"; 282fa3d789dSPierre van Houtryve for (const Record *Rec : Cases) { 283fa3d789dSPierre van Houtryve expandOpcodeSwitchCase(SS, Rec); 284fa3d789dSPierre van Houtryve SS << '\n'; 285fa3d789dSPierre van Houtryve } 286fa3d789dSPierre van Houtryve 287fa3d789dSPierre van Houtryve // Expand the default case. 288c92137e4SRahul Joshi SS << Indent << "default:\n"; 289fa3d789dSPierre van Houtryve 290c92137e4SRahul Joshi ++Indent; 291c92137e4SRahul Joshi SS << Indent; 292fa3d789dSPierre van Houtryve expandStatement(SS, Default); 293c92137e4SRahul Joshi SS << '\n' << Indent << "} // end of switch-stmt"; 294fa3d789dSPierre van Houtryve OS << Buffer; 295fa3d789dSPierre van Houtryve } 296fa3d789dSPierre van Houtryve 297fa3d789dSPierre van Houtryve void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) { 298fa3d789dSPierre van Houtryve // Assume that padding has been added by the caller. 299fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("MCOpcodeSwitchStatement")) { 300*a140931bSRahul Joshi expandOpcodeSwitchStatement(OS, Rec->getValueAsListOfDefs("Cases"), 301fa3d789dSPierre van Houtryve Rec->getValueAsDef("DefaultCase")); 302fa3d789dSPierre van Houtryve return; 303fa3d789dSPierre van Houtryve } 304fa3d789dSPierre van Houtryve 305fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("MCReturnStatement")) { 306fa3d789dSPierre van Houtryve expandReturnStatement(OS, Rec->getValueAsDef("Pred")); 307fa3d789dSPierre van Houtryve return; 308fa3d789dSPierre van Houtryve } 309fa3d789dSPierre van Houtryve 310fa3d789dSPierre van Houtryve llvm_unreachable("No known rules to expand this MCStatement"); 311fa3d789dSPierre van Houtryve } 312fa3d789dSPierre van Houtryve 313fa3d789dSPierre van Houtryve void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) { 314fa3d789dSPierre van Houtryve // Assume that padding has been added by the caller. 315fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("MCTrue")) { 316fa3d789dSPierre van Houtryve if (shouldNegate()) 317fa3d789dSPierre van Houtryve return expandFalse(OS); 318fa3d789dSPierre van Houtryve return expandTrue(OS); 319fa3d789dSPierre van Houtryve } 320fa3d789dSPierre van Houtryve 321fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("MCFalse")) { 322fa3d789dSPierre van Houtryve if (shouldNegate()) 323fa3d789dSPierre van Houtryve return expandTrue(OS); 324fa3d789dSPierre van Houtryve return expandFalse(OS); 325fa3d789dSPierre van Houtryve } 326fa3d789dSPierre van Houtryve 327fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckNot")) { 328fa3d789dSPierre van Houtryve flipNegatePredicate(); 329fa3d789dSPierre van Houtryve expandPredicate(OS, Rec->getValueAsDef("Pred")); 330fa3d789dSPierre van Houtryve flipNegatePredicate(); 331fa3d789dSPierre van Houtryve return; 332fa3d789dSPierre van Houtryve } 333fa3d789dSPierre van Houtryve 334fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckIsRegOperand")) 335fa3d789dSPierre van Houtryve return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex")); 336fa3d789dSPierre van Houtryve 337fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckIsVRegOperand")) 338fa3d789dSPierre van Houtryve return expandCheckIsVRegOperand(OS, Rec->getValueAsInt("OpIndex")); 339fa3d789dSPierre van Houtryve 340fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckIsImmOperand")) 341fa3d789dSPierre van Houtryve return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex")); 342fa3d789dSPierre van Houtryve 343fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckRegOperand")) 344fa3d789dSPierre van Houtryve return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"), 345fa3d789dSPierre van Houtryve Rec->getValueAsDef("Reg"), 346fa3d789dSPierre van Houtryve Rec->getValueAsString("FunctionMapper")); 347fa3d789dSPierre van Houtryve 348fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckRegOperandSimple")) 349fa3d789dSPierre van Houtryve return expandCheckRegOperandSimple(OS, Rec->getValueAsInt("OpIndex"), 350fa3d789dSPierre van Houtryve Rec->getValueAsString("FunctionMapper")); 351fa3d789dSPierre van Houtryve 352fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckInvalidRegOperand")) 353fa3d789dSPierre van Houtryve return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex")); 354fa3d789dSPierre van Houtryve 355fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckImmOperand")) 356fa3d789dSPierre van Houtryve return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), 357fa3d789dSPierre van Houtryve Rec->getValueAsInt("ImmVal"), 358fa3d789dSPierre van Houtryve Rec->getValueAsString("FunctionMapper")); 359fa3d789dSPierre van Houtryve 360fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckImmOperand_s")) 361fa3d789dSPierre van Houtryve return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), 362fa3d789dSPierre van Houtryve Rec->getValueAsString("ImmVal"), 363fa3d789dSPierre van Houtryve Rec->getValueAsString("FunctionMapper")); 364fa3d789dSPierre van Houtryve 365fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckImmOperandLT")) 366fa3d789dSPierre van Houtryve return expandCheckImmOperandLT(OS, Rec->getValueAsInt("OpIndex"), 367fa3d789dSPierre van Houtryve Rec->getValueAsInt("ImmVal"), 368fa3d789dSPierre van Houtryve Rec->getValueAsString("FunctionMapper")); 369fa3d789dSPierre van Houtryve 370fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckImmOperandGT")) 371fa3d789dSPierre van Houtryve return expandCheckImmOperandGT(OS, Rec->getValueAsInt("OpIndex"), 372fa3d789dSPierre van Houtryve Rec->getValueAsInt("ImmVal"), 373fa3d789dSPierre van Houtryve Rec->getValueAsString("FunctionMapper")); 374fa3d789dSPierre van Houtryve 375fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckImmOperandSimple")) 376fa3d789dSPierre van Houtryve return expandCheckImmOperandSimple(OS, Rec->getValueAsInt("OpIndex"), 377fa3d789dSPierre van Houtryve Rec->getValueAsString("FunctionMapper")); 378fa3d789dSPierre van Houtryve 379fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckSameRegOperand")) 380fa3d789dSPierre van Houtryve return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"), 381fa3d789dSPierre van Houtryve Rec->getValueAsInt("SecondIndex")); 382fa3d789dSPierre van Houtryve 383fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckNumOperands")) 384fa3d789dSPierre van Houtryve return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps")); 385fa3d789dSPierre van Houtryve 386fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckPseudo")) 387fa3d789dSPierre van Houtryve return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes")); 388fa3d789dSPierre van Houtryve 389fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckOpcode")) 390fa3d789dSPierre van Houtryve return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes")); 391fa3d789dSPierre van Houtryve 392fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckAll")) 393fa3d789dSPierre van Houtryve return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"), 394fa3d789dSPierre van Houtryve /* AllOf */ true); 395fa3d789dSPierre van Houtryve 396fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckAny")) 397fa3d789dSPierre van Houtryve return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"), 398fa3d789dSPierre van Houtryve /* AllOf */ false); 399fa3d789dSPierre van Houtryve 400fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckFunctionPredicate")) { 401fa3d789dSPierre van Houtryve return expandCheckFunctionPredicate( 402fa3d789dSPierre van Houtryve OS, Rec->getValueAsString("MCInstFnName"), 403fa3d789dSPierre van Houtryve Rec->getValueAsString("MachineInstrFnName")); 404fa3d789dSPierre van Houtryve } 405fa3d789dSPierre van Houtryve 406fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckFunctionPredicateWithTII")) { 407fa3d789dSPierre van Houtryve return expandCheckFunctionPredicateWithTII( 408fa3d789dSPierre van Houtryve OS, Rec->getValueAsString("MCInstFnName"), 409fa3d789dSPierre van Houtryve Rec->getValueAsString("MachineInstrFnName"), 410fa3d789dSPierre van Houtryve Rec->getValueAsString("TIIPtrName")); 411fa3d789dSPierre van Houtryve } 412fa3d789dSPierre van Houtryve 413fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("CheckNonPortable")) 414fa3d789dSPierre van Houtryve return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock")); 415fa3d789dSPierre van Houtryve 416fa3d789dSPierre van Houtryve if (Rec->isSubClassOf("TIIPredicate")) 417fa3d789dSPierre van Houtryve return expandTIIFunctionCall(OS, Rec->getValueAsString("FunctionName")); 418fa3d789dSPierre van Houtryve 419fa3d789dSPierre van Houtryve llvm_unreachable("No known rules to expand this MCInstPredicate"); 420fa3d789dSPierre van Houtryve } 421fa3d789dSPierre van Houtryve 422fa3d789dSPierre van Houtryve void STIPredicateExpander::expandHeader(raw_ostream &OS, 423fa3d789dSPierre van Houtryve const STIPredicateFunction &Fn) { 424fa3d789dSPierre van Houtryve const Record *Rec = Fn.getDeclaration(); 425fa3d789dSPierre van Houtryve StringRef FunctionName = Rec->getValueAsString("Name"); 426fa3d789dSPierre van Houtryve 427c92137e4SRahul Joshi OS << Indent << "bool "; 428fa3d789dSPierre van Houtryve if (shouldExpandDefinition()) 429fa3d789dSPierre van Houtryve OS << getClassPrefix() << "::"; 430fa3d789dSPierre van Houtryve OS << FunctionName << "("; 431fa3d789dSPierre van Houtryve if (shouldExpandForMC()) 432fa3d789dSPierre van Houtryve OS << "const MCInst " << (isByRef() ? "&" : "*") << "MI"; 433fa3d789dSPierre van Houtryve else 434fa3d789dSPierre van Houtryve OS << "const MachineInstr " << (isByRef() ? "&" : "*") << "MI"; 435fa3d789dSPierre van Houtryve if (Rec->getValueAsBit("UpdatesOpcodeMask")) 436fa3d789dSPierre van Houtryve OS << ", APInt &Mask"; 437fa3d789dSPierre van Houtryve OS << (shouldExpandForMC() ? ", unsigned ProcessorID) const " : ") const "); 438fa3d789dSPierre van Houtryve if (shouldExpandDefinition()) { 439fa3d789dSPierre van Houtryve OS << "{\n"; 440fa3d789dSPierre van Houtryve return; 441fa3d789dSPierre van Houtryve } 442fa3d789dSPierre van Houtryve 443fa3d789dSPierre van Houtryve if (Rec->getValueAsBit("OverridesBaseClassMember")) 444fa3d789dSPierre van Houtryve OS << "override"; 445fa3d789dSPierre van Houtryve OS << ";\n"; 446fa3d789dSPierre van Houtryve } 447fa3d789dSPierre van Houtryve 448fa3d789dSPierre van Houtryve void STIPredicateExpander::expandPrologue(raw_ostream &OS, 449fa3d789dSPierre van Houtryve const STIPredicateFunction &Fn) { 450fa3d789dSPierre van Houtryve bool UpdatesOpcodeMask = 451fa3d789dSPierre van Houtryve Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask"); 452fa3d789dSPierre van Houtryve 453c92137e4SRahul Joshi ++Indent; 4542b01452cSRahul Joshi for (const Record *Delegate : 4552b01452cSRahul Joshi Fn.getDeclaration()->getValueAsListOfDefs("Delegates")) { 456c92137e4SRahul Joshi OS << Indent << "if (" << Delegate->getValueAsString("Name") << "(MI"; 457fa3d789dSPierre van Houtryve if (UpdatesOpcodeMask) 458fa3d789dSPierre van Houtryve OS << ", Mask"; 459fa3d789dSPierre van Houtryve if (shouldExpandForMC()) 460fa3d789dSPierre van Houtryve OS << ", ProcessorID"; 461fa3d789dSPierre van Houtryve OS << "))\n"; 462c92137e4SRahul Joshi OS << Indent + 1 << "return true;\n\n"; 463fa3d789dSPierre van Houtryve } 464fa3d789dSPierre van Houtryve 465fa3d789dSPierre van Houtryve if (shouldExpandForMC()) 466fa3d789dSPierre van Houtryve return; 467fa3d789dSPierre van Houtryve 468c92137e4SRahul Joshi OS << Indent << "unsigned ProcessorID = getSchedModel().getProcessorID();\n"; 469fa3d789dSPierre van Houtryve } 470fa3d789dSPierre van Houtryve 471fa3d789dSPierre van Houtryve void STIPredicateExpander::expandOpcodeGroup(raw_ostream &OS, 472fa3d789dSPierre van Houtryve const OpcodeGroup &Group, 473fa3d789dSPierre van Houtryve bool ShouldUpdateOpcodeMask) { 474fa3d789dSPierre van Houtryve const OpcodeInfo &OI = Group.getOpcodeInfo(); 475fa3d789dSPierre van Houtryve for (const PredicateInfo &PI : OI.getPredicates()) { 476fa3d789dSPierre van Houtryve const APInt &ProcModelMask = PI.ProcModelMask; 477fa3d789dSPierre van Houtryve bool FirstProcID = true; 478fa3d789dSPierre van Houtryve for (unsigned I = 0, E = ProcModelMask.getActiveBits(); I < E; ++I) { 479fa3d789dSPierre van Houtryve if (!ProcModelMask[I]) 480fa3d789dSPierre van Houtryve continue; 481fa3d789dSPierre van Houtryve 482fa3d789dSPierre van Houtryve if (FirstProcID) { 483c92137e4SRahul Joshi OS << Indent << "if (ProcessorID == " << I; 484fa3d789dSPierre van Houtryve } else { 485fa3d789dSPierre van Houtryve OS << " || ProcessorID == " << I; 486fa3d789dSPierre van Houtryve } 487fa3d789dSPierre van Houtryve FirstProcID = false; 488fa3d789dSPierre van Houtryve } 489fa3d789dSPierre van Houtryve 490fa3d789dSPierre van Houtryve OS << ") {\n"; 491fa3d789dSPierre van Houtryve 492c92137e4SRahul Joshi ++Indent; 493c92137e4SRahul Joshi OS << Indent; 494fa3d789dSPierre van Houtryve if (ShouldUpdateOpcodeMask) { 495fa3d789dSPierre van Houtryve if (PI.OperandMask.isZero()) 496fa3d789dSPierre van Houtryve OS << "Mask.clearAllBits();\n"; 497fa3d789dSPierre van Houtryve else 498fa3d789dSPierre van Houtryve OS << "Mask = " << PI.OperandMask << ";\n"; 499c92137e4SRahul Joshi OS << Indent; 500fa3d789dSPierre van Houtryve } 501fa3d789dSPierre van Houtryve OS << "return "; 502fa3d789dSPierre van Houtryve expandPredicate(OS, PI.Predicate); 503fa3d789dSPierre van Houtryve OS << ";\n"; 504c92137e4SRahul Joshi --Indent; 505c92137e4SRahul Joshi OS << Indent << "}\n"; 506fa3d789dSPierre van Houtryve } 507fa3d789dSPierre van Houtryve } 508fa3d789dSPierre van Houtryve 509fa3d789dSPierre van Houtryve void STIPredicateExpander::expandBody(raw_ostream &OS, 510fa3d789dSPierre van Houtryve const STIPredicateFunction &Fn) { 511fa3d789dSPierre van Houtryve bool UpdatesOpcodeMask = 512fa3d789dSPierre van Houtryve Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask"); 513fa3d789dSPierre van Houtryve 514c92137e4SRahul Joshi OS << Indent << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n"; 515c92137e4SRahul Joshi OS << Indent << "default:\n"; 516c92137e4SRahul Joshi OS << Indent << " break;"; 517fa3d789dSPierre van Houtryve 518fa3d789dSPierre van Houtryve for (const OpcodeGroup &Group : Fn.getGroups()) { 519fa3d789dSPierre van Houtryve for (const Record *Opcode : Group.getOpcodes()) { 520c92137e4SRahul Joshi OS << '\n' 521c92137e4SRahul Joshi << Indent << "case " << getTargetName() << "::" << Opcode->getName() 522c92137e4SRahul Joshi << ":"; 523fa3d789dSPierre van Houtryve } 524fa3d789dSPierre van Houtryve 525fa3d789dSPierre van Houtryve OS << '\n'; 526c92137e4SRahul Joshi ++Indent; 527fa3d789dSPierre van Houtryve expandOpcodeGroup(OS, Group, UpdatesOpcodeMask); 528fa3d789dSPierre van Houtryve 529c92137e4SRahul Joshi OS << Indent << "break;\n"; 530c92137e4SRahul Joshi --Indent; 531fa3d789dSPierre van Houtryve } 532fa3d789dSPierre van Houtryve 533c92137e4SRahul Joshi OS << Indent << "}\n"; 534fa3d789dSPierre van Houtryve } 535fa3d789dSPierre van Houtryve 536fa3d789dSPierre van Houtryve void STIPredicateExpander::expandEpilogue(raw_ostream &OS, 537fa3d789dSPierre van Houtryve const STIPredicateFunction &Fn) { 538c92137e4SRahul Joshi OS << '\n' << Indent; 539fa3d789dSPierre van Houtryve OS << "return "; 540fa3d789dSPierre van Houtryve expandPredicate(OS, Fn.getDefaultReturnPredicate()); 541fa3d789dSPierre van Houtryve OS << ";\n"; 542fa3d789dSPierre van Houtryve 543c92137e4SRahul Joshi --Indent; 544fa3d789dSPierre van Houtryve StringRef FunctionName = Fn.getDeclaration()->getValueAsString("Name"); 545c92137e4SRahul Joshi OS << Indent << "} // " << ClassPrefix << "::" << FunctionName << "\n\n"; 546fa3d789dSPierre van Houtryve } 547fa3d789dSPierre van Houtryve 548fa3d789dSPierre van Houtryve void STIPredicateExpander::expandSTIPredicate(raw_ostream &OS, 549fa3d789dSPierre van Houtryve const STIPredicateFunction &Fn) { 550fa3d789dSPierre van Houtryve const Record *Rec = Fn.getDeclaration(); 551fa3d789dSPierre van Houtryve if (shouldExpandForMC() && !Rec->getValueAsBit("ExpandForMC")) 552fa3d789dSPierre van Houtryve return; 553fa3d789dSPierre van Houtryve 554fa3d789dSPierre van Houtryve expandHeader(OS, Fn); 555fa3d789dSPierre van Houtryve if (shouldExpandDefinition()) { 556fa3d789dSPierre van Houtryve expandPrologue(OS, Fn); 557fa3d789dSPierre van Houtryve expandBody(OS, Fn); 558fa3d789dSPierre van Houtryve expandEpilogue(OS, Fn); 559fa3d789dSPierre van Houtryve } 560fa3d789dSPierre van Houtryve } 561fa3d789dSPierre van Houtryve 562fa3d789dSPierre van Houtryve } // namespace llvm 563