186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach//===- PseudoLoweringEmitter.cpp - PseudoLowering Generator -----*- C++ -*-===// 286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach// 386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach// The LLVM Compiler Infrastructure 486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach// 586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach// This file is distributed under the University of Illinois Open Source 686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach// License. See LICENSE.TXT for details. 786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach// 886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach//===----------------------------------------------------------------------===// 986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 1086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach#define DEBUG_TYPE "pseudo-lowering" 1186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach#include "CodeGenInstruction.h" 1286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach#include "PseudoLoweringEmitter.h" 137c788888872233748da10a8177a9a1eb176c1bc8Peter Collingbourne#include "llvm/TableGen/Error.h" 147c788888872233748da10a8177a9a1eb176c1bc8Peter Collingbourne#include "llvm/TableGen/Record.h" 1586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach#include "llvm/ADT/IndexedMap.h" 1686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach#include "llvm/ADT/StringMap.h" 1786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach#include "llvm/Support/ErrorHandling.h" 1886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach#include "llvm/Support/Debug.h" 1986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach#include <vector> 2086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbachusing namespace llvm; 2186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 2286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach// FIXME: This pass currently can only expand a pseudo to a single instruction. 2386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach// The pseudo expansion really should take a list of dags, not just 2486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach// a single dag, so we can do fancier things. 2586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 2686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbachunsigned PseudoLoweringEmitter:: 2705bce0beee87512e52428d4b80f5a8e79a949576David GreeneaddDagOperandMapping(Record *Rec, DagInit *Dag, CodeGenInstruction &Insn, 2886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach IndexedMap<OpData> &OperandMap, unsigned BaseIdx) { 2986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach unsigned OpsAdded = 0; 3086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) { 3105bce0beee87512e52428d4b80f5a8e79a949576David Greene if (DefInit *DI = dynamic_cast<DefInit*>(Dag->getArg(i))) { 3286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // Physical register reference. Explicit check for the special case 3386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // "zero_reg" definition. 3486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach if (DI->getDef()->isSubClassOf("Register") || 3586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach DI->getDef()->getName() == "zero_reg") { 3686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach OperandMap[BaseIdx + i].Kind = OpData::Reg; 3786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach OperandMap[BaseIdx + i].Data.Reg = DI->getDef(); 3886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach ++OpsAdded; 3986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach continue; 4086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach } 4186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 4286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // Normal operands should always have the same type, or we have a 4386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // problem. 4486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // FIXME: We probably shouldn't ever get a non-zero BaseIdx here. 4586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach assert(BaseIdx == 0 && "Named subargument in pseudo expansion?!"); 4686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach if (DI->getDef() != Insn.Operands[BaseIdx + i].Rec) 4786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach throw TGError(Rec->getLoc(), 4886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach "Pseudo operand type '" + DI->getDef()->getName() + 4986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach "' does not match expansion operand type '" + 5086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach Insn.Operands[BaseIdx + i].Rec->getName() + "'"); 5186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // Source operand maps to destination operand. The Data element 5286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // will be filled in later, just set the Kind for now. Do it 5386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // for each corresponding MachineInstr operand, not just the first. 5486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach for (unsigned I = 0, E = Insn.Operands[i].MINumOperands; I != E; ++I) 5586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach OperandMap[BaseIdx + i + I].Kind = OpData::Operand; 5686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach OpsAdded += Insn.Operands[i].MINumOperands; 5705bce0beee87512e52428d4b80f5a8e79a949576David Greene } else if (IntInit *II = dynamic_cast<IntInit*>(Dag->getArg(i))) { 5886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach OperandMap[BaseIdx + i].Kind = OpData::Imm; 5986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach OperandMap[BaseIdx + i].Data.Imm = II->getValue(); 6086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach ++OpsAdded; 6105bce0beee87512e52428d4b80f5a8e79a949576David Greene } else if (DagInit *SubDag = dynamic_cast<DagInit*>(Dag->getArg(i))) { 6286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // Just add the operands recursively. This is almost certainly 6386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // a constant value for a complex operand (> 1 MI operand). 6486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach unsigned NewOps = 6586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach addDagOperandMapping(Rec, SubDag, Insn, OperandMap, BaseIdx + i); 6686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach OpsAdded += NewOps; 6786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // Since we added more than one, we also need to adjust the base. 6886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach BaseIdx += NewOps - 1; 6986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach } else 70655b8de7b2ab773a977e0c524307e71354d8af29Craig Topper llvm_unreachable("Unhandled pseudo-expansion argument type!"); 7186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach } 7286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach return OpsAdded; 7386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach} 7486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 7586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbachvoid PseudoLoweringEmitter::evaluateExpansion(Record *Rec) { 7686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach DEBUG(dbgs() << "Pseudo definition: " << Rec->getName() << "\n"); 7786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 7886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // Validate that the result pattern has the corrent number and types 7986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // of arguments for the instruction it references. 8005bce0beee87512e52428d4b80f5a8e79a949576David Greene DagInit *Dag = Rec->getValueAsDag("ResultInst"); 8186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach assert(Dag && "Missing result instruction in pseudo expansion!"); 8286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach DEBUG(dbgs() << " Result: " << *Dag << "\n"); 8386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 8405bce0beee87512e52428d4b80f5a8e79a949576David Greene DefInit *OpDef = dynamic_cast<DefInit*>(Dag->getOperator()); 8586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach if (!OpDef) 8686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach throw TGError(Rec->getLoc(), Rec->getName() + 8786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach " has unexpected operator type!"); 8886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach Record *Operator = OpDef->getDef(); 8986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach if (!Operator->isSubClassOf("Instruction")) 9086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach throw TGError(Rec->getLoc(), "Pseudo result '" + Operator->getName() + 9186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach "' is not an instruction!"); 9286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 9386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach CodeGenInstruction Insn(Operator); 9486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 9586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach if (Insn.isCodeGenOnly || Insn.isPseudo) 9686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach throw TGError(Rec->getLoc(), "Pseudo result '" + Operator->getName() + 9786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach "' cannot be another pseudo instruction!"); 9886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 9986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach if (Insn.Operands.size() != Dag->getNumArgs()) 10086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach throw TGError(Rec->getLoc(), "Pseudo result '" + Operator->getName() + 10186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach "' operand count mismatch"); 10286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 103aa7b3df1788e6ffdaa9b661cfdccdc41ad181567Evan Cheng unsigned NumMIOperands = 0; 104aa7b3df1788e6ffdaa9b661cfdccdc41ad181567Evan Cheng for (unsigned i = 0, e = Insn.Operands.size(); i != e; ++i) 105aa7b3df1788e6ffdaa9b661cfdccdc41ad181567Evan Cheng NumMIOperands += Insn.Operands[i].MINumOperands; 10686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach IndexedMap<OpData> OperandMap; 107aa7b3df1788e6ffdaa9b661cfdccdc41ad181567Evan Cheng OperandMap.grow(NumMIOperands); 10886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 10986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach addDagOperandMapping(Rec, Dag, Insn, OperandMap, 0); 11086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 11186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // If there are more operands that weren't in the DAG, they have to 11286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // be operands that have default values, or we have an error. Currently, 11386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // PredicateOperand and OptionalDefOperand both have default values. 11486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 11586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 11686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // Validate that each result pattern argument has a matching (by name) 11786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // argument in the source instruction, in either the (outs) or (ins) list. 11886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // Also check that the type of the arguments match. 11986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // 12086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // Record the mapping of the source to result arguments for use by 12186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // the lowering emitter. 12286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach CodeGenInstruction SourceInsn(Rec); 12386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach StringMap<unsigned> SourceOperands; 12486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach for (unsigned i = 0, e = SourceInsn.Operands.size(); i != e; ++i) 12586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach SourceOperands[SourceInsn.Operands[i].Name] = i; 12686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 12786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach DEBUG(dbgs() << " Operand mapping:\n"); 12886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach for (unsigned i = 0, e = Insn.Operands.size(); i != e; ++i) { 12986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // We've already handled constant values. Just map instruction operands 13086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // here. 13186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach if (OperandMap[Insn.Operands[i].MIOperandNo].Kind != OpData::Operand) 13286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach continue; 13386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach StringMap<unsigned>::iterator SourceOp = 13486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach SourceOperands.find(Dag->getArgName(i)); 13586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach if (SourceOp == SourceOperands.end()) 13686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach throw TGError(Rec->getLoc(), 13786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach "Pseudo output operand '" + Dag->getArgName(i) + 13886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach "' has no matching source operand."); 13986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // Map the source operand to the destination operand index for each 14086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // MachineInstr operand. 14186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach for (unsigned I = 0, E = Insn.Operands[i].MINumOperands; I != E; ++I) 14286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach OperandMap[Insn.Operands[i].MIOperandNo + I].Data.Operand = 14386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach SourceOp->getValue(); 14486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 14586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach DEBUG(dbgs() << " " << SourceOp->getValue() << " ==> " << i << "\n"); 14686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach } 14786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 14886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach Expansions.push_back(PseudoExpansion(SourceInsn, Insn, OperandMap)); 14986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach} 15086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 15186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbachvoid PseudoLoweringEmitter::emitLoweringEmitter(raw_ostream &o) { 15286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // Emit file header. 15386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach EmitSourceFileHeader("Pseudo-instruction MC lowering Source Fragment", o); 15486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 15586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach o << "bool " << Target.getName() + "AsmPrinter" << "::\n" 15686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach << "emitPseudoExpansionLowering(MCStreamer &OutStreamer,\n" 15786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach << " const MachineInstr *MI) {\n" 15886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach << " switch (MI->getOpcode()) {\n" 15986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach << " default: return false;\n"; 16086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach for (unsigned i = 0, e = Expansions.size(); i != e; ++i) { 16186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach PseudoExpansion &Expansion = Expansions[i]; 16286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach CodeGenInstruction &Source = Expansion.Source; 16386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach CodeGenInstruction &Dest = Expansion.Dest; 16486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach o << " case " << Source.Namespace << "::" 16586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach << Source.TheDef->getName() << ": {\n" 16686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach << " MCInst TmpInst;\n" 16786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach << " MCOperand MCOp;\n" 16886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach << " TmpInst.setOpcode(" << Dest.Namespace << "::" 16986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach << Dest.TheDef->getName() << ");\n"; 17086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 17186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // Copy the operands from the source instruction. 17286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // FIXME: Instruction operands with defaults values (predicates and cc_out 17386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // in ARM, for example shouldn't need explicit values in the 17486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // expansion DAG. 17586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach unsigned MIOpNo = 0; 17686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach for (unsigned OpNo = 0, E = Dest.Operands.size(); OpNo != E; 17786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach ++OpNo) { 17886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach o << " // Operand: " << Dest.Operands[OpNo].Name << "\n"; 17986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach for (unsigned i = 0, e = Dest.Operands[OpNo].MINumOperands; 18086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach i != e; ++i) { 18186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach switch (Expansion.OperandMap[MIOpNo + i].Kind) { 18286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach case OpData::Operand: 18386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach o << " lowerOperand(MI->getOperand(" 18486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach << Source.Operands[Expansion.OperandMap[MIOpNo].Data 18586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach .Operand].MIOperandNo + i 18686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach << "), MCOp);\n" 18786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach << " TmpInst.addOperand(MCOp);\n"; 18886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach break; 18986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach case OpData::Imm: 19086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach o << " TmpInst.addOperand(MCOperand::CreateImm(" 19186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach << Expansion.OperandMap[MIOpNo + i].Data.Imm << "));\n"; 19286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach break; 19386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach case OpData::Reg: { 19486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach Record *Reg = Expansion.OperandMap[MIOpNo + i].Data.Reg; 19586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach o << " TmpInst.addOperand(MCOperand::CreateReg("; 19686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // "zero_reg" is special. 19786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach if (Reg->getName() == "zero_reg") 19886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach o << "0"; 19986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach else 20086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach o << Reg->getValueAsString("Namespace") << "::" << Reg->getName(); 20186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach o << "));\n"; 20286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach break; 20386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach } 20486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach } 20586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach } 20686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach MIOpNo += Dest.Operands[OpNo].MINumOperands; 20786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach } 20886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach if (Dest.Operands.isVariadic) { 20986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach o << " // variable_ops\n"; 21086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach o << " for (unsigned i = " << MIOpNo 21186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach << ", e = MI->getNumOperands(); i != e; ++i)\n" 21286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach << " if (lowerOperand(MI->getOperand(i), MCOp))\n" 21386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach << " TmpInst.addOperand(MCOp);\n"; 21486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach } 21586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach o << " OutStreamer.EmitInstruction(TmpInst);\n" 21686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach << " break;\n" 21786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach << " }\n"; 21886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach } 21986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach o << " }\n return true;\n}\n\n"; 22086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach} 22186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 22286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbachvoid PseudoLoweringEmitter::run(raw_ostream &o) { 22386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach Record *ExpansionClass = Records.getClass("PseudoInstExpansion"); 22486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach Record *InstructionClass = Records.getClass("PseudoInstExpansion"); 22586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach assert(ExpansionClass && "PseudoInstExpansion class definition missing!"); 22686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach assert(InstructionClass && "Instruction class definition missing!"); 22786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 22886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach std::vector<Record*> Insts; 22986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach for (std::map<std::string, Record*>::const_iterator I = 23086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach Records.getDefs().begin(), E = Records.getDefs().end(); I != E; ++I) { 23186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach if (I->second->isSubClassOf(ExpansionClass) && 23286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach I->second->isSubClassOf(InstructionClass)) 23386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach Insts.push_back(I->second); 23486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach } 23586f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 23686f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // Process the pseudo expansion definitions, validating them as we do so. 23786f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach for (unsigned i = 0, e = Insts.size(); i != e; ++i) 23886f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach evaluateExpansion(Insts[i]); 23986f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 24086f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // Generate expansion code to lower the pseudo to an MCInst of the real 24186f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach // instruction. 24286f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach emitLoweringEmitter(o); 24386f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach} 24486f9adb8becf5da6962bd89301e96bccba26f72aJim Grosbach 245