XCoreAsmPrinter.cpp revision db125cfaf57cc83e7dd7453de2d509bc8efd0e5e
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"
17b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "XCoreInstrInfo.h"
18b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "XCoreSubtarget.h"
19b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "XCoreTargetMachine.h"
20b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/Constants.h"
21b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/DerivedTypes.h"
22b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/Module.h"
23b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/AsmPrinter.h"
24b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/MachineModuleInfo.h"
25b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/MachineFunctionPass.h"
26b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/MachineConstantPool.h"
27b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/CodeGen/MachineInstr.h"
2878700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne#include "llvm/CodeGen/MachineJumpTableInfo.h"
291abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng#include "llvm/MC/MCAsmInfo.h"
306c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h"
31325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h"
32d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner#include "llvm/Target/Mangler.h"
33b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/Target/TargetData.h"
34f0144127b98425d214e59e4a1a4b342b78e3642bChris Lattner#include "llvm/Target/TargetLoweringObjectFile.h"
350c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar#include "llvm/Target/TargetRegistry.h"
367ad07c46362500f7291a92742569e94fd3538dfdChris Lattner#include "llvm/ADT/SmallString.h"
37b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/ADT/StringExtras.h"
38b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "llvm/Support/CommandLine.h"
39804e0fea4033e3b91dbc8198cef30de30f141bb5Torok Edwin#include "llvm/Support/ErrorHandling.h"
40b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/Support/raw_ostream.h"
41b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include <algorithm>
42b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include <cctype>
43b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborneusing namespace llvm;
44b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
45b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornestatic cl::opt<unsigned> MaxThreads("xcore-max-threads", cl::Optional,
46b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  cl::desc("Maximum number of threads (for emulation thread-local storage)"),
47b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  cl::Hidden,
48b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  cl::value_desc("number"),
49b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  cl::init(8));
50b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
51b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornenamespace {
526726b6d75a8b679068a58cb954ba97cf9d1690baNick Lewycky  class XCoreAsmPrinter : public AsmPrinter {
53b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    const XCoreSubtarget &Subtarget;
5457f0db833dc30404f1f5d28b23df326e520698ecBill Wendling  public:
55b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner    explicit XCoreAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
56b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner      : AsmPrinter(TM, Streamer), Subtarget(TM.getSubtarget<XCoreSubtarget>()){}
57b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
58b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    virtual const char *getPassName() const {
59b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      return "XCore Assembly Printer";
60b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    }
61b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
6235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
6335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O,
6478700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne                       const std::string &directive = ".jmptable");
6535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printInlineJT32(const MachineInstr *MI, int opNum, raw_ostream &O) {
6635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      printInlineJT(MI, opNum, O, ".jmptable32");
6778700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne    }
6835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
69b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
70c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                         unsigned AsmVariant, const char *ExtraCode,
71c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                         raw_ostream &O);
72f301c2299c95a1f60e879be4a3b0179ed3935d44Richard Osborne
739d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    void emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV);
7474bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattner    virtual void EmitGlobalVariable(const GlobalVariable *GV);
75b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
7635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen'd.
77d95148f073c31924f275a34296da52a7cdefad91Chris Lattner    static const char *getRegisterName(unsigned RegNo);
7805af2616d0df19638e799d3e7afadea26d96a4baChris Lattner
79d7d44bd5a81a4300201064cee1407fe804990320Chris Lattner    void EmitFunctionEntryLabel();
80a34103f6fa6f21025518596efc73631eb899410bChris Lattner    void EmitInstruction(const MachineInstr *MI);
81a34103f6fa6f21025518596efc73631eb899410bChris Lattner    void EmitFunctionBodyEnd();
82b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  };
83b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne} // end of anonymous namespace
84b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
85b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne#include "XCoreGenAsmWriter.inc"
86b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
879d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattnervoid XCoreAsmPrinter::emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV) {
88f943b1586f9964c88ae6431c09887e7c7917e449Richard Osborne  assert(((GV->hasExternalLinkage() ||
89b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    GV->hasWeakLinkage()) ||
90f943b1586f9964c88ae6431c09887e7c7917e449Richard Osborne    GV->hasLinkOnceLinkage()) && "Unexpected linkage");
91db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  if (ArrayType *ATy = dyn_cast<ArrayType>(
9212164414dd3daa6974985eeb2e89bfb93cf07641Chris Lattner    cast<PointerType>(GV->getType())->getElementType())) {
939d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.EmitSymbolAttribute(Sym, MCSA_Global);
9473ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner    // FIXME: MCStreamerize.
9573ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner    OutStreamer.EmitRawText(StringRef(".globound"));
9673ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner    OutStreamer.EmitRawText("\t.set\t" + Twine(Sym->getName()));
9773ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner    OutStreamer.EmitRawText(".globound," + Twine(ATy->getNumElements()));
98b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) {
99b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      // TODO Use COMDAT groups for LinkOnceLinkage
10073ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner      OutStreamer.EmitRawText(MAI->getWeakDefDirective() +Twine(Sym->getName())+
10173ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner                              ".globound");
102b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    }
103b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  }
104b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
105b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
10674bfe21b50c14c15f55ce3bd5857d65b588fae3cChris Lattnervoid XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
107e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  // Check to see if this is a special global used by LLVM, if so, emit it.
108e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  if (!GV->hasInitializer() ||
109e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner      EmitSpecialLLVMGlobal(GV))
110e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner    return;
111b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
112e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  const TargetData *TD = TM.getTargetData();
1136c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner  OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GV, Mang,TM));
11412164414dd3daa6974985eeb2e89bfb93cf07641Chris Lattner
115e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner
116d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner  MCSymbol *GVSym = Mang->getSymbol(GV);
1177d715dfe6d66be257926f626df96a0e2bd38dc1fJay Foad  const Constant *C = GV->getInitializer();
118e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  unsigned Align = (unsigned)TD->getPreferredTypeAlignmentShift(C->getType());
119e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner
120e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  // Mark the start of the global
12173ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner  OutStreamer.EmitRawText("\t.cc_top " + Twine(GVSym->getName()) + ".data," +
12273ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner                          GVSym->getName());
123e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner
124e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  switch (GV->getLinkage()) {
125e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  case GlobalValue::AppendingLinkage:
12675361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner    report_fatal_error("AppendingLinkage is not supported by this target!");
127e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  case GlobalValue::LinkOnceAnyLinkage:
128e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  case GlobalValue::LinkOnceODRLinkage:
129e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  case GlobalValue::WeakAnyLinkage:
130e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  case GlobalValue::WeakODRLinkage:
131e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  case GlobalValue::ExternalLinkage:
13212164414dd3daa6974985eeb2e89bfb93cf07641Chris Lattner    emitArrayBound(GVSym, GV);
1339d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
1349d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner
135e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner    // TODO Use COMDAT groups for LinkOnceLinkage
13610b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner    if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage())
13773ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner      OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak);
138e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner    // FALL THROUGH
139e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  case GlobalValue::InternalLinkage:
140e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  case GlobalValue::PrivateLinkage:
141e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner    break;
142e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  case GlobalValue::DLLImportLinkage:
143e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner    llvm_unreachable("DLLImport linkage is not supported by this target!");
144e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  case GlobalValue::DLLExportLinkage:
145e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner    llvm_unreachable("DLLExport linkage is not supported by this target!");
146e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  default:
147e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner    llvm_unreachable("Unknown linkage type!");
148e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  }
149b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
150a7b611c10d0e5fef5870d854518e639ce3d3c6beChris Lattner  EmitAlignment(Align > 2 ? Align : 2, GV);
151e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner
152e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  unsigned Size = TD->getTypeAllocSize(C->getType());
153e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  if (GV->isThreadLocal()) {
154e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner    Size *= MaxThreads;
155e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  }
15633adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner  if (MAI->hasDotTypeDotSizeDirective()) {
15773ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner    OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject);
15873ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner    OutStreamer.EmitRawText("\t.size " + Twine(GVSym->getName()) + "," +
15973ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner                            Twine(Size));
160e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  }
16173ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner  OutStreamer.EmitLabel(GVSym);
162e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner
163e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  EmitGlobalConstant(C);
164e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  if (GV->isThreadLocal()) {
1656449abfbc86310edbbe0b5ffb3fad5c14301307fChris Lattner    for (unsigned i = 1; i < MaxThreads; ++i)
166e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner      EmitGlobalConstant(C);
167e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  }
1686449abfbc86310edbbe0b5ffb3fad5c14301307fChris Lattner  // The ABI requires that unsigned scalar types smaller than 32 bits
169f958dd2e1c12b70f6eef5a2aef4a6ac497a1b471Chris Lattner  // are padded to 32 bits.
1706449abfbc86310edbbe0b5ffb3fad5c14301307fChris Lattner  if (Size < 4)
1716449abfbc86310edbbe0b5ffb3fad5c14301307fChris Lattner    OutStreamer.EmitZeros(4 - Size, 0);
172e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner
173e4d8408c572a3667e49d32b95c31b455bcec4a45Chris Lattner  // Mark the end of the global
17473ce0a63e6cfdbf13470154b84b7ee1de06f996fChris Lattner  OutStreamer.EmitRawText("\t.cc_bottom " + Twine(GVSym->getName()) + ".data");
175b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
176b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
177a34103f6fa6f21025518596efc73631eb899410bChris Lattner/// EmitFunctionBodyEnd - Targets can override this to emit stuff after
178a34103f6fa6f21025518596efc73631eb899410bChris Lattner/// the last basic block in the function.
179a34103f6fa6f21025518596efc73631eb899410bChris Lattnervoid XCoreAsmPrinter::EmitFunctionBodyEnd() {
180a34103f6fa6f21025518596efc73631eb899410bChris Lattner  // Emit function end directives
1819d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  OutStreamer.EmitRawText("\t.cc_bottom " + Twine(CurrentFnSym->getName()) +
1829d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                          ".function");
183a34103f6fa6f21025518596efc73631eb899410bChris Lattner}
184a34103f6fa6f21025518596efc73631eb899410bChris Lattner
185d7d44bd5a81a4300201064cee1407fe804990320Chris Lattnervoid XCoreAsmPrinter::EmitFunctionEntryLabel() {
186d7d44bd5a81a4300201064cee1407fe804990320Chris Lattner  // Mark the start of the function
187d7d44bd5a81a4300201064cee1407fe804990320Chris Lattner  OutStreamer.EmitRawText("\t.cc_top " + Twine(CurrentFnSym->getName()) +
188d7d44bd5a81a4300201064cee1407fe804990320Chris Lattner                          ".function," + CurrentFnSym->getName());
189d7d44bd5a81a4300201064cee1407fe804990320Chris Lattner  OutStreamer.EmitLabel(CurrentFnSym);
190b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
191b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
19235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid XCoreAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
19335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O) {
19435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, opNum, O);
195b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
196d7d44bd5a81a4300201064cee1407fe804990320Chris Lattner  if (MI->getOperand(opNum+1).isImm() && MI->getOperand(opNum+1).getImm() == 0)
197b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    return;
198b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
199b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  O << "+";
20035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, opNum+1, O);
201b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
202b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
20378700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osbornevoid XCoreAsmPrinter::
20435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerprintInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O,
20535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner              const std::string &directive) {
20678700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne  unsigned JTI = MI->getOperand(opNum).getIndex();
20778700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne  const MachineFunction *MF = MI->getParent()->getParent();
20878700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
20978700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
21078700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
21178700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne  O << "\t" << directive << " ";
21278700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
21378700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne    MachineBasicBlock *MBB = JTBBs[i];
21478700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne    if (i > 0)
21578700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne      O << ",";
2161b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner    O << *MBB->getSymbol();
21778700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne  }
21878700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne}
21978700b0c55ccc2d355ba9ee2ac666d669052b0cbRichard Osborne
22035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
22135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                   raw_ostream &O) {
222b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  const MachineOperand &MO = MI->getOperand(opNum);
223b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  switch (MO.getType()) {
224b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  case MachineOperand::MO_Register:
225762ccea600158bb317dcccdff3303e942426cb71Chris Lattner    O << getRegisterName(MO.getReg());
226b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    break;
227b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  case MachineOperand::MO_Immediate:
228b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    O << MO.getImm();
229b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    break;
230b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  case MachineOperand::MO_MachineBasicBlock:
2311b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner    O << *MO.getMBB()->getSymbol();
232b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    break;
233b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  case MachineOperand::MO_GlobalAddress:
234d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner    O << *Mang->getSymbol(MO.getGlobal());
235b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    break;
236b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  case MachineOperand::MO_ExternalSymbol:
237b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    O << MO.getSymbolName();
238b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    break;
239b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  case MachineOperand::MO_ConstantPoolIndex:
24033adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner    O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
241b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      << '_' << MO.getIndex();
242b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    break;
243b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  case MachineOperand::MO_JumpTableIndex:
24433adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner    O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
245b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne      << '_' << MO.getIndex();
2466a9157913cb09ad49c000ebe255d950b1857c659Chris Lattner    break;
247bea7df56ce7f4a5e1c65770c33fbf6dd39afd1dfRichard Osborne  case MachineOperand::MO_BlockAddress:
24810b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner    O << *GetBlockAddressSymbol(MO.getBlockAddress());
249b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne    break;
250b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  default:
251c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("not implemented");
252b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  }
253b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
254b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
255b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne/// PrintAsmOperand - Print out an operand for an inline asm expression.
256b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne///
257b25baef26f03b9909b65dd5f762b38f93000445dRichard Osbornebool XCoreAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
258c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                      unsigned AsmVariant,const char *ExtraCode,
259c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                      raw_ostream &O) {
26035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, OpNo, O);
261b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  return false;
262b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
263b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
264a34103f6fa6f21025518596efc73631eb899410bChris Lattnervoid XCoreAsmPrinter::EmitInstruction(const MachineInstr *MI) {
2659d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  SmallString<128> Str;
2669d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  raw_svector_ostream O(Str);
2672aaa98da767ffd07e773a228bcae4adf65c49bc5Jakob Stoklund Olesen
268b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne  // Check for mov mnemonic
2692aaa98da767ffd07e773a228bcae4adf65c49bc5Jakob Stoklund Olesen  if (MI->getOpcode() == XCore::ADD_2rus && !MI->getOperand(2).getImm())
2702aaa98da767ffd07e773a228bcae4adf65c49bc5Jakob Stoklund Olesen    O << "\tmov " << getRegisterName(MI->getOperand(0).getReg()) << ", "
2712aaa98da767ffd07e773a228bcae4adf65c49bc5Jakob Stoklund Olesen      << getRegisterName(MI->getOperand(1).getReg());
2722aaa98da767ffd07e773a228bcae4adf65c49bc5Jakob Stoklund Olesen  else
2739d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    printInstruction(MI, O);
2749d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  OutStreamer.EmitRawText(O.str());
275b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne}
276b25baef26f03b9909b65dd5f762b38f93000445dRichard Osborne
2770c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar// Force static initialization.
2781c8c15f6d2f3f7ffbeff5daa211907dff1b13650Richard Osborneextern "C" void LLVMInitializeXCoreAsmPrinter() {
2791c8c15f6d2f3f7ffbeff5daa211907dff1b13650Richard Osborne  RegisterAsmPrinter<XCoreAsmPrinter> X(TheXCoreTarget);
2800c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar}
281