ARMAsmPrinter.cpp revision 0f3cc657387d44cd7c56e4ddea896a50ab9106b8
17bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===-- ARMAsmPrinter.cpp - ARM LLVM assembly writer ----------------------===//
27bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
37bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//                     The LLVM Compiler Infrastructure
47bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
67bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// License. See LICENSE.TXT for details.
77bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
87bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===//
97bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// This file contains a printer that converts from our internal representation
117bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// of machine-dependent LLVM code to GAS-format ARM assembly language.
127bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
137bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===//
147bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1595b2c7da5e83670881270c1cd231a240be0556d9Chris Lattner#define DEBUG_TYPE "asm-printer"
167bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARM.h"
17a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMTargetMachine.h"
18a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMAddressingModes.h"
19a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMConstantPoolValue.h"
20a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMMachineFunctionInfo.h"
217bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Constants.h"
227bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Module.h"
237bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/AsmPrinter.h"
24a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/DwarfWriter.h"
2544c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey#include "llvm/CodeGen/MachineModuleInfo.h"
267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h"
27a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h"
28563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey#include "llvm/Target/TargetAsmInfo.h"
29b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h"
307bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h"
315be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng#include "llvm/Target/TargetOptions.h"
327bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/ADT/Statistic.h"
337bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/ADT/StringExtras.h"
34a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/Support/Compiler.h"
35a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/Support/Mangler.h"
367bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Support/MathExtras.h"
377bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype>
387bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm;
397bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
4095b2c7da5e83670881270c1cd231a240be0556d9Chris LattnerSTATISTIC(EmittedInsts, "Number of machine instrs printed");
417bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
4295b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace {
43563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey  struct VISIBILITY_HIDDEN ARMAsmPrinter : public AsmPrinter {
44a0f3d17daac73c9c71aad497b298cbe82848f726Jim Laskey    ARMAsmPrinter(std::ostream &O, TargetMachine &TM, const TargetAsmInfo *T)
45f2452c5f48e13cf3a9e620d22d5040a90133ddcaDale Johannesen      : AsmPrinter(O, TM, T), DW(O, this, T), MMI(NULL), AFI(NULL),
46f2452c5f48e13cf3a9e620d22d5040a90133ddcaDale Johannesen        InCPMode(false) {
47a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      Subtarget = &TM.getSubtarget<ARMSubtarget>();
48563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey    }
497bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
50a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    DwarfWriter DW;
51f2452c5f48e13cf3a9e620d22d5040a90133ddcaDale Johannesen    MachineModuleInfo *MMI;
52a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
53a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
54a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// make the right decision when printing asm code for different targets.
55a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    const ARMSubtarget *Subtarget;
56a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
57a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// AFI - Keep a pointer to ARMFunctionInfo for the current
58a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// MachineFunction
59a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    ARMFunctionInfo *AFI;
60a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
617bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    /// We name each basic block in a Function with a unique number, so
627bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    /// that we can consistently refer to them later. This is cleared
637bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    /// at the beginning of each call to runOnMachineFunction().
647bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    ///
657bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    typedef std::map<const Value *, unsigned> ValueMapTy;
667bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    ValueMapTy NumberForBB;
677bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
68a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// Keeps the set of GlobalValues that require non-lazy-pointers for
69a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// indirect access.
70a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    std::set<std::string> GVNonLazyPtrs;
71a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
72a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// Keeps the set of external function GlobalAddresses that the asm
73a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// printer should generate stubs for.
74a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    std::set<std::string> FnStubs;
75a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
76a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// True if asm printer is printing a series of CONSTPOOL_ENTRY.
77a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    bool InCPMode;
78a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
797bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    virtual const char *getPassName() const {
807bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola      return "ARM Assembly Printer";
817bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    }
827bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
83a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printOperand(const MachineInstr *MI, int opNum,
84a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                      const char *Modifier = 0);
85a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printSOImmOperand(const MachineInstr *MI, int opNum);
86c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng    void printSOImm2PartOperand(const MachineInstr *MI, int opNum);
87a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printSORegOperand(const MachineInstr *MI, int opNum);
88a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printAddrMode2Operand(const MachineInstr *MI, int OpNo);
89a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNo);
90a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printAddrMode3Operand(const MachineInstr *MI, int OpNo);
91a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printAddrMode3OffsetOperand(const MachineInstr *MI, int OpNo);
92a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printAddrMode4Operand(const MachineInstr *MI, int OpNo,
93a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                               const char *Modifier = 0);
94a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printAddrMode5Operand(const MachineInstr *MI, int OpNo,
95a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                               const char *Modifier = 0);
96a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printAddrModePCOperand(const MachineInstr *MI, int OpNo,
97a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                const char *Modifier = 0);
98a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNo);
99a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNo,
100a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                      unsigned Scale);
101c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan Cheng    void printThumbAddrModeS1Operand(const MachineInstr *MI, int OpNo);
102c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan Cheng    void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNo);
103c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan Cheng    void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNo);
104a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNo);
10542d712b3067ec14170f80d8adfc7e5ad5878132bEvan Cheng    void printPredicateOperand(const MachineInstr *MI, int opNum);
106dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng    void printSBitModifierOperand(const MachineInstr *MI, int opNum);
107a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printPCLabel(const MachineInstr *MI, int opNum);
108a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printRegisterList(const MachineInstr *MI, int opNum);
109a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printCPInstOperand(const MachineInstr *MI, int opNum,
110a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                            const char *Modifier);
111a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printJTBlockOperand(const MachineInstr *MI, int opNum);
112a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
113a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
114a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                 unsigned AsmVariant, const char *ExtraCode);
1157bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1160f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    void printModuleLevelGV(const GlobalVariable* GVar);
1177bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    bool printInstruction(const MachineInstr *MI);  // autogenerated.
118a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printMachineInstruction(const MachineInstr *MI);
1197bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    bool runOnMachineFunction(MachineFunction &F);
1207bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    bool doInitialization(Module &M);
1217bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    bool doFinalization(Module &M);
122a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1230f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    /// getSectionForFunction - Return the section that we should emit the
1240f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    /// specified function body into.
1250f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    virtual std::string getSectionForFunction(const Function &F) const;
1260f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
127a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
128a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      printDataDirective(MCPV->getType());
129a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
130a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      ARMConstantPoolValue *ACPV = (ARMConstantPoolValue*)MCPV;
1311a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio      GlobalValue *GV = ACPV->getGV();
132c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng      std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix();
133c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng      if (!GV)
134c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng        Name += ACPV->getSymbol();
135a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      if (ACPV->isNonLazyPointer()) {
136a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        GVNonLazyPtrs.insert(Name);
137c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen        printSuffixedName(Name, "$non_lazy_ptr");
138c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng      } else if (ACPV->isStub()) {
139c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng        FnStubs.insert(Name);
140c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen        printSuffixedName(Name, "$stub");
141a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      } else
142a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        O << Name;
1430ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
14464f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio      if (ACPV->getPCAdjustment() != 0) {
145a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        O << "-(" << TAI->getPrivateGlobalPrefix() << "PC"
146a8e2989ece6dc46df59b0768184028257f913843Evan Cheng          << utostr(ACPV->getLabelId())
14764f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio          << "+" << (unsigned)ACPV->getPCAdjustment();
14864f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio         if (ACPV->mustAddCurrentAddress())
14964f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio           O << "-.";
15064f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio         O << ")";
15164f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio      }
152a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\n";
1531a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio
1541a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio      // If the constant pool value is a extern weak symbol, remember to emit
1551a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio      // the weak reference.
156c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng      if (GV && GV->hasExternalWeakLinkage())
1571a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio        ExtWeakSymbols.insert(GV);
158a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
159a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
160a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void getAnalysisUsage(AnalysisUsage &AU) const {
161cd8bc05102e7963a5839cfdca7785390288bc745Gordon Henriksen      AsmPrinter::getAnalysisUsage(AU);
162a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      AU.setPreservesAll();
16344c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey      AU.addRequired<MachineModuleInfo>();
164a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
1657bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  };
1667bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace
1677bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1687bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMGenAsmWriter.inc"
1697bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1707bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// createARMCodePrinterPass - Returns a pass that prints the ARM
1717bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// assembly code for a MachineFunction to the given output stream,
1727bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// using the given target machine description.  This should work
1737bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// regardless of whether the function is in SSA form.
1747bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola///
1757bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaFunctionPass *llvm::createARMCodePrinterPass(std::ostream &o,
176a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                             ARMTargetMachine &tm) {
177a0f3d17daac73c9c71aad497b298cbe82848f726Jim Laskey  return new ARMAsmPrinter(o, tm, tm.getTargetAsmInfo());
1787bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1797bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1800f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov// Substitute old hook with new one temporary
1810f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikovstd::string ARMAsmPrinter::getSectionForFunction(const Function &F) const {
1820f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  return TAI->SectionForGlobal(&F);
1830f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov}
1840f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
185a8e2989ece6dc46df59b0768184028257f913843Evan Cheng/// runOnMachineFunction - This uses the printInstruction()
1867bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction.
1877bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola///
1887bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
189a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  AFI = MF.getInfo<ARMFunctionInfo>();
190a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
191a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  SetupMachineFunction(MF);
192a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "\n";
193a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
194a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // NOTE: we don't print out constant pools here, they are handled as
195a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // instructions.
1964b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola
197a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "\n";
1984b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  // Print out labels for the function.
1994b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  const Function *F = MF.getFunction();
2004b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  switch (F->getLinkage()) {
2014b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  default: assert(0 && "Unknown linkage type!");
2024b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  case Function::InternalLinkage:
203a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    SwitchToTextSection("\t.text", F);
2044b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    break;
2054b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  case Function::ExternalLinkage:
206a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    SwitchToTextSection("\t.text", F);
2074b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    O << "\t.globl\t" << CurrentFnName << "\n";
2084b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    break;
2094b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  case Function::WeakLinkage:
2104b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  case Function::LinkOnceLinkage:
2115be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    if (Subtarget->isTargetDarwin()) {
212a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      SwitchToTextSection(
213a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F);
214a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\t.globl\t" << CurrentFnName << "\n";
215a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\t.weak_definition\t" << CurrentFnName << "\n";
216a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    } else {
217a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << TAI->getWeakRefDirective() << CurrentFnName << "\n";
218a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
2194b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    break;
2204b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  }
221a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
2220a1817392d3ad7ec2681e6bf495f490c443ec0b7Lauro Ramos Venancio  const char *VisibilityDirective = NULL;
223616cc663daf965695809213d8cf8e3686e5309c3Evan Cheng  if (F->hasHiddenVisibility())
2240a1817392d3ad7ec2681e6bf495f490c443ec0b7Lauro Ramos Venancio    VisibilityDirective = TAI->getHiddenDirective();
2250a1817392d3ad7ec2681e6bf495f490c443ec0b7Lauro Ramos Venancio  else if (F->hasProtectedVisibility())
2260a1817392d3ad7ec2681e6bf495f490c443ec0b7Lauro Ramos Venancio    VisibilityDirective = TAI->getProtectedDirective();
2270a1817392d3ad7ec2681e6bf495f490c443ec0b7Lauro Ramos Venancio
2280a1817392d3ad7ec2681e6bf495f490c443ec0b7Lauro Ramos Venancio  if (VisibilityDirective)
2290a1817392d3ad7ec2681e6bf495f490c443ec0b7Lauro Ramos Venancio    O << VisibilityDirective << CurrentFnName << "\n";
230616cc663daf965695809213d8cf8e3686e5309c3Evan Cheng
231a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (AFI->isThumbFunction()) {
2323a4205367dc845d4cd804b47e061f8281777c9daChris Lattner    EmitAlignment(1, F, AFI->getAlign());
233a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "\t.code\t16\n";
2346f46e59d2a0e66f3646db9677258876960477f87Lauro Ramos Venancio    O << "\t.thumb_func";
2356f46e59d2a0e66f3646db9677258876960477f87Lauro Ramos Venancio    if (Subtarget->isTargetDarwin())
2366f46e59d2a0e66f3646db9677258876960477f87Lauro Ramos Venancio      O << "\t" << CurrentFnName;
2376f46e59d2a0e66f3646db9677258876960477f87Lauro Ramos Venancio    O << "\n";
238a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    InCPMode = false;
239a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else
240a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    EmitAlignment(2, F);
241a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
2424b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  O << CurrentFnName << ":\n";
243e8e5495474d67cd5151bd88e502be3f46ace7a85Lauro Ramos Venancio  // Emit pre-function debug information.
244e8e5495474d67cd5151bd88e502be3f46ace7a85Lauro Ramos Venancio  DW.BeginFunction(&MF);
2454b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola
246200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling  if (Subtarget->isTargetDarwin()) {
247200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling    // If the function is empty, then we need to emit *something*. Otherwise,
248200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling    // the function's label might be associated with something that it wasn't
249200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling    // meant to be associated with. We emit a noop in this situation.
250200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling    MachineFunction::iterator I = MF.begin();
251200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling
252200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling    if (++I == MF.end() && MF.front().empty())
253200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling      O << "\tnop\n";
254200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling  }
255200e90c74bff0b533c87e2d781815fa61af7b4d6Bill Wendling
2564b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  // Print out code for the function.
2574b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
2584b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola       I != E; ++I) {
2594b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    // Print a label for the basic block.
2604b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    if (I != MF.begin()) {
261fb8075d03f5c87bd57dcc9c5f2304f6b13c55aadEvan Cheng      printBasicBlockLabel(I, true, true);
2624b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola      O << '\n';
2634b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    }
2644b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
2654b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola         II != E; ++II) {
2664b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola      // Print the assembly for the instruction.
267a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      printMachineInstruction(II);
2683ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola    }
2697cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola  }
2707cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola
271a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (TAI->hasDotTypeDotSizeDirective())
272a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n";
2736e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola
274e8e5495474d67cd5151bd88e502be3f46ace7a85Lauro Ramos Venancio  // Emit post-function debug information.
275e8e5495474d67cd5151bd88e502be3f46ace7a85Lauro Ramos Venancio  DW.EndFunction();
27632bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola
277a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  return false;
27832bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola}
27932bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola
280a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
281a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                 const char *Modifier) {
282a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO = MI->getOperand(opNum);
2832f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  switch (MO.getType()) {
2842f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_Register:
2856f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman    if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
28674ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling      O << TM.getRegisterInfo()->get(MO.getReg()).AsmName;
2872f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    else
2882f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola      assert(0 && "not implemented");
2892f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
290a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_Immediate: {
291a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (!Modifier || strcmp(Modifier, "no_hash") != 0)
292a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "#";
293a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
2949a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner    O << (int)MO.getImm();
2952f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
296a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
2972f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_MachineBasicBlock:
2988aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner    printBasicBlockLabel(MO.getMBB());
2992f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    return;
30084b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola  case MachineOperand::MO_GlobalAddress: {
301a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    bool isCallOp = Modifier && !strcmp(Modifier, "call");
30284b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola    GlobalValue *GV = MO.getGlobal();
30384b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola    std::string Name = Mang->getValueName(GV);
3045cbf985dcbc89fba3208e7baf8b6f488b06d3ec9Reid Spencer    bool isExt = (GV->isDeclaration() || GV->hasWeakLinkage() ||
305a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                  GV->hasLinkOnceLinkage());
3065be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    if (isExt && isCallOp && Subtarget->isTargetDarwin() &&
307a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        TM.getRelocationModel() != Reloc::Static) {
308c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen      printSuffixedName(Name, "$stub");
309a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      FnStubs.insert(Name);
310a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    } else
311a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << Name;
312388488d604a63fc25d5f6b2c598f7cc4499c9db5Chris Lattner
313388488d604a63fc25d5f6b2c598f7cc4499c9db5Chris Lattner    if (MO.getOffset() > 0)
314388488d604a63fc25d5f6b2c598f7cc4499c9db5Chris Lattner      O << '+' << MO.getOffset();
315388488d604a63fc25d5f6b2c598f7cc4499c9db5Chris Lattner    else if (MO.getOffset() < 0)
316388488d604a63fc25d5f6b2c598f7cc4499c9db5Chris Lattner      O << MO.getOffset();
317388488d604a63fc25d5f6b2c598f7cc4499c9db5Chris Lattner
3180ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio    if (isCallOp && Subtarget->isTargetELF() &&
3190ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio        TM.getRelocationModel() == Reloc::PIC_)
3200ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
321a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (GV->hasExternalWeakLinkage())
32215404d060ba8b604c03b9223a0f2e2abcd0fddedRafael Espindola      ExtWeakSymbols.insert(GV);
3232f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
324a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
325a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_ExternalSymbol: {
326a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    bool isCallOp = Modifier && !strcmp(Modifier, "call");
327a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    std::string Name(TAI->getGlobalPrefix());
328a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    Name += MO.getSymbolName();
3295be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    if (isCallOp && Subtarget->isTargetDarwin() &&
330a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        TM.getRelocationModel() != Reloc::Static) {
331c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen      printSuffixedName(Name, "$stub");
332a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      FnStubs.insert(Name);
333a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    } else
334a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << Name;
3350ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio    if (isCallOp && Subtarget->isTargetELF() &&
3360ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio        TM.getRelocationModel() == Reloc::PIC_)
3370ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
3382f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
339a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
3402f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_ConstantPoolIndex:
341347d39f1fd8ad825a7ec5b8a3dce816723a56d42Evan Cheng    O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
3428aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner      << '_' << MO.getIndex();
3432f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
344a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_JumpTableIndex:
345347d39f1fd8ad825a7ec5b8a3dce816723a56d42Evan Cheng    O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
3468aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner      << '_' << MO.getIndex();
347a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    break;
3482f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  default:
3492f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    O << "<unknown operand type>"; abort (); break;
3502f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  }
3517bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
3527bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
353c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Chengstatic void printSOImm(std::ostream &O, int64_t V, const TargetAsmInfo *TAI) {
354c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  assert(V < (1 << 12) && "Not a valid so_imm value!");
355c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  unsigned Imm = ARM_AM::getSOImmValImm(V);
356c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  unsigned Rot = ARM_AM::getSOImmValRot(V);
357a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
358a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Print low-level immediate formation info, per
359a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // A5.1.3: "Data-processing operands - Immediate".
360a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Rot) {
361a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "#" << Imm << ", " << Rot;
362a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Pretty printed version.
363a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ' ' << TAI->getCommentString() << ' ' << (int)ARM_AM::rotr32(Imm, Rot);
364a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
365a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "#" << Imm;
366a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
367a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
368a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
369c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
370c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// immediate in bits 0-7.
371c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Chengvoid ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) {
372c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
373c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  assert(MO.isImmediate() && "Not a valid so_imm value!");
3749a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner  printSOImm(O, MO.getImm(), TAI);
375c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng}
376c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng
377c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// printSOImm2PartOperand - SOImm is broken into two pieces using a mov
378c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// followed by a or to materialize.
379c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Chengvoid ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) {
380c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
381c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  assert(MO.isImmediate() && "Not a valid so_imm value!");
3829a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner  unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImm());
3839a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner  unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImm());
384c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  printSOImm(O, ARM_AM::getSOImmVal(V1), TAI);
3855e148a37d3432f83ccc4dbebe08d4f1b4717034cEvan Cheng  O << "\n\torr";
3865e148a37d3432f83ccc4dbebe08d4f1b4717034cEvan Cheng  printPredicateOperand(MI, 2);
3875e148a37d3432f83ccc4dbebe08d4f1b4717034cEvan Cheng  O << " ";
388c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  printOperand(MI, 0);
389c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  O << ", ";
390c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  printOperand(MI, 0);
391c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  O << ", ";
392c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  printSOImm(O, ARM_AM::getSOImmVal(V2), TAI);
393c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng}
394c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng
395a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// so_reg is a 4-operand unit corresponding to register forms of the A5.1
396a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// "Addressing Mode 1 - Data-processing operands" forms.  This includes:
397a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//    REG 0   0    - e.g. R5
398a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//    REG REG 0,SH_OPC     - e.g. R5, ROR R3
399a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
400a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op) {
401a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
402a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
403a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
404a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
4056f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
40674ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling  O << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
407a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
408a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Print the shift opc.
409a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << ", "
4109a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner    << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()))
411a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    << " ";
412a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
413a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (MO2.getReg()) {
4146f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman    assert(TargetRegisterInfo::isPhysicalRegister(MO2.getReg()));
41574ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling    O << TM.getRegisterInfo()->get(MO2.getReg()).AsmName;
416a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
417a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
418a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "#" << ARM_AM::getSORegOffset(MO3.getImm());
419a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
420a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
421a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
422a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op) {
423a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
424a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
425a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
426a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
427a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!MO1.isRegister()) {   // FIXME: This is for CP entries, but isn't right.
428a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    printOperand(MI, Op);
429a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
430a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
431a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
43274ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
433a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
434a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!MO2.getReg()) {
435a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ARM_AM::getAM2Offset(MO3.getImm()))  // Don't print +0.
436a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << ", #"
437a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        << (char)ARM_AM::getAM2Op(MO3.getImm())
438a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        << ARM_AM::getAM2Offset(MO3.getImm());
439a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "]";
440a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
441a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
442a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
443a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << ", "
444a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    << (char)ARM_AM::getAM2Op(MO3.getImm())
44574ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling    << TM.getRegisterInfo()->get(MO2.getReg()).AsmName;
446a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
447a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
448a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", "
4499a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
450a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << " #" << ShImm;
451a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
452a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
453a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
454a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op){
455a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
456a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
457a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
458a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!MO1.getReg()) {
459bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng    unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
460bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng    assert(ImmOffs && "Malformed indexed load / store!");
461bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng    O << "#"
462bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng      << (char)ARM_AM::getAM2Op(MO2.getImm())
463bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng      << ImmOffs;
464a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
465a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
466a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
467a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << (char)ARM_AM::getAM2Op(MO2.getImm())
46874ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling    << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
469a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
470a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
471a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", "
4729a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm()))
473a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << " #" << ShImm;
474a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
475a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
476a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op) {
477a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
478a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
479a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
480a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
4816f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
48274ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
483a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
484a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (MO2.getReg()) {
485a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", "
486a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << (char)ARM_AM::getAM3Op(MO3.getImm())
48774ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling      << TM.getRegisterInfo()->get(MO2.getReg()).AsmName
488a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << "]";
489a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
490a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
491a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
492a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
493a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", #"
494a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << (char)ARM_AM::getAM3Op(MO3.getImm())
495a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << ImmOffs;
496a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
497a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
498a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
499a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op){
500a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
501a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
502a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
503a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (MO1.getReg()) {
504a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << (char)ARM_AM::getAM3Op(MO2.getImm())
50574ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling      << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
506a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
507a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
508a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
509a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
510bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng  assert(ImmOffs && "Malformed indexed load / store!");
511a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "#"
512bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng    << (char)ARM_AM::getAM3Op(MO2.getImm())
513a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    << ImmOffs;
514a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
515a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
516a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
517a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                          const char *Modifier) {
518a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
519a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
520a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
521a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Modifier && strcmp(Modifier, "submode") == 0) {
522a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (MO1.getReg() == ARM::SP) {
523a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      bool isLDM = (MI->getOpcode() == ARM::LDM ||
524a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                    MI->getOpcode() == ARM::LDM_RET);
525a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << ARM_AM::getAMSubModeAltStr(Mode, isLDM);
526a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    } else
527a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << ARM_AM::getAMSubModeStr(Mode);
528a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
529a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    printOperand(MI, Op);
530a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ARM_AM::getAM4WBFlag(MO2.getImm()))
531a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "!";
532a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
533a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
534a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
535a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
536a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                          const char *Modifier) {
537a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
538a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
539a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
540a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!MO1.isRegister()) {   // FIXME: This is for CP entries, but isn't right.
541a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    printOperand(MI, Op);
542a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
543a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
544a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
5456f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
546a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
547a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Modifier && strcmp(Modifier, "submode") == 0) {
548a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MO2.getImm());
549a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (MO1.getReg() == ARM::SP) {
550a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      bool isFLDM = (MI->getOpcode() == ARM::FLDMD ||
551a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                     MI->getOpcode() == ARM::FLDMS);
552a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << ARM_AM::getAMSubModeAltStr(Mode, isFLDM);
553a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    } else
554a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << ARM_AM::getAMSubModeStr(Mode);
555a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
556a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else if (Modifier && strcmp(Modifier, "base") == 0) {
557a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Used for FSTM{D|S} and LSTM{D|S} operations.
55874ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling    O << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
559a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ARM_AM::getAM5WBFlag(MO2.getImm()))
560a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "!";
561a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
562a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
563a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
56474ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
565a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
566a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
567a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", #"
568a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << (char)ARM_AM::getAM5Op(MO2.getImm())
569a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << ImmOffs*4;
570a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
571a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
572a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
573a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
574a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
575a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                           const char *Modifier) {
576a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Modifier && strcmp(Modifier, "label") == 0) {
577a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    printPCLabel(MI, Op+1);
578a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
579a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
580a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
581a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
5826f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
58374ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling  O << "[pc, +" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName << "]";
584a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
585a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
586a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
587a8e2989ece6dc46df59b0768184028257f913843Evan ChengARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op) {
588a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
589a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
59074ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
59174ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling  O << ", " << TM.getRegisterInfo()->get(MO2.getReg()).AsmName << "]";
592a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
593a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
594a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
595a8e2989ece6dc46df59b0768184028257f913843Evan ChengARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
596a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                            unsigned Scale) {
597a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
598cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
599cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
600a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
601a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!MO1.isRegister()) {   // FIXME: This is for CP entries, but isn't right.
602a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    printOperand(MI, Op);
603a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
604a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
605a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
60674ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
607cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  if (MO3.getReg())
60874ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling    O << ", " << TM.getRegisterInfo()->get(MO3.getReg()).AsmName;
609cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  else if (unsigned ImmOffs = MO2.getImm()) {
610a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", #" << ImmOffs;
611a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (Scale > 1)
612a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << " * " << Scale;
613a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
614a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
615a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
616a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
617a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
618c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan ChengARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op) {
619cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  printThumbAddrModeRI5Operand(MI, Op, 1);
620a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
621a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
622c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan ChengARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op) {
623cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  printThumbAddrModeRI5Operand(MI, Op, 2);
624a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
625a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
626c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan ChengARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op) {
627cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  printThumbAddrModeRI5Operand(MI, Op, 4);
628a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
629a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
630a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) {
631a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
632a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
63374ab84c31ef64538a1b56e1f282e49303412ad17Bill Wendling  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
634a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ImmOffs = MO2.getImm())
635a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", #" << ImmOffs << " * 4";
636a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
6377bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
6387bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
63942d712b3067ec14170f80d8adfc7e5ad5878132bEvan Chengvoid ARMAsmPrinter::printPredicateOperand(const MachineInstr *MI, int opNum) {
6409a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner  ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(opNum).getImm();
64144bec52b1b7e9a3ac1efbae90db240b8c1ca2ad4Evan Cheng  if (CC != ARMCC::AL)
64244bec52b1b7e9a3ac1efbae90db240b8c1ca2ad4Evan Cheng    O << ARMCondCodeToString(CC);
6437bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
6447bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
645dfb2ebac29f92a533218bd576734913a89d1299dEvan Chengvoid ARMAsmPrinter::printSBitModifierOperand(const MachineInstr *MI, int opNum){
646dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng  unsigned Reg = MI->getOperand(opNum).getReg();
647dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng  if (Reg) {
648dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng    assert(Reg == ARM::CPSR && "Expect ARM CPSR register!");
649dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng    O << 's';
650dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng  }
651dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng}
652dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng
653a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int opNum) {
6549a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner  int Id = (int)MI->getOperand(opNum).getImm();
655a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << TAI->getPrivateGlobalPrefix() << "PC" << Id;
656a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
657a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
658a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int opNum) {
659a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "{";
660a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  for (unsigned i = opNum, e = MI->getNumOperands(); i != e; ++i) {
661a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    printOperand(MI, i);
662a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (i != e-1) O << ", ";
663a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
664a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "}";
665a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
666a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
667a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNo,
668a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                       const char *Modifier) {
669a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  assert(Modifier && "This operand only works with a modifier!");
670a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
671a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // data itself.
672a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!strcmp(Modifier, "label")) {
673a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    unsigned ID = MI->getOperand(OpNo).getImm();
674347d39f1fd8ad825a7ec5b8a3dce816723a56d42Evan Cheng    O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
675347d39f1fd8ad825a7ec5b8a3dce816723a56d42Evan Cheng      << '_' << ID << ":\n";
676a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
677a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
6788aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner    unsigned CPI = MI->getOperand(OpNo).getIndex();
679a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
680a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    const MachineConstantPoolEntry &MCPE =  // Chasing pointers is fun?
681a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      MI->getParent()->getParent()->getConstantPool()->getConstants()[CPI];
682a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
683a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (MCPE.isMachineConstantPoolEntry())
684a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
685305b8a5f62c9d027f3d8a870fc12fc2abf69aeeaLauro Ramos Venancio    else {
686a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      EmitGlobalConstant(MCPE.Val.ConstVal);
687305b8a5f62c9d027f3d8a870fc12fc2abf69aeeaLauro Ramos Venancio      // remember to emit the weak reference
688305b8a5f62c9d027f3d8a870fc12fc2abf69aeeaLauro Ramos Venancio      if (const GlobalValue *GV = dyn_cast<GlobalValue>(MCPE.Val.ConstVal))
689305b8a5f62c9d027f3d8a870fc12fc2abf69aeeaLauro Ramos Venancio        if (GV->hasExternalWeakLinkage())
690305b8a5f62c9d027f3d8a870fc12fc2abf69aeeaLauro Ramos Venancio          ExtWeakSymbols.insert(GV);
691305b8a5f62c9d027f3d8a870fc12fc2abf69aeeaLauro Ramos Venancio    }
692a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
693a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
694a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
695a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNo) {
696a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNo);
697a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNo+1); // Unique Id
6988aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner  unsigned JTI = MO1.getIndex();
699347d39f1fd8ad825a7ec5b8a3dce816723a56d42Evan Cheng  O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
7009a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner    << '_' << JTI << '_' << MO2.getImm() << ":\n";
701a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
702a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const char *JTEntryDirective = TAI->getJumpTableDirective();
703a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!JTEntryDirective)
704a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    JTEntryDirective = TAI->getData32bitsDirective();
705a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
706a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineFunction *MF = MI->getParent()->getParent();
7074542611bb9793e8376d7d5f33b4a1e2d11712894Dan Gohman  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
708a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
709a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
710a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  bool UseSet= TAI->getSetDirective() && TM.getRelocationModel() == Reloc::PIC_;
711a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  std::set<MachineBasicBlock*> JTSets;
712a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
713a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    MachineBasicBlock *MBB = JTBBs[i];
714a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (UseSet && JTSets.insert(MBB).second)
7159a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner      printPICJumpTableSetLabel(JTI, MO2.getImm(), MBB);
716a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
717a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << JTEntryDirective << ' ';
718a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (UseSet)
719347d39f1fd8ad825a7ec5b8a3dce816723a56d42Evan Cheng      O << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
7209a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner        << '_' << JTI << '_' << MO2.getImm()
721347d39f1fd8ad825a7ec5b8a3dce816723a56d42Evan Cheng        << "_set_" << MBB->getNumber();
722a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    else if (TM.getRelocationModel() == Reloc::PIC_) {
723fb8075d03f5c87bd57dcc9c5f2304f6b13c55aadEvan Cheng      printBasicBlockLabel(MBB, false, false, false);
724a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      // If the arch uses custom Jump Table directives, don't calc relative to JT
725a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      if (!TAI->getJumpTableDirective())
726a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        O << '-' << TAI->getPrivateGlobalPrefix() << "JTI"
7279a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner          << getFunctionNumber() << '_' << JTI << '_' << MO2.getImm();
728a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    } else
729fb8075d03f5c87bd57dcc9c5f2304f6b13c55aadEvan Cheng      printBasicBlockLabel(MBB, false, false, false);
730d85ac4d07966a56b3101598f29393f4532acc50fEvan Cheng    if (i != e-1)
731d85ac4d07966a56b3101598f29393f4532acc50fEvan Cheng      O << '\n';
732a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
733a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
734a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
735a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
736a8e2989ece6dc46df59b0768184028257f913843Evan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
737a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                    unsigned AsmVariant, const char *ExtraCode){
738a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Does this asm operand have a single letter operand modifier?
739a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (ExtraCode && ExtraCode[0]) {
740a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ExtraCode[1] != 0) return true; // Unknown modifier.
741a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
742a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    switch (ExtraCode[0]) {
743a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    default: return true;  // Unknown modifier.
74423a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng    case 'c': // Don't print "$" before a global var name or constant.
745e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng    case 'P': // Print a VFP double precision register.
74623a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng      printOperand(MI, OpNo);
74723a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng      return false;
748a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'Q':
749a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      if (TM.getTargetData()->isLittleEndian())
750a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        break;
751a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      // Fallthrough
752a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'R':
753a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      if (TM.getTargetData()->isBigEndian())
754a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        break;
755a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      // Fallthrough
756a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'H': // Write second word of DI / DF reference.
757a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      // Verify that this operand has two consecutive registers.
758a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      if (!MI->getOperand(OpNo).isRegister() ||
759a8e2989ece6dc46df59b0768184028257f913843Evan Cheng          OpNo+1 == MI->getNumOperands() ||
760a8e2989ece6dc46df59b0768184028257f913843Evan Cheng          !MI->getOperand(OpNo+1).isRegister())
761a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        return true;
762a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      ++OpNo;   // Return the high-part.
763a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
764a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
765a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
766a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  printOperand(MI, OpNo);
767a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  return false;
768a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
769a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
770a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
771a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  ++EmittedInsts;
772a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
773c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng  int Opc = MI->getOpcode();
774c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng  switch (Opc) {
775c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng  case ARM::CONSTPOOL_ENTRY:
776a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (!InCPMode && AFI->isThumbFunction()) {
777a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      EmitAlignment(2);
778a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      InCPMode = true;
779a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
780c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng    break;
781c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng  default: {
7823bf12d0460cc6dcd5ad9375be9a2b05535b002a6Evan Cheng    if (InCPMode && AFI->isThumbFunction())
783a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      InCPMode = false;
784c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng    switch (Opc) {
785c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng    case ARM::PICADD:
786c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng    case ARM::PICLD:
787341dcccb4e1f190f4aee12e92c2b7c2cb68c520dEvan Cheng    case ARM::PICLDZH:
788341dcccb4e1f190f4aee12e92c2b7c2cb68c520dEvan Cheng    case ARM::PICLDZB:
789341dcccb4e1f190f4aee12e92c2b7c2cb68c520dEvan Cheng    case ARM::PICLDH:
790341dcccb4e1f190f4aee12e92c2b7c2cb68c520dEvan Cheng    case ARM::PICLDB:
791341dcccb4e1f190f4aee12e92c2b7c2cb68c520dEvan Cheng    case ARM::PICLDSH:
792341dcccb4e1f190f4aee12e92c2b7c2cb68c520dEvan Cheng    case ARM::PICLDSB:
793341dcccb4e1f190f4aee12e92c2b7c2cb68c520dEvan Cheng    case ARM::PICSTR:
794341dcccb4e1f190f4aee12e92c2b7c2cb68c520dEvan Cheng    case ARM::PICSTRH:
795341dcccb4e1f190f4aee12e92c2b7c2cb68c520dEvan Cheng    case ARM::PICSTRB:
796c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng    case ARM::tPICADD:
797c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng      break;
798c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng    default:
799c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng      break;
800c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng    }
801c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng  }}
802a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
803a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Call the autogenerated instruction printer routines.
804a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  printInstruction(MI);
805a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
806a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
8077bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::doInitialization(Module &M) {
808e8e5495474d67cd5151bd88e502be3f46ace7a85Lauro Ramos Venancio  // Emit initial debug information.
809e8e5495474d67cd5151bd88e502be3f46ace7a85Lauro Ramos Venancio  DW.BeginModule(&M);
810a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
811b8275a3f6f6497889653cb2452d82a46f92b4926Dan Gohman  bool Result = AsmPrinter::doInitialization(M);
8125411835165429dc409012adc5efaf92c4938563fDale Johannesen
813f2452c5f48e13cf3a9e620d22d5040a90133ddcaDale Johannesen  // AsmPrinter::doInitialization should have done this analysis.
814f2452c5f48e13cf3a9e620d22d5040a90133ddcaDale Johannesen  MMI = getAnalysisToUpdate<MachineModuleInfo>();
815f2452c5f48e13cf3a9e620d22d5040a90133ddcaDale Johannesen  assert(MMI);
816f2452c5f48e13cf3a9e620d22d5040a90133ddcaDale Johannesen  DW.SetModuleInfo(MMI);
817f2452c5f48e13cf3a9e620d22d5040a90133ddcaDale Johannesen
8185411835165429dc409012adc5efaf92c4938563fDale Johannesen  // Darwin wants symbols to be quoted if they have complex names.
8195411835165429dc409012adc5efaf92c4938563fDale Johannesen  if (Subtarget->isTargetDarwin())
8205411835165429dc409012adc5efaf92c4938563fDale Johannesen    Mang->setUseQuotes(true);
8215411835165429dc409012adc5efaf92c4938563fDale Johannesen
822b8275a3f6f6497889653cb2452d82a46f92b4926Dan Gohman  return Result;
8237bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
8247bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
825ec321b4d64ee02a1b90021c09d9513618787c6e8Chris Lattner/// PrintUnmangledNameSafely - Print out the printable characters in the name.
826ec321b4d64ee02a1b90021c09d9513618787c6e8Chris Lattner/// Don't print things like \n or \0.
827ec321b4d64ee02a1b90021c09d9513618787c6e8Chris Lattnerstatic void PrintUnmangledNameSafely(const Value *V, std::ostream &OS) {
828ec321b4d64ee02a1b90021c09d9513618787c6e8Chris Lattner  for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
829ec321b4d64ee02a1b90021c09d9513618787c6e8Chris Lattner       Name != E; ++Name)
830ec321b4d64ee02a1b90021c09d9513618787c6e8Chris Lattner    if (isprint(*Name))
831ec321b4d64ee02a1b90021c09d9513618787c6e8Chris Lattner      OS << *Name;
832ec321b4d64ee02a1b90021c09d9513618787c6e8Chris Lattner}
833ec321b4d64ee02a1b90021c09d9513618787c6e8Chris Lattner
8340f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikovvoid ARMAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
835b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola  const TargetData *TD = TM.getTargetData();
836b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola
8370f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  if (!GVar->hasInitializer())   // External global require no code
8380f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    return;
8390f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
8400f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  // Check to see if this is a special global used by LLVM, if so, emit it.
8410f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
8420f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  if (EmitSpecialLLVMGlobal(GVar)) {
8430f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    if (Subtarget->isTargetDarwin() &&
8440f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov        TM.getRelocationModel() == Reloc::Static) {
8450f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov      if (GVar->getName() == "llvm.global_ctors")
8460f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov        O << ".reference .constructors_used\n";
8470f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov      else if (GVar->getName() == "llvm.global_dtors")
8480f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov        O << ".reference .destructors_used\n";
849b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng    }
8500f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    return;
8510f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  }
8520f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
8530f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  std::string SectionName = TAI->SectionForGlobal(GVar);
8540f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  std::string name = Mang->getValueName(GVar);
8550f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  Constant *C = GVar->getInitializer();
8560f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  const Type *Type = C->getType();
8570f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  unsigned Size = TD->getABITypeSize(Type);
8580f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  unsigned Align = TD->getPreferredAlignmentLog(GVar);
859b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola
8600f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  const char *VisibilityDirective = NULL;
8610f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  if (GVar->hasHiddenVisibility())
8620f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    VisibilityDirective = TAI->getHiddenDirective();
8630f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  else if (GVar->hasProtectedVisibility())
8640f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    VisibilityDirective = TAI->getProtectedDirective();
865b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola
8660f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  if (VisibilityDirective)
8670f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    O << VisibilityDirective << name << "\n";
8680a1817392d3ad7ec2681e6bf495f490c443ec0b7Lauro Ramos Venancio
8690f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  if (Subtarget->isTargetELF())
8700f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    O << "\t.type " << name << ",%object\n";
8710a1817392d3ad7ec2681e6bf495f490c443ec0b7Lauro Ramos Venancio
8720f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  SwitchToDataSection(SectionName.c_str());
8735be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng
8740f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  if (C->isNullValue() && !GVar->hasSection() && !GVar->isThreadLocal()) {
8750f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    // FIXME: This seems to be pretty darwin-specific
8760f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
8770f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    if (GVar->hasExternalLinkage()) {
8780f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov      if (const char *Directive = TAI->getZeroFillDirective()) {
8790f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov        O << "\t.globl\t" << name << "\n";
8800f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov        O << Directive << "__DATA, __common, " << name << ", "
8810f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov          << Size << ", " << Align << "\n";
8820f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov        return;
883a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      }
8845be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    }
8851366626e08322aaecd60704d02a5d881b0826725Rafael Espindola
8860f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    if (GVar->hasInternalLinkage() || GVar->isWeakForLinker()) {
8870f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov      if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
8880f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
8890f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov      if (TAI->getLCOMMDirective() != NULL) {
8900f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov        if (GVar->hasInternalLinkage()) {
8910f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov          O << TAI->getLCOMMDirective() << name << "," << Size;
8920f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov          if (Subtarget->isTargetDarwin())
8930f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov            O << "," << Align;
8940f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov        } else
8950f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov          O << TAI->getCOMMDirective()  << name << "," << Size;
8965be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      } else {
8970f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov        if (GVar->hasInternalLinkage())
8980f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov          O << "\t.local\t" << name << "\n";
8990f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov        O << TAI->getCOMMDirective()  << name << "," << Size;
9000f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov        if (TAI->getCOMMDirectiveTakesAlignment())
9010f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov          O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
9025be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      }
9030f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov      O << "\t\t" << TAI->getCommentString() << " ";
9040f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov      PrintUnmangledNameSafely(GVar, O);
9050f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov      O << "\n";
9060f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov      return;
9075be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    }
9080f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  }
9090f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
9100f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  switch (GVar->getLinkage()) {
9110f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov   case GlobalValue::LinkOnceLinkage:
9120f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov   case GlobalValue::WeakLinkage:
9130f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    if (Subtarget->isTargetDarwin()) {
9140f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov      O << "\t.globl " << name << "\n"
9150f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov        << "\t.weak_definition " << name << "\n";
9160f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    } else {
9170f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov      O << "\t.weak " << name << "\n";
918a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
9190f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    break;
9200f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov   case GlobalValue::AppendingLinkage:
9210f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    // FIXME: appending linkage variables should go into a section of
9220f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    // their name or something.  For now, just emit them as external.
9230f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov   case GlobalValue::ExternalLinkage:
9240f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    O << "\t.globl " << name << "\n";
9250f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    // FALL THROUGH
9260f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov   case GlobalValue::InternalLinkage:
9270f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    break;
9280f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov   default:
9290f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    assert(0 && "Unknown linkage type!");
9300f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    break;
9310f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  }
932b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola
9330f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  EmitAlignment(Align, GVar);
9340f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  O << name << ":\t\t\t\t" << TAI->getCommentString() << " ";
9350f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  PrintUnmangledNameSafely(GVar, O);
9360f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  O << "\n";
9370f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  if (TAI->hasDotTypeDotSizeDirective())
9380f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    O << "\t.size " << name << ", " << Size << "\n";
9390f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
9400f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  // If the initializer is a extern weak symbol, remember to emit the weak
9410f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  // reference!
9420f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
9430f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    if (GV->hasExternalWeakLinkage())
944a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      ExtWeakSymbols.insert(GV);
945a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
9460f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  EmitGlobalConstant(C);
9470f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  O << '\n';
9480f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov}
9490f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
9500f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
9510f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikovbool ARMAsmPrinter::doFinalization(Module &M) {
9520f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov  for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
9530f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov       I != E; ++I)
9540f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov    printModuleLevelGV(I);
955a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
9565be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng  if (Subtarget->isTargetDarwin()) {
9575be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    SwitchToDataSection("");
9585be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng
959a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Output stubs for dynamically-linked functions
960a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    unsigned j = 1;
961a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
962a8e2989ece6dc46df59b0768184028257f913843Evan Cheng         i != e; ++i, ++j) {
963a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      if (TM.getRelocationModel() == Reloc::PIC_)
964a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        SwitchToTextSection(".section __TEXT,__picsymbolstub4,symbol_stubs,"
965a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                            "none,16", 0);
966a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      else
967a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        SwitchToTextSection(".section __TEXT,__symbol_stub4,symbol_stubs,"
968a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                            "none,12", 0);
969a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
970a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      EmitAlignment(2);
971a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\t.code\t32\n";
972a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
973c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen      std::string p = *i;
974c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen      printSuffixedName(p, "$stub");
975c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen      O << ":\n";
976a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\t.indirect_symbol " << *i << "\n";
977c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen      O << "\tldr ip, ";
978c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen      printSuffixedName(p, "$slp");
979c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen      O << "\n";
980a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      if (TM.getRelocationModel() == Reloc::PIC_) {
981c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen        printSuffixedName(p, "$scv");
982c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen        O << ":\n";
983a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        O << "\tadd ip, pc, ip\n";
984a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      }
985a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\tldr pc, [ip, #0]\n";
986c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen      printSuffixedName(p, "$slp");
987c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen      O << ":\n";
988c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen      O << "\t.long\t";
989c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen      printSuffixedName(p, "$lazy_ptr");
990c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen      if (TM.getRelocationModel() == Reloc::PIC_) {
991c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen        O << "-(";
992c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen        printSuffixedName(p, "$scv");
993c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen        O << "+8)\n";
994c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen      } else
995c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen        O << "\n";
996a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      SwitchToDataSection(".lazy_symbol_pointer", 0);
997c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen      printSuffixedName(p, "$lazy_ptr");
998c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen      O << ":\n";
999a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\t.indirect_symbol " << *i << "\n";
1000a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\t.long\tdyld_stub_binding_helper\n";
1001a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
1002a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "\n";
1003a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1004a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Output non-lazy-pointers for external and common global variables.
1005cb406c25973b4e88a6c10ad839ef1beeb3664715Dan Gohman    if (!GVNonLazyPtrs.empty())
1006a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      SwitchToDataSection(".non_lazy_symbol_pointer", 0);
1007a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    for (std::set<std::string>::iterator i = GVNonLazyPtrs.begin(),
1008a8e2989ece6dc46df59b0768184028257f913843Evan Cheng           e = GVNonLazyPtrs.end(); i != e; ++i) {
1009c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen      std::string p = *i;
1010c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen      printSuffixedName(p, "$non_lazy_ptr");
1011c215b3ef5d9627f5fb6fe9034e46bc29ae592916Dale Johannesen      O << ":\n";
1012a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\t.indirect_symbol " << *i << "\n";
1013a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\t.long\t0\n";
1014a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
1015a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1016a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Emit initial debug information.
1017a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    DW.EndModule();
1018a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1019a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Funny Darwin hack: This flag tells the linker that no global symbols
1020a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // contain code that falls through to other global symbols (e.g. the obvious
1021a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // implementation of multiple entry points).  If this doesn't occur, the
1022a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // linker can safely perform dead code stripping.  Since LLVM never
1023a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // generates code that does this, it is always safe to set.
1024a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "\t.subsections_via_symbols\n";
1025e8e5495474d67cd5151bd88e502be3f46ace7a85Lauro Ramos Venancio  } else {
1026e8e5495474d67cd5151bd88e502be3f46ace7a85Lauro Ramos Venancio    // Emit final debug information for ELF.
1027e8e5495474d67cd5151bd88e502be3f46ace7a85Lauro Ramos Venancio    DW.EndModule();
1028b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola  }
1029b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola
1030b8275a3f6f6497889653cb2452d82a46f92b4926Dan Gohman  return AsmPrinter::doFinalization(M);
10317bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1032