530 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			530 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===--------------------- PredicateExpander.cpp --------------------------===//
 | |
| //
 | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | |
| // See https://llvm.org/LICENSE.txt for license information.
 | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| /// \file
 | |
| /// Functionalities used by the Tablegen backends to expand machine predicates.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "PredicateExpander.h"
 | |
| #include "CodeGenSchedule.h" // Definition of STIPredicateFunction.
 | |
| 
 | |
| namespace llvm {
 | |
| 
 | |
| void PredicateExpander::expandTrue(raw_ostream &OS) { OS << "true"; }
 | |
| void PredicateExpander::expandFalse(raw_ostream &OS) { OS << "false"; }
 | |
| 
 | |
| void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
 | |
|                                               int ImmVal,
 | |
|                                               StringRef FunctionMapper) {
 | |
|   if (!FunctionMapper.empty())
 | |
|     OS << FunctionMapper << "(";
 | |
|   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
 | |
|      << ").getImm()";
 | |
|   if (!FunctionMapper.empty())
 | |
|     OS << ")";
 | |
|   OS << (shouldNegate() ? " != " : " == ") << ImmVal;
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex,
 | |
|                                               StringRef ImmVal,
 | |
|                                               StringRef FunctionMapper) {
 | |
|   if (ImmVal.empty())
 | |
|     expandCheckImmOperandSimple(OS, OpIndex, FunctionMapper);
 | |
| 
 | |
|   if (!FunctionMapper.empty())
 | |
|     OS << FunctionMapper << "(";
 | |
|   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
 | |
|      << ").getImm()";
 | |
|   if (!FunctionMapper.empty())
 | |
|     OS << ")";
 | |
|   OS << (shouldNegate() ? " != " : " == ") << ImmVal;
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandCheckImmOperandSimple(raw_ostream &OS,
 | |
|                                                     int OpIndex,
 | |
|                                                     StringRef FunctionMapper) {
 | |
|   if (shouldNegate())
 | |
|     OS << "!";
 | |
|   if (!FunctionMapper.empty())
 | |
|     OS << FunctionMapper << "(";
 | |
|   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
 | |
|      << ").getImm()";
 | |
|   if (!FunctionMapper.empty())
 | |
|     OS << ")";
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex,
 | |
|                                               const Record *Reg,
 | |
|                                               StringRef FunctionMapper) {
 | |
|   assert(Reg->isSubClassOf("Register") && "Expected a register Record!");
 | |
| 
 | |
|   if (!FunctionMapper.empty())
 | |
|     OS << FunctionMapper << "(";
 | |
|   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
 | |
|      << ").getReg()";
 | |
|   if (!FunctionMapper.empty())
 | |
|     OS << ")";
 | |
|   OS << (shouldNegate() ? " != " : " == ");
 | |
|   const StringRef Str = Reg->getValueAsString("Namespace");
 | |
|   if (!Str.empty())
 | |
|     OS << Str << "::";
 | |
|   OS << Reg->getName();
 | |
| }
 | |
| 
 | |
| 
 | |
| void PredicateExpander::expandCheckRegOperandSimple(raw_ostream &OS,
 | |
|                                                     int OpIndex,
 | |
|                                                     StringRef FunctionMapper) {
 | |
|   if (shouldNegate())
 | |
|     OS << "!";
 | |
|   if (!FunctionMapper.empty())
 | |
|     OS << FunctionMapper << "(";
 | |
|   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
 | |
|      << ").getReg()";
 | |
|   if (!FunctionMapper.empty())
 | |
|     OS << ")";
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandCheckInvalidRegOperand(raw_ostream &OS,
 | |
|                                                      int OpIndex) {
 | |
|   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
 | |
|      << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0";
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandCheckSameRegOperand(raw_ostream &OS, int First,
 | |
|                                                   int Second) {
 | |
|   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First
 | |
|      << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI"
 | |
|      << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()";
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandCheckNumOperands(raw_ostream &OS, int NumOps) {
 | |
|   OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() "
 | |
|      << (shouldNegate() ? "!= " : "== ") << NumOps;
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandCheckOpcode(raw_ostream &OS, const Record *Inst) {
 | |
|   OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() "
 | |
|      << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace")
 | |
|      << "::" << Inst->getName();
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandCheckOpcode(raw_ostream &OS,
 | |
|                                           const RecVec &Opcodes) {
 | |
|   assert(!Opcodes.empty() && "Expected at least one opcode to check!");
 | |
|   bool First = true;
 | |
| 
 | |
|   if (Opcodes.size() == 1) {
 | |
|     OS << "( ";
 | |
|     expandCheckOpcode(OS, Opcodes[0]);
 | |
|     OS << " )";
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   OS << '(';
 | |
|   increaseIndentLevel();
 | |
|   for (const Record *Rec : Opcodes) {
 | |
|     OS << '\n';
 | |
|     OS.indent(getIndentLevel() * 2);
 | |
|     if (!First)
 | |
|       OS << (shouldNegate() ? "&& " : "|| ");
 | |
| 
 | |
|     expandCheckOpcode(OS, Rec);
 | |
|     First = false;
 | |
|   }
 | |
| 
 | |
|   OS << '\n';
 | |
|   decreaseIndentLevel();
 | |
|   OS.indent(getIndentLevel() * 2);
 | |
|   OS << ')';
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandCheckPseudo(raw_ostream &OS,
 | |
|                                           const RecVec &Opcodes) {
 | |
|   if (shouldExpandForMC())
 | |
|     expandFalse(OS);
 | |
|   else
 | |
|     expandCheckOpcode(OS, Opcodes);
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandPredicateSequence(raw_ostream &OS,
 | |
|                                                 const RecVec &Sequence,
 | |
|                                                 bool IsCheckAll) {
 | |
|   assert(!Sequence.empty() && "Found an invalid empty predicate set!");
 | |
|   if (Sequence.size() == 1)
 | |
|     return expandPredicate(OS, Sequence[0]);
 | |
| 
 | |
|   // Okay, there is more than one predicate in the set.
 | |
|   bool First = true;
 | |
|   OS << (shouldNegate() ? "!(" : "(");
 | |
|   increaseIndentLevel();
 | |
| 
 | |
|   bool OldValue = shouldNegate();
 | |
|   setNegatePredicate(false);
 | |
|   for (const Record *Rec : Sequence) {
 | |
|     OS << '\n';
 | |
|     OS.indent(getIndentLevel() * 2);
 | |
|     if (!First)
 | |
|       OS << (IsCheckAll ? "&& " : "|| ");
 | |
|     expandPredicate(OS, Rec);
 | |
|     First = false;
 | |
|   }
 | |
|   OS << '\n';
 | |
|   decreaseIndentLevel();
 | |
|   OS.indent(getIndentLevel() * 2);
 | |
|   OS << ')';
 | |
|   setNegatePredicate(OldValue);
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS,
 | |
|                                               StringRef MethodName) {
 | |
|   OS << (shouldNegate() ? "!" : "");
 | |
|   OS << TargetName << (shouldExpandForMC() ? "_MC::" : "InstrInfo::");
 | |
|   OS << MethodName << (isByRef() ? "(MI)" : "(*MI)");
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) {
 | |
|   OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
 | |
|      << "getOperand(" << OpIndex << ").isReg() ";
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) {
 | |
|   OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
 | |
|      << "getOperand(" << OpIndex << ").isImm() ";
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS,
 | |
|                                                      StringRef MCInstFn,
 | |
|                                                      StringRef MachineInstrFn) {
 | |
|   OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn)
 | |
|      << (isByRef() ? "(MI)" : "(*MI)");
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandCheckNonPortable(raw_ostream &OS,
 | |
|                                                StringRef Code) {
 | |
|   if (shouldExpandForMC())
 | |
|     return expandFalse(OS);
 | |
| 
 | |
|   OS << '(' << Code << ')';
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandReturnStatement(raw_ostream &OS,
 | |
|                                               const Record *Rec) {
 | |
|   std::string Buffer;
 | |
|   raw_string_ostream SS(Buffer);
 | |
| 
 | |
|   SS << "return ";
 | |
|   expandPredicate(SS, Rec);
 | |
|   SS << ";";
 | |
|   SS.flush();
 | |
|   OS << Buffer;
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS,
 | |
|                                                const Record *Rec) {
 | |
|   const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes");
 | |
|   for (const Record *Opcode : Opcodes) {
 | |
|     OS.indent(getIndentLevel() * 2);
 | |
|     OS << "case " << Opcode->getValueAsString("Namespace")
 | |
|        << "::" << Opcode->getName() << ":\n";
 | |
|   }
 | |
| 
 | |
|   increaseIndentLevel();
 | |
|   OS.indent(getIndentLevel() * 2);
 | |
|   expandStatement(OS, Rec->getValueAsDef("CaseStmt"));
 | |
|   decreaseIndentLevel();
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS,
 | |
|                                                     const RecVec &Cases,
 | |
|                                                     const Record *Default) {
 | |
|   std::string Buffer;
 | |
|   raw_string_ostream SS(Buffer);
 | |
| 
 | |
|   SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
 | |
|   for (const Record *Rec : Cases) {
 | |
|     expandOpcodeSwitchCase(SS, Rec);
 | |
|     SS << '\n';
 | |
|   }
 | |
| 
 | |
|   // Expand the default case.
 | |
|   SS.indent(getIndentLevel() * 2);
 | |
|   SS << "default:\n";
 | |
| 
 | |
|   increaseIndentLevel();
 | |
|   SS.indent(getIndentLevel() * 2);
 | |
|   expandStatement(SS, Default);
 | |
|   decreaseIndentLevel();
 | |
|   SS << '\n';
 | |
| 
 | |
|   SS.indent(getIndentLevel() * 2);
 | |
|   SS << "} // end of switch-stmt";
 | |
|   SS.flush();
 | |
|   OS << Buffer;
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) {
 | |
|   // Assume that padding has been added by the caller.
 | |
|   if (Rec->isSubClassOf("MCOpcodeSwitchStatement")) {
 | |
|     expandOpcodeSwitchStatement(OS, Rec->getValueAsListOfDefs("Cases"),
 | |
|                                 Rec->getValueAsDef("DefaultCase"));
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if (Rec->isSubClassOf("MCReturnStatement")) {
 | |
|     expandReturnStatement(OS, Rec->getValueAsDef("Pred"));
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   llvm_unreachable("No known rules to expand this MCStatement");
 | |
| }
 | |
| 
 | |
| void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) {
 | |
|   // Assume that padding has been added by the caller.
 | |
|   if (Rec->isSubClassOf("MCTrue")) {
 | |
|     if (shouldNegate())
 | |
|       return expandFalse(OS);
 | |
|     return expandTrue(OS);
 | |
|   }
 | |
| 
 | |
|   if (Rec->isSubClassOf("MCFalse")) {
 | |
|     if (shouldNegate())
 | |
|       return expandTrue(OS);
 | |
|     return expandFalse(OS);
 | |
|   }
 | |
| 
 | |
|   if (Rec->isSubClassOf("CheckNot")) {
 | |
|     flipNegatePredicate();
 | |
|     expandPredicate(OS, Rec->getValueAsDef("Pred"));
 | |
|     flipNegatePredicate();
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if (Rec->isSubClassOf("CheckIsRegOperand"))
 | |
|     return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex"));
 | |
| 
 | |
|   if (Rec->isSubClassOf("CheckIsImmOperand"))
 | |
|     return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex"));
 | |
| 
 | |
|   if (Rec->isSubClassOf("CheckRegOperand"))
 | |
|     return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"),
 | |
|                                  Rec->getValueAsDef("Reg"),
 | |
|                                  Rec->getValueAsString("FunctionMapper"));
 | |
| 
 | |
|   if (Rec->isSubClassOf("CheckRegOperandSimple"))
 | |
|     return expandCheckRegOperandSimple(OS, Rec->getValueAsInt("OpIndex"),
 | |
|                                        Rec->getValueAsString("FunctionMapper"));
 | |
| 
 | |
|   if (Rec->isSubClassOf("CheckInvalidRegOperand"))
 | |
|     return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex"));
 | |
| 
 | |
|   if (Rec->isSubClassOf("CheckImmOperand"))
 | |
|     return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
 | |
|                                  Rec->getValueAsInt("ImmVal"),
 | |
|                                  Rec->getValueAsString("FunctionMapper"));
 | |
| 
 | |
|   if (Rec->isSubClassOf("CheckImmOperand_s"))
 | |
|     return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
 | |
|                                  Rec->getValueAsString("ImmVal"),
 | |
|                                  Rec->getValueAsString("FunctionMapper"));
 | |
| 
 | |
|   if (Rec->isSubClassOf("CheckImmOperandSimple"))
 | |
|     return expandCheckImmOperandSimple(OS, Rec->getValueAsInt("OpIndex"),
 | |
|                                        Rec->getValueAsString("FunctionMapper"));
 | |
| 
 | |
|   if (Rec->isSubClassOf("CheckSameRegOperand"))
 | |
|     return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"),
 | |
|                                      Rec->getValueAsInt("SecondIndex"));
 | |
| 
 | |
|   if (Rec->isSubClassOf("CheckNumOperands"))
 | |
|     return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps"));
 | |
| 
 | |
|   if (Rec->isSubClassOf("CheckPseudo"))
 | |
|     return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
 | |
| 
 | |
|   if (Rec->isSubClassOf("CheckOpcode"))
 | |
|     return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
 | |
| 
 | |
|   if (Rec->isSubClassOf("CheckAll"))
 | |
|     return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
 | |
|                                    /* AllOf */ true);
 | |
| 
 | |
|   if (Rec->isSubClassOf("CheckAny"))
 | |
|     return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
 | |
|                                    /* AllOf */ false);
 | |
| 
 | |
|   if (Rec->isSubClassOf("CheckFunctionPredicate"))
 | |
|     return expandCheckFunctionPredicate(
 | |
|         OS, Rec->getValueAsString("MCInstFnName"),
 | |
|         Rec->getValueAsString("MachineInstrFnName"));
 | |
| 
 | |
|   if (Rec->isSubClassOf("CheckNonPortable"))
 | |
|     return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock"));
 | |
| 
 | |
|   if (Rec->isSubClassOf("TIIPredicate"))
 | |
|     return expandTIIFunctionCall(OS, Rec->getValueAsString("FunctionName"));
 | |
| 
 | |
|   llvm_unreachable("No known rules to expand this MCInstPredicate");
 | |
| }
 | |
| 
 | |
| void STIPredicateExpander::expandHeader(raw_ostream &OS,
 | |
|                                         const STIPredicateFunction &Fn) {
 | |
|   const Record *Rec = Fn.getDeclaration();
 | |
|   StringRef FunctionName = Rec->getValueAsString("Name");
 | |
| 
 | |
|   OS.indent(getIndentLevel() * 2);
 | |
|   OS << "bool ";
 | |
|   if (shouldExpandDefinition())
 | |
|     OS << getClassPrefix() << "::";
 | |
|   OS << FunctionName << "(";
 | |
|   if (shouldExpandForMC())
 | |
|     OS << "const MCInst " << (isByRef() ? "&" : "*") << "MI";
 | |
|   else
 | |
|     OS << "const MachineInstr " << (isByRef() ? "&" : "*") << "MI";
 | |
|   if (Rec->getValueAsBit("UpdatesOpcodeMask"))
 | |
|     OS << ", APInt &Mask";
 | |
|   OS << (shouldExpandForMC() ? ", unsigned ProcessorID) const " : ") const ");
 | |
|   if (shouldExpandDefinition()) {
 | |
|     OS << "{\n";
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if (Rec->getValueAsBit("OverridesBaseClassMember"))
 | |
|     OS << "override";
 | |
|   OS << ";\n";
 | |
| }
 | |
| 
 | |
| void STIPredicateExpander::expandPrologue(raw_ostream &OS,
 | |
|                                           const STIPredicateFunction &Fn) {
 | |
|   RecVec Delegates = Fn.getDeclaration()->getValueAsListOfDefs("Delegates");
 | |
|   bool UpdatesOpcodeMask =
 | |
|       Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
 | |
| 
 | |
|   increaseIndentLevel();
 | |
|   unsigned IndentLevel = getIndentLevel();
 | |
|   for (const Record *Delegate : Delegates) {
 | |
|     OS.indent(IndentLevel * 2);
 | |
|     OS << "if (" << Delegate->getValueAsString("Name") << "(MI";
 | |
|     if (UpdatesOpcodeMask)
 | |
|       OS << ", Mask";
 | |
|     if (shouldExpandForMC())
 | |
|       OS << ", ProcessorID";
 | |
|     OS << "))\n";
 | |
|     OS.indent((1 + IndentLevel) * 2);
 | |
|     OS << "return true;\n\n";
 | |
|   }
 | |
| 
 | |
|   if (shouldExpandForMC())
 | |
|     return;
 | |
| 
 | |
|   OS.indent(IndentLevel * 2);
 | |
|   OS << "unsigned ProcessorID = getSchedModel().getProcessorID();\n";
 | |
| }
 | |
| 
 | |
| void STIPredicateExpander::expandOpcodeGroup(raw_ostream &OS, const OpcodeGroup &Group,
 | |
|                                              bool ShouldUpdateOpcodeMask) {
 | |
|   const OpcodeInfo &OI = Group.getOpcodeInfo();
 | |
|   for (const PredicateInfo &PI : OI.getPredicates()) {
 | |
|     const APInt &ProcModelMask = PI.ProcModelMask;
 | |
|     bool FirstProcID = true;
 | |
|     for (unsigned I = 0, E = ProcModelMask.getActiveBits(); I < E; ++I) {
 | |
|       if (!ProcModelMask[I])
 | |
|         continue;
 | |
| 
 | |
|       if (FirstProcID) {
 | |
|         OS.indent(getIndentLevel() * 2);
 | |
|         OS << "if (ProcessorID == " << I;
 | |
|       } else {
 | |
|         OS << " || ProcessorID == " << I;
 | |
|       }
 | |
|       FirstProcID = false;
 | |
|     }
 | |
| 
 | |
|     OS << ") {\n";
 | |
| 
 | |
|     increaseIndentLevel();
 | |
|     OS.indent(getIndentLevel() * 2);
 | |
|     if (ShouldUpdateOpcodeMask) {
 | |
|       if (PI.OperandMask.isNullValue())
 | |
|         OS << "Mask.clearAllBits();\n";
 | |
|       else
 | |
|         OS << "Mask = " << PI.OperandMask << ";\n";
 | |
|       OS.indent(getIndentLevel() * 2);
 | |
|     }
 | |
|     OS << "return ";
 | |
|     expandPredicate(OS, PI.Predicate);
 | |
|     OS << ";\n";
 | |
|     decreaseIndentLevel();
 | |
|     OS.indent(getIndentLevel() * 2);
 | |
|     OS << "}\n";
 | |
|   }
 | |
| }
 | |
| 
 | |
| void STIPredicateExpander::expandBody(raw_ostream &OS,
 | |
|                                       const STIPredicateFunction &Fn) {
 | |
|   bool UpdatesOpcodeMask =
 | |
|       Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask");
 | |
| 
 | |
|   unsigned IndentLevel = getIndentLevel();
 | |
|   OS.indent(IndentLevel * 2);
 | |
|   OS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n";
 | |
|   OS.indent(IndentLevel * 2);
 | |
|   OS << "default:\n";
 | |
|   OS.indent(IndentLevel * 2);
 | |
|   OS << "  break;";
 | |
| 
 | |
|   for (const OpcodeGroup &Group : Fn.getGroups()) {
 | |
|     for (const Record *Opcode : Group.getOpcodes()) {
 | |
|       OS << '\n';
 | |
|       OS.indent(IndentLevel * 2);
 | |
|       OS << "case " << getTargetName() << "::" << Opcode->getName() << ":";
 | |
|     }
 | |
| 
 | |
|     OS << '\n';
 | |
|     increaseIndentLevel();
 | |
|     expandOpcodeGroup(OS, Group, UpdatesOpcodeMask);
 | |
| 
 | |
|     OS.indent(getIndentLevel() * 2);
 | |
|     OS << "break;\n";
 | |
|     decreaseIndentLevel();
 | |
|   }
 | |
| 
 | |
|   OS.indent(IndentLevel * 2);
 | |
|   OS << "}\n";
 | |
| }
 | |
| 
 | |
| void STIPredicateExpander::expandEpilogue(raw_ostream &OS,
 | |
|                                           const STIPredicateFunction &Fn) {
 | |
|   OS << '\n';
 | |
|   OS.indent(getIndentLevel() * 2);
 | |
|   OS << "return ";
 | |
|   expandPredicate(OS, Fn.getDefaultReturnPredicate());
 | |
|   OS << ";\n";
 | |
| 
 | |
|   decreaseIndentLevel();
 | |
|   OS.indent(getIndentLevel() * 2);
 | |
|   StringRef FunctionName = Fn.getDeclaration()->getValueAsString("Name");
 | |
|   OS << "} // " << ClassPrefix << "::" << FunctionName << "\n\n";
 | |
| }
 | |
| 
 | |
| void STIPredicateExpander::expandSTIPredicate(raw_ostream &OS,
 | |
|                                               const STIPredicateFunction &Fn) {
 | |
|   const Record *Rec = Fn.getDeclaration();
 | |
|   if (shouldExpandForMC() && !Rec->getValueAsBit("ExpandForMC"))
 | |
|     return;
 | |
| 
 | |
|   expandHeader(OS, Fn);
 | |
|   if (shouldExpandDefinition()) {
 | |
|     expandPrologue(OS, Fn);
 | |
|     expandBody(OS, Fn);
 | |
|     expandEpilogue(OS, Fn);
 | |
|   }
 | |
| }
 | |
| 
 | |
| } // namespace llvm
 |