X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FXCore%2FXCoreAsmPrinter.cpp;h=0d146ba4d98d8027bf4e8b37b93aab9bdecb5a72;hb=0f1bcedf5a871c360f2ca1354464d81cb81bdca7;hp=5874294886e8acec7cf7a6e40ba9e412ae72ad48;hpb=c23197a26f34f559ea9797de51e187087c039c42;p=oota-llvm.git diff --git a/lib/Target/XCore/XCoreAsmPrinter.cpp b/lib/Target/XCore/XCoreAsmPrinter.cpp index 5874294886e..0d146ba4d98 100644 --- a/lib/Target/XCore/XCoreAsmPrinter.cpp +++ b/lib/Target/XCore/XCoreAsmPrinter.cpp @@ -14,39 +14,38 @@ #define DEBUG_TYPE "asm-printer" #include "XCore.h" +#include "InstPrinter/XCoreInstPrinter.h" #include "XCoreInstrInfo.h" +#include "XCoreMCInstLower.h" #include "XCoreSubtarget.h" #include "XCoreTargetMachine.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/DwarfWriter.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Support/Mangler.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/StringExtras.h" +#include "llvm/CodeGen/MachineJumpTableInfo.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/DebugInfo.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Module.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/MathExtras.h" +#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Target/Mangler.h" +#include "llvm/Target/TargetLoweringObjectFile.h" #include #include using namespace llvm; -STATISTIC(EmittedInsts, "Number of machine instrs printed"); - -static cl::opt FileDirective("xcore-file-directive", cl::Optional, - cl::desc("Output a file directive into the assembly file"), - cl::Hidden, - cl::value_desc("filename"), - cl::init("")); - static cl::opt MaxThreads("xcore-max-threads", cl::Optional, cl::desc("Maximum number of threads (for emulation thread-local storage)"), cl::Hidden, @@ -54,332 +53,196 @@ static cl::opt MaxThreads("xcore-max-threads", cl::Optional, cl::init(8)); namespace { - class VISIBILITY_HIDDEN XCoreAsmPrinter : public AsmPrinter { - DwarfWriter *DW; + class XCoreAsmPrinter : public AsmPrinter { const XCoreSubtarget &Subtarget; + XCoreMCInstLower MCInstLowering; + void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); public: - explicit XCoreAsmPrinter(raw_ostream &O, XCoreTargetMachine &TM, - const TargetAsmInfo *T, bool V) - : AsmPrinter(O, TM, T, V), DW(0), - Subtarget(*TM.getSubtargetImpl()) {} + explicit XCoreAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) + : AsmPrinter(TM, Streamer), Subtarget(TM.getSubtarget()), + MCInstLowering(*this) {} virtual const char *getPassName() const { return "XCore Assembly Printer"; } - void printMemOperand(const MachineInstr *MI, int opNum); - void printOperand(const MachineInstr *MI, int opNum); + void printInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O, + const std::string &directive = ".jmptable"); + void printInlineJT32(const MachineInstr *MI, int opNum, raw_ostream &O) { + printInlineJT(MI, opNum, O, ".jmptable32"); + } + void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O); bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode); - - void emitFileDirective(const std::string &filename); - void emitGlobalDirective(const std::string &name); - void emitExternDirective(const std::string &name); - - void emitArrayBound(const std::string &name, const GlobalVariable *GV); - void emitGlobal(const GlobalVariable *GV); + unsigned AsmVariant, const char *ExtraCode, + raw_ostream &O); - void emitFunctionStart(MachineFunction &MF); - void emitFunctionEnd(MachineFunction &MF); + void emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV); + virtual void EmitGlobalVariable(const GlobalVariable *GV); - bool printInstruction(const MachineInstr *MI); // autogenerated. - void printMachineInstruction(const MachineInstr *MI); - bool runOnMachineFunction(MachineFunction &F); - bool doInitialization(Module &M); - bool doFinalization(Module &M); - - void getAnalysisUsage(AnalysisUsage &AU) const { - AsmPrinter::getAnalysisUsage(AU); - AU.setPreservesAll(); - AU.addRequired(); - AU.addRequired(); - } + void EmitFunctionEntryLabel(); + void EmitInstruction(const MachineInstr *MI); + void EmitFunctionBodyStart(); + void EmitFunctionBodyEnd(); + virtual MachineLocation getDebugValueLocation(const MachineInstr *MI) const; }; } // end of anonymous namespace -#include "XCoreGenAsmWriter.inc" - -/// createXCoreCodePrinterPass - Returns a pass that prints the XCore -/// assembly code for a MachineFunction to the given output stream, -/// using the given target machine description. This should work -/// regardless of whether the function is in SSA form. -/// -FunctionPass *llvm::createXCoreCodePrinterPass(raw_ostream &o, - XCoreTargetMachine &tm, - bool verbose) { - return new XCoreAsmPrinter(o, tm, tm.getTargetAsmInfo(), verbose); -} - -// PrintEscapedString - Print each character of the specified string, escaping -// it if it is not printable or if it is an escape char. -static void PrintEscapedString(const std::string &Str, raw_ostream &Out) { - for (unsigned i = 0, e = Str.size(); i != e; ++i) { - unsigned char C = Str[i]; - if (isprint(C) && C != '"' && C != '\\') { - Out << C; - } else { - Out << '\\' - << (char) ((C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A')) - << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A')); - } - } -} - -void XCoreAsmPrinter:: -emitFileDirective(const std::string &name) -{ - O << "\t.file\t\""; - PrintEscapedString(name, O); - O << "\"\n"; -} - -void XCoreAsmPrinter:: -emitGlobalDirective(const std::string &name) -{ - O << TAI->getGlobalDirective() << name; - O << "\n"; -} - -void XCoreAsmPrinter:: -emitExternDirective(const std::string &name) -{ - O << "\t.extern\t" << name; - O << '\n'; -} - -void XCoreAsmPrinter:: -emitArrayBound(const std::string &name, const GlobalVariable *GV) -{ +void XCoreAsmPrinter::emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV) { assert(((GV->hasExternalLinkage() || GV->hasWeakLinkage()) || GV->hasLinkOnceLinkage()) && "Unexpected linkage"); - if (const ArrayType *ATy = dyn_cast( - cast(GV->getType())->getElementType())) - { - O << TAI->getGlobalDirective() << name << ".globound" << "\n"; - O << TAI->getSetDirective() << name << ".globound" << "," - << ATy->getNumElements() << "\n"; + if (ArrayType *ATy = dyn_cast( + cast(GV->getType())->getElementType())) { + OutStreamer.EmitSymbolAttribute(Sym, MCSA_Global); + // FIXME: MCStreamerize. + OutStreamer.EmitRawText(StringRef(".globound")); + OutStreamer.EmitRawText("\t.set\t" + Twine(Sym->getName())); + OutStreamer.EmitRawText(".globound," + Twine(ATy->getNumElements())); if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) { // TODO Use COMDAT groups for LinkOnceLinkage - O << TAI->getWeakDefDirective() << name << ".globound" << "\n"; + OutStreamer.EmitRawText(MAI->getWeakDefDirective() +Twine(Sym->getName())+ + ".globound"); } } } -void XCoreAsmPrinter:: -emitGlobal(const GlobalVariable *GV) -{ - const TargetData *TD = TM.getTargetData(); - - if (GV->hasInitializer()) { - // Check to see if this is a special global used by LLVM, if so, emit it. - if (EmitSpecialLLVMGlobal(GV)) - return; - - SwitchToSection(TAI->SectionForGlobal(GV)); - - std::string name = Mang->getValueName(GV); - Constant *C = GV->getInitializer(); - unsigned Align = (unsigned)TD->getPreferredTypeAlignmentShift(C->getType()); - - // Mark the start of the global - O << "\t.cc_top " << name << ".data," << name << "\n"; - - switch (GV->getLinkage()) { - case GlobalValue::AppendingLinkage: - llvm_report_error("AppendingLinkage is not supported by this target!"); - case GlobalValue::LinkOnceAnyLinkage: - case GlobalValue::LinkOnceODRLinkage: - case GlobalValue::WeakAnyLinkage: - case GlobalValue::WeakODRLinkage: - case GlobalValue::ExternalLinkage: - emitArrayBound(name, GV); - emitGlobalDirective(name); - // TODO Use COMDAT groups for LinkOnceLinkage - if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) { - O << TAI->getWeakDefDirective() << name << "\n"; - } - // FALL THROUGH - case GlobalValue::InternalLinkage: - case GlobalValue::PrivateLinkage: - break; - case GlobalValue::GhostLinkage: - llvm_unreachable("Should not have any unmaterialized functions!"); - case GlobalValue::DLLImportLinkage: - llvm_unreachable("DLLImport linkage is not supported by this target!"); - case GlobalValue::DLLExportLinkage: - llvm_unreachable("DLLExport linkage is not supported by this target!"); - default: - llvm_unreachable("Unknown linkage type!"); - } - - EmitAlignment(Align, GV, 2); - - unsigned Size = TD->getTypeAllocSize(C->getType()); - if (GV->isThreadLocal()) { - Size *= MaxThreads; - } - if (TAI->hasDotTypeDotSizeDirective()) { - O << "\t.type " << name << ",@object\n"; - O << "\t.size " << name << "," << Size << "\n"; - } - O << name << ":\n"; - - EmitGlobalConstant(C); - if (GV->isThreadLocal()) { - for (unsigned i = 1; i < MaxThreads; ++i) { - EmitGlobalConstant(C); - } - } - if (Size < 4) { - // The ABI requires that unsigned scalar types smaller than 32 bits - // are are padded to 32 bits. - EmitZeros(4 - Size); - } - - // Mark the end of the global - O << "\t.cc_bottom " << name << ".data\n"; - } -} +void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { + // Check to see if this is a special global used by LLVM, if so, emit it. + if (!GV->hasInitializer() || + EmitSpecialLLVMGlobal(GV)) + return; -/// Emit the directives on the start of functions -void XCoreAsmPrinter:: -emitFunctionStart(MachineFunction &MF) -{ - // Print out the label for the function. - const Function *F = MF.getFunction(); + const DataLayout *TD = TM.getDataLayout(); + OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GV, Mang,TM)); - SwitchToSection(TAI->SectionForGlobal(F)); - // Mark the start of the function - O << "\t.cc_top " << CurrentFnName << ".function," << CurrentFnName << "\n"; + MCSymbol *GVSym = Mang->getSymbol(GV); + const Constant *C = GV->getInitializer(); + unsigned Align = (unsigned)TD->getPreferredTypeAlignmentShift(C->getType()); + + // Mark the start of the global + OutStreamer.EmitRawText("\t.cc_top " + Twine(GVSym->getName()) + ".data," + + GVSym->getName()); + + switch (GV->getLinkage()) { + case GlobalValue::AppendingLinkage: + report_fatal_error("AppendingLinkage is not supported by this target!"); + case GlobalValue::LinkOnceAnyLinkage: + case GlobalValue::LinkOnceODRLinkage: + case GlobalValue::WeakAnyLinkage: + case GlobalValue::WeakODRLinkage: + case GlobalValue::ExternalLinkage: + emitArrayBound(GVSym, GV); + OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); - switch (F->getLinkage()) { - default: llvm_unreachable("Unknown linkage type!"); - case Function::InternalLinkage: // Symbols default to internal. - case Function::PrivateLinkage: - break; - case Function::ExternalLinkage: - emitGlobalDirective(CurrentFnName); - break; - case Function::LinkOnceAnyLinkage: - case Function::LinkOnceODRLinkage: - case Function::WeakAnyLinkage: - case Function::WeakODRLinkage: // TODO Use COMDAT groups for LinkOnceLinkage - O << TAI->getGlobalDirective() << CurrentFnName << "\n"; - O << TAI->getWeakDefDirective() << CurrentFnName << "\n"; + if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) + OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak); + // FALL THROUGH + case GlobalValue::InternalLinkage: + case GlobalValue::PrivateLinkage: break; + case GlobalValue::DLLImportLinkage: + llvm_unreachable("DLLImport linkage is not supported by this target!"); + case GlobalValue::DLLExportLinkage: + llvm_unreachable("DLLExport linkage is not supported by this target!"); + default: + llvm_unreachable("Unknown linkage type!"); } - // (1 << 1) byte aligned - EmitAlignment(MF.getAlignment(), F, 1); - if (TAI->hasDotTypeDotSizeDirective()) { - O << "\t.type " << CurrentFnName << ",@function\n"; + + EmitAlignment(Align > 2 ? Align : 2, GV); + + unsigned Size = TD->getTypeAllocSize(C->getType()); + if (GV->isThreadLocal()) { + Size *= MaxThreads; } - O << CurrentFnName << ":\n"; + if (MAI->hasDotTypeDotSizeDirective()) { + OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject); + OutStreamer.EmitRawText("\t.size " + Twine(GVSym->getName()) + "," + + Twine(Size)); + } + OutStreamer.EmitLabel(GVSym); + + EmitGlobalConstant(C); + if (GV->isThreadLocal()) { + for (unsigned i = 1; i < MaxThreads; ++i) + EmitGlobalConstant(C); + } + // The ABI requires that unsigned scalar types smaller than 32 bits + // are padded to 32 bits. + if (Size < 4) + OutStreamer.EmitZeros(4 - Size); + + // Mark the end of the global + OutStreamer.EmitRawText("\t.cc_bottom " + Twine(GVSym->getName()) + ".data"); } -/// Emit the directives on the end of functions -void XCoreAsmPrinter:: -emitFunctionEnd(MachineFunction &MF) -{ - // Mark the end of the function - O << "\t.cc_bottom " << CurrentFnName << ".function\n"; +void XCoreAsmPrinter::EmitFunctionBodyStart() { + MCInstLowering.Initialize(Mang, &MF->getContext()); } -/// runOnMachineFunction - This uses the printMachineInstruction() -/// method to print assembly for each instruction. -/// -bool XCoreAsmPrinter::runOnMachineFunction(MachineFunction &MF) -{ - this->MF = &MF; - - SetupMachineFunction(MF); - - // Print out constants referenced by the function - EmitConstantPool(MF.getConstantPool()); - - // Print out jump tables referenced by the function - EmitJumpTableInfo(MF.getJumpTableInfo(), MF); - - // Emit the function start directives - emitFunctionStart(MF); - - // Emit pre-function debug information. - DW->BeginFunction(&MF); - - // Print out code for the function. - for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); - I != E; ++I) { - - // Print a label for the basic block. - if (I != MF.begin()) { - printBasicBlockLabel(I, true , true); - O << '\n'; - } - - for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); - II != E; ++II) { - // Print the assembly for the instruction. - O << "\t"; - printMachineInstruction(II); - } - - // Each Basic Block is separated by a newline - O << '\n'; - } - +/// EmitFunctionBodyEnd - Targets can override this to emit stuff after +/// the last basic block in the function. +void XCoreAsmPrinter::EmitFunctionBodyEnd() { // Emit function end directives - emitFunctionEnd(MF); - - // Emit post-function debug information. - DW->EndFunction(&MF); + OutStreamer.EmitRawText("\t.cc_bottom " + Twine(CurrentFnSym->getName()) + + ".function"); +} - // We didn't modify anything. - return false; +void XCoreAsmPrinter::EmitFunctionEntryLabel() { + // Mark the start of the function + OutStreamer.EmitRawText("\t.cc_top " + Twine(CurrentFnSym->getName()) + + ".function," + CurrentFnSym->getName()); + OutStreamer.EmitLabel(CurrentFnSym); } -void XCoreAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum) -{ - printOperand(MI, opNum); - - if (MI->getOperand(opNum+1).isImm() - && MI->getOperand(opNum+1).getImm() == 0) - return; - - O << "+"; - printOperand(MI, opNum+1); +void XCoreAsmPrinter:: +printInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O, + const std::string &directive) { + unsigned JTI = MI->getOperand(opNum).getIndex(); + const MachineFunction *MF = MI->getParent()->getParent(); + const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); + const std::vector &JT = MJTI->getJumpTables(); + const std::vector &JTBBs = JT[JTI].MBBs; + O << "\t" << directive << " "; + for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { + MachineBasicBlock *MBB = JTBBs[i]; + if (i > 0) + O << ","; + O << *MBB->getSymbol(); + } } -void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum) { +void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum, + raw_ostream &O) { const MachineOperand &MO = MI->getOperand(opNum); switch (MO.getType()) { case MachineOperand::MO_Register: - if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) - O << TM.getRegisterInfo()->get(MO.getReg()).AsmName; - else - llvm_unreachable("not implemented"); + O << XCoreInstPrinter::getRegisterName(MO.getReg()); break; case MachineOperand::MO_Immediate: O << MO.getImm(); break; case MachineOperand::MO_MachineBasicBlock: - printBasicBlockLabel(MO.getMBB()); + O << *MO.getMBB()->getSymbol(); break; case MachineOperand::MO_GlobalAddress: - O << Mang->getValueName(MO.getGlobal()); + O << *Mang->getSymbol(MO.getGlobal()); break; case MachineOperand::MO_ExternalSymbol: O << MO.getSymbolName(); break; case MachineOperand::MO_ConstantPoolIndex: - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() + O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_' << MO.getIndex(); break; case MachineOperand::MO_JumpTableIndex: - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() + O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' << MO.getIndex(); break; + case MachineOperand::MO_BlockAddress: + O << *GetBlockAddressSymbol(MO.getBlockAddress()); + break; default: llvm_unreachable("not implemented"); } @@ -388,48 +251,92 @@ void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum) { /// PrintAsmOperand - Print out an operand for an inline asm expression. /// bool XCoreAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, - const char *ExtraCode) { - printOperand(MI, OpNo); + unsigned AsmVariant,const char *ExtraCode, + raw_ostream &O) { + // Does this asm operand have a single letter operand modifier? + if (ExtraCode && ExtraCode[0]) + if (ExtraCode[1] != 0) return true; // Unknown modifier. + + switch (ExtraCode[0]) { + default: + // See if this is a generic print operand + return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O); + } + + printOperand(MI, OpNo, O); return false; } -void XCoreAsmPrinter::printMachineInstruction(const MachineInstr *MI) { - ++EmittedInsts; +void XCoreAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, + raw_ostream &OS) { + unsigned NOps = MI->getNumOperands(); + assert(NOps == 4); + OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; + // cast away const; DIetc do not take const operands for some reason. + DIVariable V(const_cast(MI->getOperand(NOps-1).getMetadata())); + OS << V.getName(); + OS << " <- "; + // Frame address. Currently handles register +- offset only. + assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); + OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS); + OS << ']'; + OS << "+"; + printOperand(MI, NOps-2, OS); +} - // Check for mov mnemonic - unsigned src, dst, srcSR, dstSR; - if (TM.getInstrInfo()->isMoveInstr(*MI, src, dst, srcSR, dstSR)) { - O << "\tmov "; - O << TM.getRegisterInfo()->get(dst).AsmName; - O << ", "; - O << TM.getRegisterInfo()->get(src).AsmName; - O << "\n"; +MachineLocation XCoreAsmPrinter:: +getDebugValueLocation(const MachineInstr *MI) const { + // Handles frame addresses emitted in XCoreInstrInfo::emitFrameIndexDebugValue. + assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); + assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm() && + "Unexpected MachineOperand types"); + return MachineLocation(MI->getOperand(0).getReg(), + MI->getOperand(1).getImm()); +} + +void XCoreAsmPrinter::EmitInstruction(const MachineInstr *MI) { + SmallString<128> Str; + raw_svector_ostream O(Str); + + switch (MI->getOpcode()) { + case XCore::DBG_VALUE: { + if (isVerbose() && OutStreamer.hasRawTextSupport()) { + SmallString<128> TmpStr; + raw_svector_ostream OS(TmpStr); + PrintDebugValueComment(MI, OS); + OutStreamer.EmitRawText(StringRef(OS.str())); + } return; } - if (printInstruction(MI)) { + case XCore::ADD_2rus: + if (MI->getOperand(2).getImm() == 0) { + O << "\tmov " + << XCoreInstPrinter::getRegisterName(MI->getOperand(0).getReg()) << ", " + << XCoreInstPrinter::getRegisterName(MI->getOperand(1).getReg()); + OutStreamer.EmitRawText(O.str()); + return; + } + break; + case XCore::BR_JT: + case XCore::BR_JT32: + O << "\tbru " + << XCoreInstPrinter::getRegisterName(MI->getOperand(1).getReg()) << '\n'; + if (MI->getOpcode() == XCore::BR_JT) + printInlineJT(MI, 0, O); + else + printInlineJT32(MI, 0, O); + O << '\n'; + OutStreamer.EmitRawText(O.str()); return; } - llvm_unreachable("Unhandled instruction in asm writer!"); -} -bool XCoreAsmPrinter::doInitialization(Module &M) { - bool Result = AsmPrinter::doInitialization(M); - DW = getAnalysisIfAvailable(); - - if (!FileDirective.empty()) - emitFileDirective(FileDirective); + MCInst TmpInst; + MCInstLowering.Lower(MI, TmpInst); - return Result; + OutStreamer.EmitInstruction(TmpInst); } -bool XCoreAsmPrinter::doFinalization(Module &M) { - - // Print out module-level global variables. - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - emitGlobal(I); - } - - return AsmPrinter::doFinalization(M); +// Force static initialization. +extern "C" void LLVMInitializeXCoreAsmPrinter() { + RegisterAsmPrinter X(TheXCoreTarget); }