1336809Sdim//===--------------------- PredicateExpander.cpp --------------------------===// 2336809Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6336809Sdim// 7336809Sdim//===----------------------------------------------------------------------===// 8336809Sdim/// \file 9336809Sdim/// Functionalities used by the Tablegen backends to expand machine predicates. 10336809Sdim// 11336809Sdim//===----------------------------------------------------------------------===// 12336809Sdim 13336809Sdim#include "PredicateExpander.h" 14344779Sdim#include "CodeGenSchedule.h" // Definition of STIPredicateFunction. 15336809Sdim 16336809Sdimnamespace llvm { 17336809Sdim 18344779Sdimvoid PredicateExpander::expandTrue(raw_ostream &OS) { OS << "true"; } 19344779Sdimvoid PredicateExpander::expandFalse(raw_ostream &OS) { OS << "false"; } 20344779Sdim 21344779Sdimvoid PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex, 22344779Sdim int ImmVal, 23344779Sdim StringRef FunctionMapper) { 24344779Sdim if (!FunctionMapper.empty()) 25344779Sdim OS << FunctionMapper << "("; 26344779Sdim OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 27344779Sdim << ").getImm()"; 28344779Sdim if (!FunctionMapper.empty()) 29344779Sdim OS << ")"; 30344779Sdim OS << (shouldNegate() ? " != " : " == ") << ImmVal; 31336809Sdim} 32336809Sdim 33344779Sdimvoid PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex, 34344779Sdim StringRef ImmVal, 35344779Sdim StringRef FunctionMapper) { 36344779Sdim if (ImmVal.empty()) 37344779Sdim expandCheckImmOperandSimple(OS, OpIndex, FunctionMapper); 38344779Sdim 39344779Sdim if (!FunctionMapper.empty()) 40344779Sdim OS << FunctionMapper << "("; 41336809Sdim OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 42344779Sdim << ").getImm()"; 43344779Sdim if (!FunctionMapper.empty()) 44344779Sdim OS << ")"; 45344779Sdim OS << (shouldNegate() ? " != " : " == ") << ImmVal; 46336809Sdim} 47336809Sdim 48344779Sdimvoid PredicateExpander::expandCheckImmOperandSimple(raw_ostream &OS, 49344779Sdim int OpIndex, 50344779Sdim StringRef FunctionMapper) { 51344779Sdim if (shouldNegate()) 52344779Sdim OS << "!"; 53344779Sdim if (!FunctionMapper.empty()) 54344779Sdim OS << FunctionMapper << "("; 55336809Sdim OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 56344779Sdim << ").getImm()"; 57344779Sdim if (!FunctionMapper.empty()) 58344779Sdim OS << ")"; 59336809Sdim} 60336809Sdim 61344779Sdimvoid PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex, 62344779Sdim const Record *Reg, 63344779Sdim StringRef FunctionMapper) { 64336809Sdim assert(Reg->isSubClassOf("Register") && "Expected a register Record!"); 65336809Sdim 66344779Sdim if (!FunctionMapper.empty()) 67344779Sdim OS << FunctionMapper << "("; 68336809Sdim OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 69344779Sdim << ").getReg()"; 70344779Sdim if (!FunctionMapper.empty()) 71344779Sdim OS << ")"; 72344779Sdim OS << (shouldNegate() ? " != " : " == "); 73336809Sdim const StringRef Str = Reg->getValueAsString("Namespace"); 74336809Sdim if (!Str.empty()) 75336809Sdim OS << Str << "::"; 76336809Sdim OS << Reg->getName(); 77336809Sdim} 78336809Sdim 79344779Sdim 80344779Sdimvoid PredicateExpander::expandCheckRegOperandSimple(raw_ostream &OS, 81344779Sdim int OpIndex, 82344779Sdim StringRef FunctionMapper) { 83344779Sdim if (shouldNegate()) 84344779Sdim OS << "!"; 85344779Sdim if (!FunctionMapper.empty()) 86344779Sdim OS << FunctionMapper << "("; 87344779Sdim OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 88344779Sdim << ").getReg()"; 89344779Sdim if (!FunctionMapper.empty()) 90344779Sdim OS << ")"; 91344779Sdim} 92344779Sdim 93344779Sdimvoid PredicateExpander::expandCheckInvalidRegOperand(raw_ostream &OS, 94336809Sdim int OpIndex) { 95336809Sdim OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex 96336809Sdim << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0"; 97336809Sdim} 98336809Sdim 99344779Sdimvoid PredicateExpander::expandCheckSameRegOperand(raw_ostream &OS, int First, 100344779Sdim int Second) { 101336809Sdim OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First 102336809Sdim << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI" 103336809Sdim << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()"; 104336809Sdim} 105336809Sdim 106344779Sdimvoid PredicateExpander::expandCheckNumOperands(raw_ostream &OS, int NumOps) { 107336809Sdim OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() " 108336809Sdim << (shouldNegate() ? "!= " : "== ") << NumOps; 109336809Sdim} 110336809Sdim 111344779Sdimvoid PredicateExpander::expandCheckOpcode(raw_ostream &OS, const Record *Inst) { 112336809Sdim OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() " 113336809Sdim << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace") 114336809Sdim << "::" << Inst->getName(); 115336809Sdim} 116336809Sdim 117344779Sdimvoid PredicateExpander::expandCheckOpcode(raw_ostream &OS, 118336809Sdim const RecVec &Opcodes) { 119336809Sdim assert(!Opcodes.empty() && "Expected at least one opcode to check!"); 120336809Sdim bool First = true; 121336809Sdim 122336809Sdim if (Opcodes.size() == 1) { 123336809Sdim OS << "( "; 124336809Sdim expandCheckOpcode(OS, Opcodes[0]); 125336809Sdim OS << " )"; 126336809Sdim return; 127336809Sdim } 128336809Sdim 129336809Sdim OS << '('; 130336809Sdim increaseIndentLevel(); 131336809Sdim for (const Record *Rec : Opcodes) { 132336809Sdim OS << '\n'; 133344779Sdim OS.indent(getIndentLevel() * 2); 134336809Sdim if (!First) 135336809Sdim OS << (shouldNegate() ? "&& " : "|| "); 136336809Sdim 137336809Sdim expandCheckOpcode(OS, Rec); 138336809Sdim First = false; 139336809Sdim } 140336809Sdim 141336809Sdim OS << '\n'; 142336809Sdim decreaseIndentLevel(); 143344779Sdim OS.indent(getIndentLevel() * 2); 144336809Sdim OS << ')'; 145336809Sdim} 146336809Sdim 147344779Sdimvoid PredicateExpander::expandCheckPseudo(raw_ostream &OS, 148336809Sdim const RecVec &Opcodes) { 149336809Sdim if (shouldExpandForMC()) 150336809Sdim expandFalse(OS); 151336809Sdim else 152336809Sdim expandCheckOpcode(OS, Opcodes); 153336809Sdim} 154336809Sdim 155344779Sdimvoid PredicateExpander::expandPredicateSequence(raw_ostream &OS, 156336809Sdim const RecVec &Sequence, 157336809Sdim bool IsCheckAll) { 158336809Sdim assert(!Sequence.empty() && "Found an invalid empty predicate set!"); 159336809Sdim if (Sequence.size() == 1) 160336809Sdim return expandPredicate(OS, Sequence[0]); 161336809Sdim 162336809Sdim // Okay, there is more than one predicate in the set. 163336809Sdim bool First = true; 164336809Sdim OS << (shouldNegate() ? "!(" : "("); 165336809Sdim increaseIndentLevel(); 166336809Sdim 167336809Sdim bool OldValue = shouldNegate(); 168336809Sdim setNegatePredicate(false); 169336809Sdim for (const Record *Rec : Sequence) { 170336809Sdim OS << '\n'; 171344779Sdim OS.indent(getIndentLevel() * 2); 172336809Sdim if (!First) 173336809Sdim OS << (IsCheckAll ? "&& " : "|| "); 174336809Sdim expandPredicate(OS, Rec); 175336809Sdim First = false; 176336809Sdim } 177336809Sdim OS << '\n'; 178336809Sdim decreaseIndentLevel(); 179344779Sdim OS.indent(getIndentLevel() * 2); 180336809Sdim OS << ')'; 181336809Sdim setNegatePredicate(OldValue); 182336809Sdim} 183336809Sdim 184344779Sdimvoid PredicateExpander::expandTIIFunctionCall(raw_ostream &OS, 185336809Sdim StringRef MethodName) { 186336809Sdim OS << (shouldNegate() ? "!" : ""); 187344779Sdim OS << TargetName << (shouldExpandForMC() ? "_MC::" : "InstrInfo::"); 188336809Sdim OS << MethodName << (isByRef() ? "(MI)" : "(*MI)"); 189336809Sdim} 190336809Sdim 191344779Sdimvoid PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) { 192336809Sdim OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->") 193336809Sdim << "getOperand(" << OpIndex << ").isReg() "; 194336809Sdim} 195336809Sdim 196344779Sdimvoid PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) { 197336809Sdim OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->") 198336809Sdim << "getOperand(" << OpIndex << ").isImm() "; 199336809Sdim} 200336809Sdim 201344779Sdimvoid PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS, 202336809Sdim StringRef MCInstFn, 203336809Sdim StringRef MachineInstrFn) { 204336809Sdim OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn) 205336809Sdim << (isByRef() ? "(MI)" : "(*MI)"); 206336809Sdim} 207336809Sdim 208344779Sdimvoid PredicateExpander::expandCheckNonPortable(raw_ostream &OS, 209336809Sdim StringRef Code) { 210336809Sdim if (shouldExpandForMC()) 211336809Sdim return expandFalse(OS); 212336809Sdim 213336809Sdim OS << '(' << Code << ')'; 214336809Sdim} 215336809Sdim 216344779Sdimvoid PredicateExpander::expandReturnStatement(raw_ostream &OS, 217344779Sdim const Record *Rec) { 218344779Sdim std::string Buffer; 219344779Sdim raw_string_ostream SS(Buffer); 220336809Sdim 221344779Sdim SS << "return "; 222344779Sdim expandPredicate(SS, Rec); 223344779Sdim SS << ";"; 224344779Sdim SS.flush(); 225344779Sdim OS << Buffer; 226344779Sdim} 227344779Sdim 228344779Sdimvoid PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS, 229344779Sdim const Record *Rec) { 230344779Sdim const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes"); 231344779Sdim for (const Record *Opcode : Opcodes) { 232344779Sdim OS.indent(getIndentLevel() * 2); 233344779Sdim OS << "case " << Opcode->getValueAsString("Namespace") 234344779Sdim << "::" << Opcode->getName() << ":\n"; 235344779Sdim } 236344779Sdim 237344779Sdim increaseIndentLevel(); 238344779Sdim OS.indent(getIndentLevel() * 2); 239344779Sdim expandStatement(OS, Rec->getValueAsDef("CaseStmt")); 240344779Sdim decreaseIndentLevel(); 241344779Sdim} 242344779Sdim 243344779Sdimvoid PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS, 244344779Sdim const RecVec &Cases, 245344779Sdim const Record *Default) { 246344779Sdim std::string Buffer; 247344779Sdim raw_string_ostream SS(Buffer); 248344779Sdim 249344779Sdim SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n"; 250344779Sdim for (const Record *Rec : Cases) { 251344779Sdim expandOpcodeSwitchCase(SS, Rec); 252344779Sdim SS << '\n'; 253344779Sdim } 254344779Sdim 255344779Sdim // Expand the default case. 256344779Sdim SS.indent(getIndentLevel() * 2); 257344779Sdim SS << "default:\n"; 258344779Sdim 259344779Sdim increaseIndentLevel(); 260344779Sdim SS.indent(getIndentLevel() * 2); 261344779Sdim expandStatement(SS, Default); 262344779Sdim decreaseIndentLevel(); 263344779Sdim SS << '\n'; 264344779Sdim 265344779Sdim SS.indent(getIndentLevel() * 2); 266344779Sdim SS << "} // end of switch-stmt"; 267344779Sdim SS.flush(); 268344779Sdim OS << Buffer; 269344779Sdim} 270344779Sdim 271344779Sdimvoid PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) { 272344779Sdim // Assume that padding has been added by the caller. 273344779Sdim if (Rec->isSubClassOf("MCOpcodeSwitchStatement")) { 274344779Sdim expandOpcodeSwitchStatement(OS, Rec->getValueAsListOfDefs("Cases"), 275344779Sdim Rec->getValueAsDef("DefaultCase")); 276344779Sdim return; 277344779Sdim } 278344779Sdim 279344779Sdim if (Rec->isSubClassOf("MCReturnStatement")) { 280344779Sdim expandReturnStatement(OS, Rec->getValueAsDef("Pred")); 281344779Sdim return; 282344779Sdim } 283344779Sdim 284344779Sdim llvm_unreachable("No known rules to expand this MCStatement"); 285344779Sdim} 286344779Sdim 287344779Sdimvoid PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) { 288344779Sdim // Assume that padding has been added by the caller. 289336809Sdim if (Rec->isSubClassOf("MCTrue")) { 290336809Sdim if (shouldNegate()) 291336809Sdim return expandFalse(OS); 292336809Sdim return expandTrue(OS); 293336809Sdim } 294336809Sdim 295336809Sdim if (Rec->isSubClassOf("MCFalse")) { 296336809Sdim if (shouldNegate()) 297336809Sdim return expandTrue(OS); 298336809Sdim return expandFalse(OS); 299336809Sdim } 300336809Sdim 301336809Sdim if (Rec->isSubClassOf("CheckNot")) { 302336809Sdim flipNegatePredicate(); 303336809Sdim expandPredicate(OS, Rec->getValueAsDef("Pred")); 304336809Sdim flipNegatePredicate(); 305336809Sdim return; 306336809Sdim } 307336809Sdim 308336809Sdim if (Rec->isSubClassOf("CheckIsRegOperand")) 309336809Sdim return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex")); 310336809Sdim 311336809Sdim if (Rec->isSubClassOf("CheckIsImmOperand")) 312336809Sdim return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex")); 313336809Sdim 314336809Sdim if (Rec->isSubClassOf("CheckRegOperand")) 315336809Sdim return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"), 316344779Sdim Rec->getValueAsDef("Reg"), 317344779Sdim Rec->getValueAsString("FunctionMapper")); 318336809Sdim 319344779Sdim if (Rec->isSubClassOf("CheckRegOperandSimple")) 320344779Sdim return expandCheckRegOperandSimple(OS, Rec->getValueAsInt("OpIndex"), 321344779Sdim Rec->getValueAsString("FunctionMapper")); 322344779Sdim 323336809Sdim if (Rec->isSubClassOf("CheckInvalidRegOperand")) 324336809Sdim return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex")); 325336809Sdim 326336809Sdim if (Rec->isSubClassOf("CheckImmOperand")) 327336809Sdim return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), 328344779Sdim Rec->getValueAsInt("ImmVal"), 329344779Sdim Rec->getValueAsString("FunctionMapper")); 330336809Sdim 331336809Sdim if (Rec->isSubClassOf("CheckImmOperand_s")) 332336809Sdim return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), 333344779Sdim Rec->getValueAsString("ImmVal"), 334344779Sdim Rec->getValueAsString("FunctionMapper")); 335336809Sdim 336344779Sdim if (Rec->isSubClassOf("CheckImmOperandSimple")) 337344779Sdim return expandCheckImmOperandSimple(OS, Rec->getValueAsInt("OpIndex"), 338344779Sdim Rec->getValueAsString("FunctionMapper")); 339344779Sdim 340336809Sdim if (Rec->isSubClassOf("CheckSameRegOperand")) 341336809Sdim return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"), 342336809Sdim Rec->getValueAsInt("SecondIndex")); 343336809Sdim 344336809Sdim if (Rec->isSubClassOf("CheckNumOperands")) 345336809Sdim return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps")); 346336809Sdim 347336809Sdim if (Rec->isSubClassOf("CheckPseudo")) 348336809Sdim return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes")); 349336809Sdim 350336809Sdim if (Rec->isSubClassOf("CheckOpcode")) 351336809Sdim return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes")); 352336809Sdim 353336809Sdim if (Rec->isSubClassOf("CheckAll")) 354336809Sdim return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"), 355336809Sdim /* AllOf */ true); 356336809Sdim 357336809Sdim if (Rec->isSubClassOf("CheckAny")) 358336809Sdim return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"), 359336809Sdim /* AllOf */ false); 360336809Sdim 361336809Sdim if (Rec->isSubClassOf("CheckFunctionPredicate")) 362336809Sdim return expandCheckFunctionPredicate( 363336809Sdim OS, Rec->getValueAsString("MCInstFnName"), 364336809Sdim Rec->getValueAsString("MachineInstrFnName")); 365336809Sdim 366336809Sdim if (Rec->isSubClassOf("CheckNonPortable")) 367336809Sdim return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock")); 368336809Sdim 369336809Sdim if (Rec->isSubClassOf("TIIPredicate")) 370344779Sdim return expandTIIFunctionCall(OS, Rec->getValueAsString("FunctionName")); 371336809Sdim 372336809Sdim llvm_unreachable("No known rules to expand this MCInstPredicate"); 373336809Sdim} 374336809Sdim 375344779Sdimvoid STIPredicateExpander::expandHeader(raw_ostream &OS, 376344779Sdim const STIPredicateFunction &Fn) { 377344779Sdim const Record *Rec = Fn.getDeclaration(); 378344779Sdim StringRef FunctionName = Rec->getValueAsString("Name"); 379344779Sdim 380344779Sdim OS.indent(getIndentLevel() * 2); 381344779Sdim OS << "bool "; 382344779Sdim if (shouldExpandDefinition()) 383344779Sdim OS << getClassPrefix() << "::"; 384344779Sdim OS << FunctionName << "("; 385344779Sdim if (shouldExpandForMC()) 386344779Sdim OS << "const MCInst " << (isByRef() ? "&" : "*") << "MI"; 387344779Sdim else 388344779Sdim OS << "const MachineInstr " << (isByRef() ? "&" : "*") << "MI"; 389344779Sdim if (Rec->getValueAsBit("UpdatesOpcodeMask")) 390344779Sdim OS << ", APInt &Mask"; 391344779Sdim OS << (shouldExpandForMC() ? ", unsigned ProcessorID) const " : ") const "); 392344779Sdim if (shouldExpandDefinition()) { 393344779Sdim OS << "{\n"; 394344779Sdim return; 395344779Sdim } 396344779Sdim 397344779Sdim if (Rec->getValueAsBit("OverridesBaseClassMember")) 398344779Sdim OS << "override"; 399344779Sdim OS << ";\n"; 400344779Sdim} 401344779Sdim 402344779Sdimvoid STIPredicateExpander::expandPrologue(raw_ostream &OS, 403344779Sdim const STIPredicateFunction &Fn) { 404344779Sdim RecVec Delegates = Fn.getDeclaration()->getValueAsListOfDefs("Delegates"); 405344779Sdim bool UpdatesOpcodeMask = 406344779Sdim Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask"); 407344779Sdim 408344779Sdim increaseIndentLevel(); 409344779Sdim unsigned IndentLevel = getIndentLevel(); 410344779Sdim for (const Record *Delegate : Delegates) { 411344779Sdim OS.indent(IndentLevel * 2); 412344779Sdim OS << "if (" << Delegate->getValueAsString("Name") << "(MI"; 413344779Sdim if (UpdatesOpcodeMask) 414344779Sdim OS << ", Mask"; 415344779Sdim if (shouldExpandForMC()) 416344779Sdim OS << ", ProcessorID"; 417344779Sdim OS << "))\n"; 418344779Sdim OS.indent((1 + IndentLevel) * 2); 419344779Sdim OS << "return true;\n\n"; 420344779Sdim } 421344779Sdim 422344779Sdim if (shouldExpandForMC()) 423344779Sdim return; 424344779Sdim 425344779Sdim OS.indent(IndentLevel * 2); 426344779Sdim OS << "unsigned ProcessorID = getSchedModel().getProcessorID();\n"; 427344779Sdim} 428344779Sdim 429344779Sdimvoid STIPredicateExpander::expandOpcodeGroup(raw_ostream &OS, const OpcodeGroup &Group, 430344779Sdim bool ShouldUpdateOpcodeMask) { 431344779Sdim const OpcodeInfo &OI = Group.getOpcodeInfo(); 432344779Sdim for (const PredicateInfo &PI : OI.getPredicates()) { 433344779Sdim const APInt &ProcModelMask = PI.ProcModelMask; 434344779Sdim bool FirstProcID = true; 435344779Sdim for (unsigned I = 0, E = ProcModelMask.getActiveBits(); I < E; ++I) { 436344779Sdim if (!ProcModelMask[I]) 437344779Sdim continue; 438344779Sdim 439344779Sdim if (FirstProcID) { 440344779Sdim OS.indent(getIndentLevel() * 2); 441344779Sdim OS << "if (ProcessorID == " << I; 442344779Sdim } else { 443344779Sdim OS << " || ProcessorID == " << I; 444344779Sdim } 445344779Sdim FirstProcID = false; 446344779Sdim } 447344779Sdim 448344779Sdim OS << ") {\n"; 449344779Sdim 450344779Sdim increaseIndentLevel(); 451344779Sdim OS.indent(getIndentLevel() * 2); 452344779Sdim if (ShouldUpdateOpcodeMask) { 453344779Sdim if (PI.OperandMask.isNullValue()) 454344779Sdim OS << "Mask.clearAllBits();\n"; 455344779Sdim else 456344779Sdim OS << "Mask = " << PI.OperandMask << ";\n"; 457344779Sdim OS.indent(getIndentLevel() * 2); 458344779Sdim } 459344779Sdim OS << "return "; 460344779Sdim expandPredicate(OS, PI.Predicate); 461344779Sdim OS << ";\n"; 462344779Sdim decreaseIndentLevel(); 463344779Sdim OS.indent(getIndentLevel() * 2); 464344779Sdim OS << "}\n"; 465344779Sdim } 466344779Sdim} 467344779Sdim 468344779Sdimvoid STIPredicateExpander::expandBody(raw_ostream &OS, 469344779Sdim const STIPredicateFunction &Fn) { 470344779Sdim bool UpdatesOpcodeMask = 471344779Sdim Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask"); 472344779Sdim 473344779Sdim unsigned IndentLevel = getIndentLevel(); 474344779Sdim OS.indent(IndentLevel * 2); 475344779Sdim OS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n"; 476344779Sdim OS.indent(IndentLevel * 2); 477344779Sdim OS << "default:\n"; 478344779Sdim OS.indent(IndentLevel * 2); 479344779Sdim OS << " break;"; 480344779Sdim 481344779Sdim for (const OpcodeGroup &Group : Fn.getGroups()) { 482344779Sdim for (const Record *Opcode : Group.getOpcodes()) { 483344779Sdim OS << '\n'; 484344779Sdim OS.indent(IndentLevel * 2); 485344779Sdim OS << "case " << getTargetName() << "::" << Opcode->getName() << ":"; 486344779Sdim } 487344779Sdim 488344779Sdim OS << '\n'; 489344779Sdim increaseIndentLevel(); 490344779Sdim expandOpcodeGroup(OS, Group, UpdatesOpcodeMask); 491344779Sdim 492344779Sdim OS.indent(getIndentLevel() * 2); 493344779Sdim OS << "break;\n"; 494344779Sdim decreaseIndentLevel(); 495344779Sdim } 496344779Sdim 497344779Sdim OS.indent(IndentLevel * 2); 498344779Sdim OS << "}\n"; 499344779Sdim} 500344779Sdim 501344779Sdimvoid STIPredicateExpander::expandEpilogue(raw_ostream &OS, 502344779Sdim const STIPredicateFunction &Fn) { 503344779Sdim OS << '\n'; 504344779Sdim OS.indent(getIndentLevel() * 2); 505344779Sdim OS << "return "; 506344779Sdim expandPredicate(OS, Fn.getDefaultReturnPredicate()); 507344779Sdim OS << ";\n"; 508344779Sdim 509344779Sdim decreaseIndentLevel(); 510344779Sdim OS.indent(getIndentLevel() * 2); 511344779Sdim StringRef FunctionName = Fn.getDeclaration()->getValueAsString("Name"); 512344779Sdim OS << "} // " << ClassPrefix << "::" << FunctionName << "\n\n"; 513344779Sdim} 514344779Sdim 515344779Sdimvoid STIPredicateExpander::expandSTIPredicate(raw_ostream &OS, 516344779Sdim const STIPredicateFunction &Fn) { 517344779Sdim const Record *Rec = Fn.getDeclaration(); 518344779Sdim if (shouldExpandForMC() && !Rec->getValueAsBit("ExpandForMC")) 519344779Sdim return; 520344779Sdim 521344779Sdim expandHeader(OS, Fn); 522344779Sdim if (shouldExpandDefinition()) { 523344779Sdim expandPrologue(OS, Fn); 524344779Sdim expandBody(OS, Fn); 525344779Sdim expandEpilogue(OS, Fn); 526344779Sdim } 527344779Sdim} 528344779Sdim 529336809Sdim} // namespace llvm 530