1b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//===-- XCoreAsmPrinter.cpp - XCore LLVM assembly writer ------------------===// 2b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// 3b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// The LLVM Compiler Infrastructure 4b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// 5b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// This file is distributed under the University of Illinois Open Source 6b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// License. See LICENSE.TXT for details. 7b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// 8b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//===----------------------------------------------------------------------===// 9b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// 10b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// This file contains a printer that converts from our internal representation 11b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// of machine-dependent LLVM code to the XAS-format XCore assembly language. 12b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne// 13b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne//===----------------------------------------------------------------------===// 14b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 15b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#define DEBUG_TYPE "asm-printer" 16b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "XCore.h" 1758a2cbef4aac9ee7d530dfb690c78d6fc11a2371Chandler Carruth#include "InstPrinter/XCoreInstPrinter.h" 18b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "XCoreInstrInfo.h" 199578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne#include "XCoreMCInstLower.h" 20b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "XCoreSubtarget.h" 21b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "XCoreTargetMachine.h" 22d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallString.h" 23d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/StringExtras.h" 24b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/AsmPrinter.h" 25b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/MachineConstantPool.h" 26d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineFunctionPass.h" 27b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/MachineInstr.h" 2878700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne#include "llvm/CodeGen/MachineJumpTableInfo.h" 29d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineModuleInfo.h" 30d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/DebugInfo.h" 310b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h" 320b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 330b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h" 340b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 351abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng#include "llvm/MC/MCAsmInfo.h" 369578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne#include "llvm/MC/MCInst.h" 376c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h" 38325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h" 39b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/Support/CommandLine.h" 40804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin#include "llvm/Support/ErrorHandling.h" 413e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 42b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/Support/raw_ostream.h" 43d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/Mangler.h" 44d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetLoweringObjectFile.h" 45b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include <algorithm> 46b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include <cctype> 47b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborneusing namespace llvm; 48b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 49b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic cl::opt<unsigned> MaxThreads("xcore-max-threads", cl::Optional, 50b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne cl::desc("Maximum number of threads (for emulation thread-local storage)"), 51b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne cl::Hidden, 52b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne cl::value_desc("number"), 53b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne cl::init(8)); 54b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 55b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornenamespace { 566726b6d75a8b679068a58cb954ba97cf9d1690baNick Lewycky class XCoreAsmPrinter : public AsmPrinter { 57b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne const XCoreSubtarget &Subtarget; 589578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne XCoreMCInstLower MCInstLowering; 596c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS); 6057f0db833dc30404f1f5d28b23df326e520698ecBill Wendling public: 61b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner explicit XCoreAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 629578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne : AsmPrinter(TM, Streamer), Subtarget(TM.getSubtarget<XCoreSubtarget>()), 639578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne MCInstLowering(*this) {} 64b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 65b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne virtual const char *getPassName() const { 66b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return "XCore Assembly Printer"; 67b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 68b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 6935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner void printInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O, 7078700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne const std::string &directive = ".jmptable"); 7135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner void printInlineJT32(const MachineInstr *MI, int opNum, raw_ostream &O) { 7235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printInlineJT(MI, opNum, O, ".jmptable32"); 7378700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne } 7435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O); 75b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 76c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner unsigned AsmVariant, const char *ExtraCode, 77c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O); 78f301c2299c95a1f60e879be4a3b0179ed3935d44Richard Osborne 799d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner void emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV); 8074bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner virtual void EmitGlobalVariable(const GlobalVariable *GV); 81b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 82d7d44bd5a81a4300201064cee1407fe804990320Chris Lattner void EmitFunctionEntryLabel(); 83a34103f6fa6f21025518596efc73631eb899410bChris Lattner void EmitInstruction(const MachineInstr *MI); 849578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne void EmitFunctionBodyStart(); 85a34103f6fa6f21025518596efc73631eb899410bChris Lattner void EmitFunctionBodyEnd(); 866c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne virtual MachineLocation getDebugValueLocation(const MachineInstr *MI) const; 87b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne }; 88b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} // end of anonymous namespace 89b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 909d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattnervoid XCoreAsmPrinter::emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV) { 91f943b1586f9964c88ae6431c09887e7c7917e449Richard Osborne assert(((GV->hasExternalLinkage() || 92b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne GV->hasWeakLinkage()) || 93f943b1586f9964c88ae6431c09887e7c7917e449Richard Osborne GV->hasLinkOnceLinkage()) && "Unexpected linkage"); 94db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner if (ArrayType *ATy = dyn_cast<ArrayType>( 9512164414dd3daa6974985eeb2e89bfb93cf07641Chris Lattner cast<PointerType>(GV->getType())->getElementType())) { 969d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner OutStreamer.EmitSymbolAttribute(Sym, MCSA_Global); 9773ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner // FIXME: MCStreamerize. 9873ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner OutStreamer.EmitRawText(StringRef(".globound")); 9973ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner OutStreamer.EmitRawText("\t.set\t" + Twine(Sym->getName())); 10073ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner OutStreamer.EmitRawText(".globound," + Twine(ATy->getNumElements())); 101b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) { 102b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne // TODO Use COMDAT groups for LinkOnceLinkage 10373ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner OutStreamer.EmitRawText(MAI->getWeakDefDirective() +Twine(Sym->getName())+ 10473ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner ".globound"); 105b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 106b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 107b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 108b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 10974bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattnervoid XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { 110e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner // Check to see if this is a special global used by LLVM, if so, emit it. 111e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner if (!GV->hasInitializer() || 112e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner EmitSpecialLLVMGlobal(GV)) 113e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner return; 114b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 1153574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow const DataLayout *TD = TM.getDataLayout(); 1166c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GV, Mang,TM)); 11712164414dd3daa6974985eeb2e89bfb93cf07641Chris Lattner 118e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner 119d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner MCSymbol *GVSym = Mang->getSymbol(GV); 1207d715dfe6d66be257926f626df96a0e2bd38dc1fJay Foad const Constant *C = GV->getInitializer(); 121e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner unsigned Align = (unsigned)TD->getPreferredTypeAlignmentShift(C->getType()); 122e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner 123e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner // Mark the start of the global 12473ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner OutStreamer.EmitRawText("\t.cc_top " + Twine(GVSym->getName()) + ".data," + 12573ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner GVSym->getName()); 126e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner 127e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner switch (GV->getLinkage()) { 128e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner case GlobalValue::AppendingLinkage: 12975361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("AppendingLinkage is not supported by this target!"); 130e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner case GlobalValue::LinkOnceAnyLinkage: 131e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner case GlobalValue::LinkOnceODRLinkage: 132e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner case GlobalValue::WeakAnyLinkage: 133e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner case GlobalValue::WeakODRLinkage: 134e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner case GlobalValue::ExternalLinkage: 13512164414dd3daa6974985eeb2e89bfb93cf07641Chris Lattner emitArrayBound(GVSym, GV); 1369d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); 1379d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner 138e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner // TODO Use COMDAT groups for LinkOnceLinkage 13910b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) 14073ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak); 141e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner // FALL THROUGH 142e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner case GlobalValue::InternalLinkage: 143e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner case GlobalValue::PrivateLinkage: 144e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner break; 145e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner case GlobalValue::DLLImportLinkage: 146e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner llvm_unreachable("DLLImport linkage is not supported by this target!"); 147e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner case GlobalValue::DLLExportLinkage: 148e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner llvm_unreachable("DLLExport linkage is not supported by this target!"); 149e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner default: 150e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner llvm_unreachable("Unknown linkage type!"); 151e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner } 152b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 153a7b611c10d0e5fef5870d854518e639ce3d3c6beChris Lattner EmitAlignment(Align > 2 ? Align : 2, GV); 154e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner 155e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner unsigned Size = TD->getTypeAllocSize(C->getType()); 156e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner if (GV->isThreadLocal()) { 157e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner Size *= MaxThreads; 158e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner } 15933adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner if (MAI->hasDotTypeDotSizeDirective()) { 16073ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject); 16173ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner OutStreamer.EmitRawText("\t.size " + Twine(GVSym->getName()) + "," + 16273ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner Twine(Size)); 163e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner } 16473ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner OutStreamer.EmitLabel(GVSym); 165e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner 166e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner EmitGlobalConstant(C); 167e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner if (GV->isThreadLocal()) { 1686449abfbc86310edbbe0b5ffb3fad5c14301307fChris Lattner for (unsigned i = 1; i < MaxThreads; ++i) 169e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner EmitGlobalConstant(C); 170e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner } 1716449abfbc86310edbbe0b5ffb3fad5c14301307fChris Lattner // The ABI requires that unsigned scalar types smaller than 32 bits 172f958dd2e1c12b70f6eef5a2aef4a6ac497a1b471Chris Lattner // are padded to 32 bits. 1736449abfbc86310edbbe0b5ffb3fad5c14301307fChris Lattner if (Size < 4) 1741ced208be9cab0f994c5df9000da36bc313b2507Eric Christopher OutStreamer.EmitZeros(4 - Size); 175e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner 176e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner // Mark the end of the global 17773ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner OutStreamer.EmitRawText("\t.cc_bottom " + Twine(GVSym->getName()) + ".data"); 178b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 179b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 1809578d793c9450b315721d5cb15001c2e69bff3d0Richard Osbornevoid XCoreAsmPrinter::EmitFunctionBodyStart() { 1819578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne MCInstLowering.Initialize(Mang, &MF->getContext()); 1829578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne} 1839578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne 184a34103f6fa6f21025518596efc73631eb899410bChris Lattner/// EmitFunctionBodyEnd - Targets can override this to emit stuff after 185a34103f6fa6f21025518596efc73631eb899410bChris Lattner/// the last basic block in the function. 186a34103f6fa6f21025518596efc73631eb899410bChris Lattnervoid XCoreAsmPrinter::EmitFunctionBodyEnd() { 187a34103f6fa6f21025518596efc73631eb899410bChris Lattner // Emit function end directives 1889d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner OutStreamer.EmitRawText("\t.cc_bottom " + Twine(CurrentFnSym->getName()) + 1899d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner ".function"); 190a34103f6fa6f21025518596efc73631eb899410bChris Lattner} 191a34103f6fa6f21025518596efc73631eb899410bChris Lattner 192d7d44bd5a81a4300201064cee1407fe804990320Chris Lattnervoid XCoreAsmPrinter::EmitFunctionEntryLabel() { 193d7d44bd5a81a4300201064cee1407fe804990320Chris Lattner // Mark the start of the function 194d7d44bd5a81a4300201064cee1407fe804990320Chris Lattner OutStreamer.EmitRawText("\t.cc_top " + Twine(CurrentFnSym->getName()) + 195d7d44bd5a81a4300201064cee1407fe804990320Chris Lattner ".function," + CurrentFnSym->getName()); 196d7d44bd5a81a4300201064cee1407fe804990320Chris Lattner OutStreamer.EmitLabel(CurrentFnSym); 197b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 198b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 19978700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osbornevoid XCoreAsmPrinter:: 20035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerprintInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O, 20135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner const std::string &directive) { 20278700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne unsigned JTI = MI->getOperand(opNum).getIndex(); 20378700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne const MachineFunction *MF = MI->getParent()->getParent(); 20478700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); 20578700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 20678700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs; 20778700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne O << "\t" << directive << " "; 20878700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { 20978700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne MachineBasicBlock *MBB = JTBBs[i]; 21078700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne if (i > 0) 21178700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne O << ","; 2121b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner O << *MBB->getSymbol(); 21378700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne } 21478700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne} 21578700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne 21635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum, 21735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner raw_ostream &O) { 218b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne const MachineOperand &MO = MI->getOperand(opNum); 219b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne switch (MO.getType()) { 220b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne case MachineOperand::MO_Register: 2219578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne O << XCoreInstPrinter::getRegisterName(MO.getReg()); 222b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne break; 223b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne case MachineOperand::MO_Immediate: 224b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne O << MO.getImm(); 225b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne break; 226b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne case MachineOperand::MO_MachineBasicBlock: 2271b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner O << *MO.getMBB()->getSymbol(); 228b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne break; 229b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne case MachineOperand::MO_GlobalAddress: 230d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner O << *Mang->getSymbol(MO.getGlobal()); 231b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne break; 232b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne case MachineOperand::MO_ExternalSymbol: 233b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne O << MO.getSymbolName(); 234b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne break; 235b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne case MachineOperand::MO_ConstantPoolIndex: 23633adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() 237b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne << '_' << MO.getIndex(); 238b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne break; 239b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne case MachineOperand::MO_JumpTableIndex: 24033adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() 241b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne << '_' << MO.getIndex(); 2426a9157913cb09ad49c000ebe255d950b1857c659Chris Lattner break; 243bea7df56ce7f4a5e1c65770c33fbf6dd39afd1dfRichard Osborne case MachineOperand::MO_BlockAddress: 24410b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner O << *GetBlockAddressSymbol(MO.getBlockAddress()); 245b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne break; 246b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne default: 247c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("not implemented"); 248b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne } 249b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 250b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 251b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// PrintAsmOperand - Print out an operand for an inline asm expression. 252b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// 253b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornebool XCoreAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 254c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner unsigned AsmVariant,const char *ExtraCode, 255c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 2560518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter // Does this asm operand have a single letter operand modifier? 2570518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter if (ExtraCode && ExtraCode[0]) 2580518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter if (ExtraCode[1] != 0) return true; // Unknown modifier. 2590518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter 2600518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter switch (ExtraCode[0]) { 2610518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter default: 2620518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter // See if this is a generic print operand 2630518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O); 2640518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter } 2650518fca843ff87d069ecb07fc00d306c1f587d58Jack Carter 2669578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne printOperand(MI, OpNo, O); 267b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne return false; 268b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 269b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 2706c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osbornevoid XCoreAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, 2716c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne raw_ostream &OS) { 2726c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne unsigned NOps = MI->getNumOperands(); 2736c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne assert(NOps == 4); 2746c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; 2756c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne // cast away const; DIetc do not take const operands for some reason. 2766c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata())); 2776c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne OS << V.getName(); 2786c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne OS << " <- "; 2796c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne // Frame address. Currently handles register +- offset only. 2806c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); 2816c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS); 2826c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne OS << ']'; 2836c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne OS << "+"; 2846c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne printOperand(MI, NOps-2, OS); 2856c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne} 2866c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne 2876c6f28ffe42d06655f5977bd0d01214e32de93a5Richard OsborneMachineLocation XCoreAsmPrinter:: 2886c6f28ffe42d06655f5977bd0d01214e32de93a5Richard OsbornegetDebugValueLocation(const MachineInstr *MI) const { 2896c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne // Handles frame addresses emitted in XCoreInstrInfo::emitFrameIndexDebugValue. 2906c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); 2916c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm() && 2926c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne "Unexpected MachineOperand types"); 2936c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne return MachineLocation(MI->getOperand(0).getReg(), 2946c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne MI->getOperand(1).getImm()); 2956c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne} 2966c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne 297a34103f6fa6f21025518596efc73631eb899410bChris Lattnervoid XCoreAsmPrinter::EmitInstruction(const MachineInstr *MI) { 2989d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner SmallString<128> Str; 2999d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner raw_svector_ostream O(Str); 3002aaa98da767ffd07e773a228bcae4adf65c49bc5Jakob Stoklund Olesen 3016c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne switch (MI->getOpcode()) { 3026c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne case XCore::DBG_VALUE: { 3036c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne if (isVerbose() && OutStreamer.hasRawTextSupport()) { 3046c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne SmallString<128> TmpStr; 3056c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne raw_svector_ostream OS(TmpStr); 3066c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne PrintDebugValueComment(MI, OS); 3076c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne OutStreamer.EmitRawText(StringRef(OS.str())); 3086c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne } 3096c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne return; 3106c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne } 3116c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne case XCore::ADD_2rus: 3126c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne if (MI->getOperand(2).getImm() == 0) { 3139578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne O << "\tmov " 3149578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne << XCoreInstPrinter::getRegisterName(MI->getOperand(0).getReg()) << ", " 3159578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne << XCoreInstPrinter::getRegisterName(MI->getOperand(1).getReg()); 3166c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne OutStreamer.EmitRawText(O.str()); 3176c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne return; 3186c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne } 3196c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne break; 3209578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne case XCore::BR_JT: 3219578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne case XCore::BR_JT32: 3229578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne O << "\tbru " 3239578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne << XCoreInstPrinter::getRegisterName(MI->getOperand(1).getReg()) << '\n'; 3249578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne if (MI->getOpcode() == XCore::BR_JT) 3259578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne printInlineJT(MI, 0, O); 3269578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne else 3279578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne printInlineJT32(MI, 0, O); 3289578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne O << '\n'; 3299578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne OutStreamer.EmitRawText(O.str()); 3309578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne return; 3316c6f28ffe42d06655f5977bd0d01214e32de93a5Richard Osborne } 3329578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne 3339578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne MCInst TmpInst; 3349578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne MCInstLowering.Lower(MI, TmpInst); 3359578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne 3369578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne OutStreamer.EmitInstruction(TmpInst); 337b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} 338b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne 3390c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar// Force static initialization. 3401c8c15f6d2f3f7ffbeff5daa211907dff1b13650Richard Osborneextern "C" void LLVMInitializeXCoreAsmPrinter() { 3411c8c15f6d2f3f7ffbeff5daa211907dff1b13650Richard Osborne RegisterAsmPrinter<XCoreAsmPrinter> X(TheXCoreTarget); 3420c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar} 343