ARMAsmPrinter.cpp revision 0ae4a3357a556261f25b1584a2d9914637c69e65
17bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===-- ARMAsmPrinter.cpp - ARM LLVM assembly writer ----------------------===//
27bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
37bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//                     The LLVM Compiler Infrastructure
47bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
57bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// This file was developed by the "Instituto Nokia de Tecnologia" and
67bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// is distributed under the University of Illinois Open Source
77bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// License. See LICENSE.TXT for details.
87bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
97bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===//
107bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
117bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// This file contains a printer that converts from our internal representation
127bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola// of machine-dependent LLVM code to GAS-format ARM assembly language.
137bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//
147bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola//===----------------------------------------------------------------------===//
157bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1695b2c7da5e83670881270c1cd231a240be0556d9Chris Lattner#define DEBUG_TYPE "asm-printer"
177bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARM.h"
18a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMTargetMachine.h"
19a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMAddressingModes.h"
20a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMConstantPoolValue.h"
21a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMMachineFunctionInfo.h"
227bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Constants.h"
237bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Module.h"
247bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/AsmPrinter.h"
25a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/DwarfWriter.h"
2644c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey#include "llvm/CodeGen/MachineModuleInfo.h"
277bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h"
28a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h"
29563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey#include "llvm/Target/TargetAsmInfo.h"
30b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h"
317bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h"
325be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng#include "llvm/Target/TargetOptions.h"
337bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/ADT/Statistic.h"
347bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/ADT/StringExtras.h"
35a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/Support/Compiler.h"
36a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/Support/Mangler.h"
377bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Support/MathExtras.h"
387bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype>
397bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm;
407bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
4195b2c7da5e83670881270c1cd231a240be0556d9Chris LattnerSTATISTIC(EmittedInsts, "Number of machine instrs printed");
427bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
4395b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace {
44563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey  struct VISIBILITY_HIDDEN ARMAsmPrinter : public AsmPrinter {
45a0f3d17daac73c9c71aad497b298cbe82848f726Jim Laskey    ARMAsmPrinter(std::ostream &O, TargetMachine &TM, const TargetAsmInfo *T)
46a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      : AsmPrinter(O, TM, T), DW(O, this, T), AFI(NULL), InCPMode(false) {
47a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      Subtarget = &TM.getSubtarget<ARMSubtarget>();
48563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey    }
497bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
50a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    DwarfWriter DW;
51a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
52a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
53a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// make the right decision when printing asm code for different targets.
54a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    const ARMSubtarget *Subtarget;
55a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
56a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// AFI - Keep a pointer to ARMFunctionInfo for the current
57a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// MachineFunction
58a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    ARMFunctionInfo *AFI;
59a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
607bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    /// We name each basic block in a Function with a unique number, so
617bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    /// that we can consistently refer to them later. This is cleared
627bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    /// at the beginning of each call to runOnMachineFunction().
637bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    ///
647bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    typedef std::map<const Value *, unsigned> ValueMapTy;
657bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    ValueMapTy NumberForBB;
667bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
67a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// Keeps the set of GlobalValues that require non-lazy-pointers for
68a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// indirect access.
69a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    std::set<std::string> GVNonLazyPtrs;
70a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
71a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// Keeps the set of external function GlobalAddresses that the asm
72a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// printer should generate stubs for.
73a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    std::set<std::string> FnStubs;
74a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
75a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// True if asm printer is printing a series of CONSTPOOL_ENTRY.
76a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    bool InCPMode;
77a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
787bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    virtual const char *getPassName() const {
797bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola      return "ARM Assembly Printer";
807bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    }
817bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
82a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printOperand(const MachineInstr *MI, int opNum,
83a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                      const char *Modifier = 0);
84a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printSOImmOperand(const MachineInstr *MI, int opNum);
85c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng    void printSOImm2PartOperand(const MachineInstr *MI, int opNum);
86a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printSORegOperand(const MachineInstr *MI, int opNum);
87a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printAddrMode2Operand(const MachineInstr *MI, int OpNo);
88a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNo);
89a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printAddrMode3Operand(const MachineInstr *MI, int OpNo);
90a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printAddrMode3OffsetOperand(const MachineInstr *MI, int OpNo);
91a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printAddrMode4Operand(const MachineInstr *MI, int OpNo,
92a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                               const char *Modifier = 0);
93a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printAddrMode5Operand(const MachineInstr *MI, int OpNo,
94a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                               const char *Modifier = 0);
95a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printAddrModePCOperand(const MachineInstr *MI, int OpNo,
96a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                const char *Modifier = 0);
97a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNo);
98a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNo,
99a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                      unsigned Scale);
100c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan Cheng    void printThumbAddrModeS1Operand(const MachineInstr *MI, int OpNo);
101c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan Cheng    void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNo);
102c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan Cheng    void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNo);
103a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNo);
1047bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    void printCCOperand(const MachineInstr *MI, int opNum);
105a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printPCLabel(const MachineInstr *MI, int opNum);
106a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printRegisterList(const MachineInstr *MI, int opNum);
107a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printCPInstOperand(const MachineInstr *MI, int opNum,
108a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                            const char *Modifier);
109a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printJTBlockOperand(const MachineInstr *MI, int opNum);
110a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
111a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
112a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                 unsigned AsmVariant, const char *ExtraCode);
1137bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1147bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    bool printInstruction(const MachineInstr *MI);  // autogenerated.
115a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void printMachineInstruction(const MachineInstr *MI);
1167bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    bool runOnMachineFunction(MachineFunction &F);
1177bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    bool doInitialization(Module &M);
1187bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    bool doFinalization(Module &M);
119a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
120a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
121a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      printDataDirective(MCPV->getType());
122a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
123a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      ARMConstantPoolValue *ACPV = (ARMConstantPoolValue*)MCPV;
1241a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio      GlobalValue *GV = ACPV->getGV();
125c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng      std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix();
126c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng      if (!GV)
127c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng        Name += ACPV->getSymbol();
128a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      if (ACPV->isNonLazyPointer()) {
129a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        GVNonLazyPtrs.insert(Name);
130a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        O << TAI->getPrivateGlobalPrefix() << Name << "$non_lazy_ptr";
131c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng      } else if (ACPV->isStub()) {
132c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng        FnStubs.insert(Name);
133c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng        O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
134a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      } else
135a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        O << Name;
1360ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
137a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      if (ACPV->getPCAdjustment() != 0)
138a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        O << "-(" << TAI->getPrivateGlobalPrefix() << "PC"
139a8e2989ece6dc46df59b0768184028257f913843Evan Cheng          << utostr(ACPV->getLabelId())
140a8e2989ece6dc46df59b0768184028257f913843Evan Cheng          << "+" << (unsigned)ACPV->getPCAdjustment() << ")";
141a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\n";
1421a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio
1431a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio      // If the constant pool value is a extern weak symbol, remember to emit
1441a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio      // the weak reference.
145c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng      if (GV && GV->hasExternalWeakLinkage())
1461a92d941b3541f0c361caad499d0eb37a8339453Lauro Ramos Venancio        ExtWeakSymbols.insert(GV);
147a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
148a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
149a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    void getAnalysisUsage(AnalysisUsage &AU) const {
150a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      AU.setPreservesAll();
15144c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey      AU.addRequired<MachineModuleInfo>();
152a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
1537bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  };
1547bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace
1557bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1567bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMGenAsmWriter.inc"
1577bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1587bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// createARMCodePrinterPass - Returns a pass that prints the ARM
1597bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// assembly code for a MachineFunction to the given output stream,
1607bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// using the given target machine description.  This should work
1617bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// regardless of whether the function is in SSA form.
1627bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola///
1637bc59bc3952ad7842b1e079753deb32217a768a3Rafael EspindolaFunctionPass *llvm::createARMCodePrinterPass(std::ostream &o,
164a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                             ARMTargetMachine &tm) {
165a0f3d17daac73c9c71aad497b298cbe82848f726Jim Laskey  return new ARMAsmPrinter(o, tm, tm.getTargetAsmInfo());
1667bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
1677bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
168a8e2989ece6dc46df59b0768184028257f913843Evan Cheng/// runOnMachineFunction - This uses the printInstruction()
1697bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction.
1707bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola///
1717bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
172a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  AFI = MF.getInfo<ARMFunctionInfo>();
173a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1745be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng  if (Subtarget->isTargetDarwin()) {
17544c3b9fdd416c79f4b67cde1aecfced5921efd81Jim Laskey    DW.SetModuleInfo(&getAnalysis<MachineModuleInfo>());
1761a199de81322a844faee0ea242f68fe326bbd885Chris Lattner  }
1771a199de81322a844faee0ea242f68fe326bbd885Chris Lattner
178a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  SetupMachineFunction(MF);
179a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "\n";
180a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
181a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // NOTE: we don't print out constant pools here, they are handled as
182a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // instructions.
1834b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola
184a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "\n";
1854b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  // Print out labels for the function.
1864b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  const Function *F = MF.getFunction();
1874b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  switch (F->getLinkage()) {
1884b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  default: assert(0 && "Unknown linkage type!");
1894b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  case Function::InternalLinkage:
190a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    SwitchToTextSection("\t.text", F);
1914b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    break;
1924b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  case Function::ExternalLinkage:
193a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    SwitchToTextSection("\t.text", F);
1944b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    O << "\t.globl\t" << CurrentFnName << "\n";
1954b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    break;
1964b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  case Function::WeakLinkage:
1974b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  case Function::LinkOnceLinkage:
1985be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    if (Subtarget->isTargetDarwin()) {
199a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      SwitchToTextSection(
200a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                ".section __TEXT,__textcoal_nt,coalesced,pure_instructions", F);
201a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\t.globl\t" << CurrentFnName << "\n";
202a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\t.weak_definition\t" << CurrentFnName << "\n";
203a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    } else {
204a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << TAI->getWeakRefDirective() << CurrentFnName << "\n";
205a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
2064b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    break;
2074b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  }
208a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
209616cc663daf965695809213d8cf8e3686e5309c3Evan Cheng  if (F->hasHiddenVisibility())
210616cc663daf965695809213d8cf8e3686e5309c3Evan Cheng    if (const char *Directive = TAI->getHiddenDirective())
211616cc663daf965695809213d8cf8e3686e5309c3Evan Cheng      O << Directive << CurrentFnName << "\n";
212616cc663daf965695809213d8cf8e3686e5309c3Evan Cheng
213a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (AFI->isThumbFunction()) {
214a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    EmitAlignment(1, F);
215a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "\t.code\t16\n";
2166f46e59d2a0e66f3646db9677258876960477f87Lauro Ramos Venancio    O << "\t.thumb_func";
2176f46e59d2a0e66f3646db9677258876960477f87Lauro Ramos Venancio    if (Subtarget->isTargetDarwin())
2186f46e59d2a0e66f3646db9677258876960477f87Lauro Ramos Venancio      O << "\t" << CurrentFnName;
2196f46e59d2a0e66f3646db9677258876960477f87Lauro Ramos Venancio    O << "\n";
220a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    InCPMode = false;
221a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else
222a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    EmitAlignment(2, F);
223a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
2244b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  O << CurrentFnName << ":\n";
2255be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng  if (Subtarget->isTargetDarwin()) {
226a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Emit pre-function debug information.
227a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    DW.BeginFunction(&MF);
228a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
2294b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola
2304b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  // Print out code for the function.
2314b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola  for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
2324b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola       I != E; ++I) {
2334b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    // Print a label for the basic block.
2344b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    if (I != MF.begin()) {
2354b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola      printBasicBlockLabel(I, true);
2364b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola      O << '\n';
2374b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    }
2384b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola    for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
2394b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola         II != E; ++II) {
2404b442b528a50ef06cd75f0e7c41ad57426175bccRafael Espindola      // Print the assembly for the instruction.
241a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      printMachineInstruction(II);
2423ad5e5cf998841681e9d11e08eb82a94ddffd1f8Rafael Espindola    }
2437cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola  }
2447cca7c531773f763c1bddc3fefecc99ba56ed10aRafael Espindola
245a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (TAI->hasDotTypeDotSizeDirective())
246a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "\t.size " << CurrentFnName << ", .-" << CurrentFnName << "\n";
2476e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola
2485be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng  if (Subtarget->isTargetDarwin()) {
249a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Emit post-function debug information.
250a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    DW.EndFunction();
2516e8c6493f0db238d06549368bd647e29ff3c7821Rafael Espindola  }
25232bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola
253a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  return false;
25432bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola}
25532bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola
256a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
257a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                 const char *Modifier) {
258a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO = MI->getOperand(opNum);
2592f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  switch (MO.getType()) {
2602f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_Register:
2612f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
262a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << TM.getRegisterInfo()->get(MO.getReg()).Name;
2632f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    else
2642f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola      assert(0 && "not implemented");
2652f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
266a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_Immediate: {
267a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (!Modifier || strcmp(Modifier, "no_hash") != 0)
268a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "#";
269a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
270a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << (int)MO.getImmedValue();
2712f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
272a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
2732f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_MachineBasicBlock:
274687bc49d1ada3fe0a2cd3fb5c044f12d267f259fRafael Espindola    printBasicBlockLabel(MO.getMachineBasicBlock());
2752f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    return;
27684b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola  case MachineOperand::MO_GlobalAddress: {
277a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    bool isCallOp = Modifier && !strcmp(Modifier, "call");
27884b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola    GlobalValue *GV = MO.getGlobal();
27984b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola    std::string Name = Mang->getValueName(GV);
2805cbf985dcbc89fba3208e7baf8b6f488b06d3ec9Reid Spencer    bool isExt = (GV->isDeclaration() || GV->hasWeakLinkage() ||
281a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                  GV->hasLinkOnceLinkage());
2825be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    if (isExt && isCallOp && Subtarget->isTargetDarwin() &&
283a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        TM.getRelocationModel() != Reloc::Static) {
284a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
285a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      FnStubs.insert(Name);
286a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    } else
287a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << Name;
2880ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio    if (isCallOp && Subtarget->isTargetELF() &&
2890ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio        TM.getRelocationModel() == Reloc::PIC_)
2900ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
291a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (GV->hasExternalWeakLinkage())
29215404d060ba8b604c03b9223a0f2e2abcd0fddedRafael Espindola      ExtWeakSymbols.insert(GV);
2932f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
294a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
295a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_ExternalSymbol: {
296a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    bool isCallOp = Modifier && !strcmp(Modifier, "call");
297a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    std::string Name(TAI->getGlobalPrefix());
298a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    Name += MO.getSymbolName();
2995be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    if (isCallOp && Subtarget->isTargetDarwin() &&
300a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        TM.getRelocationModel() != Reloc::Static) {
301a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
302a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      FnStubs.insert(Name);
303a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    } else
304a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << Name;
3050ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio    if (isCallOp && Subtarget->isTargetELF() &&
3060ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio        TM.getRelocationModel() == Reloc::PIC_)
3070ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
3082f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
309a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
3102f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_ConstantPoolIndex:
311563321a2582851c653d0863e8e0bba3d483734f9Jim Laskey    O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
31206c1e7eacb11edd1671eabfc11291b7716be2608Rafael Espindola      << '_' << MO.getConstantPoolIndex();
3132f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
314a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_JumpTableIndex:
315a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
316a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << '_' << MO.getJumpTableIndex();
317a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    break;
3182f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  default:
3192f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    O << "<unknown operand type>"; abort (); break;
3202f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  }
3217bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
3227bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
323c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Chengstatic void printSOImm(std::ostream &O, int64_t V, const TargetAsmInfo *TAI) {
324c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  assert(V < (1 << 12) && "Not a valid so_imm value!");
325c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  unsigned Imm = ARM_AM::getSOImmValImm(V);
326c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  unsigned Rot = ARM_AM::getSOImmValRot(V);
327a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
328a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Print low-level immediate formation info, per
329a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // A5.1.3: "Data-processing operands - Immediate".
330a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Rot) {
331a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "#" << Imm << ", " << Rot;
332a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Pretty printed version.
333a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ' ' << TAI->getCommentString() << ' ' << (int)ARM_AM::rotr32(Imm, Rot);
334a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
335a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "#" << Imm;
336a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
337a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
338a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
339c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
340c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// immediate in bits 0-7.
341c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Chengvoid ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) {
342c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
343c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  assert(MO.isImmediate() && "Not a valid so_imm value!");
344c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  printSOImm(O, MO.getImmedValue(), TAI);
345c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng}
346c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng
347c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// printSOImm2PartOperand - SOImm is broken into two pieces using a mov
348c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// followed by a or to materialize.
349c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Chengvoid ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) {
350c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
351c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  assert(MO.isImmediate() && "Not a valid so_imm value!");
352c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImmedValue());
353c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImmedValue());
354c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  printSOImm(O, ARM_AM::getSOImmVal(V1), TAI);
355c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  O << "\n\torr ";
356c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  printOperand(MI, 0);
357c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  O << ", ";
358c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  printOperand(MI, 0);
359c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  O << ", ";
360c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  printSOImm(O, ARM_AM::getSOImmVal(V2), TAI);
361c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng}
362c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng
363a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// so_reg is a 4-operand unit corresponding to register forms of the A5.1
364a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// "Addressing Mode 1 - Data-processing operands" forms.  This includes:
365a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//    REG 0   0    - e.g. R5
366a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//    REG REG 0,SH_OPC     - e.g. R5, ROR R3
367a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
368a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op) {
369a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
370a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
371a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
372a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
373a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
374a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << TM.getRegisterInfo()->get(MO1.getReg()).Name;
375a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
376a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Print the shift opc.
377a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << ", "
378a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImmedValue()))
379a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    << " ";
380a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
381a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (MO2.getReg()) {
382a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    assert(MRegisterInfo::isPhysicalRegister(MO2.getReg()));
383a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << TM.getRegisterInfo()->get(MO2.getReg()).Name;
384a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
385a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
386a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "#" << ARM_AM::getSORegOffset(MO3.getImm());
387a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
388a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
389a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
390a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op) {
391a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
392a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
393a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
394a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
395a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!MO1.isRegister()) {   // FIXME: This is for CP entries, but isn't right.
396a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    printOperand(MI, Op);
397a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
398a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
399a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
400a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
401a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
402a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!MO2.getReg()) {
403a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ARM_AM::getAM2Offset(MO3.getImm()))  // Don't print +0.
404a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << ", #"
405a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        << (char)ARM_AM::getAM2Op(MO3.getImm())
406a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        << ARM_AM::getAM2Offset(MO3.getImm());
407a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "]";
408a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
409a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
410a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
411a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << ", "
412a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    << (char)ARM_AM::getAM2Op(MO3.getImm())
413a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    << TM.getRegisterInfo()->get(MO2.getReg()).Name;
414a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
415a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
416a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", "
417a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImmedValue()))
418a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << " #" << ShImm;
419a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
420a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
421a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
422a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op){
423a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
424a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
425a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
426a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!MO1.getReg()) {
427a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ARM_AM::getAM2Offset(MO2.getImm()))  // Don't print +0.
428a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "#"
429a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        << (char)ARM_AM::getAM2Op(MO2.getImm())
430a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        << ARM_AM::getAM2Offset(MO2.getImm());
431a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
432a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
433a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
434a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << (char)ARM_AM::getAM2Op(MO2.getImm())
435a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    << TM.getRegisterInfo()->get(MO1.getReg()).Name;
436a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
437a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
438a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", "
439a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImmedValue()))
440a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << " #" << ShImm;
441a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
442a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
443a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op) {
444a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
445a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
446a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
447a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
448a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
449a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
450a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
451a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (MO2.getReg()) {
452a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", "
453a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << (char)ARM_AM::getAM3Op(MO3.getImm())
454a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << TM.getRegisterInfo()->get(MO2.getReg()).Name
455a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << "]";
456a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
457a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
458a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
459a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
460a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", #"
461a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << (char)ARM_AM::getAM3Op(MO3.getImm())
462a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << ImmOffs;
463a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
464a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
465a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
466a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op){
467a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
468a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
469a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
470a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (MO1.getReg()) {
471a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << (char)ARM_AM::getAM3Op(MO2.getImm())
472a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << TM.getRegisterInfo()->get(MO1.getReg()).Name;
473a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
474a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
475a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
476a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
477a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "#"
478a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  << (char)ARM_AM::getAM3Op(MO2.getImm())
479a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    << ImmOffs;
480a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
481a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
482a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
483a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                          const char *Modifier) {
484a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
485a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
486a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
487a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Modifier && strcmp(Modifier, "submode") == 0) {
488a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (MO1.getReg() == ARM::SP) {
489a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      bool isLDM = (MI->getOpcode() == ARM::LDM ||
490a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                    MI->getOpcode() == ARM::LDM_RET);
491a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << ARM_AM::getAMSubModeAltStr(Mode, isLDM);
492a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    } else
493a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << ARM_AM::getAMSubModeStr(Mode);
494a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
495a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    printOperand(MI, Op);
496a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ARM_AM::getAM4WBFlag(MO2.getImm()))
497a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "!";
498a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
499a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
500a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
501a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
502a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                          const char *Modifier) {
503a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
504a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
505a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
506a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!MO1.isRegister()) {   // FIXME: This is for CP entries, but isn't right.
507a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    printOperand(MI, Op);
508a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
509a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
510a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
511a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
512a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
513a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Modifier && strcmp(Modifier, "submode") == 0) {
514a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MO2.getImm());
515a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (MO1.getReg() == ARM::SP) {
516a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      bool isFLDM = (MI->getOpcode() == ARM::FLDMD ||
517a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                     MI->getOpcode() == ARM::FLDMS);
518a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << ARM_AM::getAMSubModeAltStr(Mode, isFLDM);
519a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    } else
520a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << ARM_AM::getAMSubModeStr(Mode);
521a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
522a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else if (Modifier && strcmp(Modifier, "base") == 0) {
523a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Used for FSTM{D|S} and LSTM{D|S} operations.
524a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << TM.getRegisterInfo()->get(MO1.getReg()).Name;
525a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ARM_AM::getAM5WBFlag(MO2.getImm()))
526a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "!";
527a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
528a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
529a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
530a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
531a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
532a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
533a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", #"
534a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << (char)ARM_AM::getAM5Op(MO2.getImm())
535a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << ImmOffs*4;
536a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
537a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
538a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
539a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
540a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
541a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                           const char *Modifier) {
542a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Modifier && strcmp(Modifier, "label") == 0) {
543a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    printPCLabel(MI, Op+1);
544a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
545a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
546a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
547a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
548a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
549a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "[pc, +" << TM.getRegisterInfo()->get(MO1.getReg()).Name << "]";
550a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
551a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
552a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
553a8e2989ece6dc46df59b0768184028257f913843Evan ChengARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op) {
554a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
555a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
556a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
557a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << ", " << TM.getRegisterInfo()->get(MO2.getReg()).Name << "]";
558a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
559a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
560a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
561a8e2989ece6dc46df59b0768184028257f913843Evan ChengARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
562a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                            unsigned Scale) {
563a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
564cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
565cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
566a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
567a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!MO1.isRegister()) {   // FIXME: This is for CP entries, but isn't right.
568a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    printOperand(MI, Op);
569a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
570a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
571a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
572a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
573cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  if (MO3.getReg())
574cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng    O << ", " << TM.getRegisterInfo()->get(MO3.getReg()).Name;
575cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  else if (unsigned ImmOffs = MO2.getImm()) {
576a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", #" << ImmOffs;
577a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (Scale > 1)
578a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << " * " << Scale;
579a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
580a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
581a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
582a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
583a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
584c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan ChengARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op) {
585cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  printThumbAddrModeRI5Operand(MI, Op, 1);
586a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
587a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
588c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan ChengARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op) {
589cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  printThumbAddrModeRI5Operand(MI, Op, 2);
590a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
591a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
592c38f2bc3c29337f777c48b33daa8b1d6c76c27bfEvan ChengARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op) {
593cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  printThumbAddrModeRI5Operand(MI, Op, 4);
594a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
595a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
596a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) {
597a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
598a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
599a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
600a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ImmOffs = MO2.getImm())
601a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", #" << ImmOffs << " * 4";
602a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
6037bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
6047bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
6057bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolavoid ARMAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
6066f602de3b68cc63d12554ad6ae3c98a4c436c32dRafael Espindola  int CC = (int)MI->getOperand(opNum).getImmedValue();
6076f602de3b68cc63d12554ad6ae3c98a4c436c32dRafael Espindola  O << ARMCondCodeToString((ARMCC::CondCodes)CC);
6087bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
6097bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
610a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int opNum) {
611a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  int Id = (int)MI->getOperand(opNum).getImmedValue();
612a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << TAI->getPrivateGlobalPrefix() << "PC" << Id;
613a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
614a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
615a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int opNum) {
616a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "{";
617a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  for (unsigned i = opNum, e = MI->getNumOperands(); i != e; ++i) {
618a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    printOperand(MI, i);
619a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (i != e-1) O << ", ";
620a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
621a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "}";
622a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
623a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
624a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNo,
625a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                       const char *Modifier) {
626a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  assert(Modifier && "This operand only works with a modifier!");
627a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
628a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // data itself.
629a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!strcmp(Modifier, "label")) {
630a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    unsigned ID = MI->getOperand(OpNo).getImm();
631a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
632a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << '_' << ID << ":\n";
633a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
634a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
635a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    unsigned CPI = MI->getOperand(OpNo).getConstantPoolIndex();
636a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
637a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    const MachineConstantPoolEntry &MCPE =  // Chasing pointers is fun?
638a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      MI->getParent()->getParent()->getConstantPool()->getConstants()[CPI];
639a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
640a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (MCPE.isMachineConstantPoolEntry())
641a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
642a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    else
643a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      EmitGlobalConstant(MCPE.Val.ConstVal);
644a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
645a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
646a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
647a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNo) {
648a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNo);
649a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNo+1); // Unique Id
650a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  unsigned JTI = MO1.getJumpTableIndex();
651a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
652a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    << '_' << JTI << '_' << MO2.getImmedValue() << ":\n";
653a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
654a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const char *JTEntryDirective = TAI->getJumpTableDirective();
655a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!JTEntryDirective)
656a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    JTEntryDirective = TAI->getData32bitsDirective();
657a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
658a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineFunction *MF = MI->getParent()->getParent();
659a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
660a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
661a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
662a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  bool UseSet= TAI->getSetDirective() && TM.getRelocationModel() == Reloc::PIC_;
663a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  std::set<MachineBasicBlock*> JTSets;
664a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
665a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    MachineBasicBlock *MBB = JTBBs[i];
666a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (UseSet && JTSets.insert(MBB).second)
667a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      printSetLabel(JTI, MO2.getImmedValue(), MBB);
668a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
669a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << JTEntryDirective << ' ';
670a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (UseSet)
671a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
672a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        << '_' << JTI << '_' << MO2.getImmedValue()
673a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        << "_set_" << MBB->getNumber();
674a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    else if (TM.getRelocationModel() == Reloc::PIC_) {
675a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      printBasicBlockLabel(MBB, false, false);
676a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      // If the arch uses custom Jump Table directives, don't calc relative to JT
677a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      if (!TAI->getJumpTableDirective())
678a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        O << '-' << TAI->getPrivateGlobalPrefix() << "JTI"
679a8e2989ece6dc46df59b0768184028257f913843Evan Cheng          << getFunctionNumber() << '_' << JTI << '_' << MO2.getImmedValue();
680a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    } else
681a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      printBasicBlockLabel(MBB, false, false);
682d85ac4d07966a56b3101598f29393f4532acc50fEvan Cheng    if (i != e-1)
683d85ac4d07966a56b3101598f29393f4532acc50fEvan Cheng      O << '\n';
684a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
685a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
686a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
687a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
688a8e2989ece6dc46df59b0768184028257f913843Evan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
689a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                    unsigned AsmVariant, const char *ExtraCode){
690a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Does this asm operand have a single letter operand modifier?
691a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (ExtraCode && ExtraCode[0]) {
692a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ExtraCode[1] != 0) return true; // Unknown modifier.
693a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
694a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    switch (ExtraCode[0]) {
695a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    default: return true;  // Unknown modifier.
69623a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng    case 'c': // Don't print "$" before a global var name or constant.
697e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng    case 'P': // Print a VFP double precision register.
69823a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng      printOperand(MI, OpNo);
69923a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng      return false;
700a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'Q':
701a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      if (TM.getTargetData()->isLittleEndian())
702a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        break;
703a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      // Fallthrough
704a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'R':
705a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      if (TM.getTargetData()->isBigEndian())
706a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        break;
707a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      // Fallthrough
708a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'H': // Write second word of DI / DF reference.
709a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      // Verify that this operand has two consecutive registers.
710a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      if (!MI->getOperand(OpNo).isRegister() ||
711a8e2989ece6dc46df59b0768184028257f913843Evan Cheng          OpNo+1 == MI->getNumOperands() ||
712a8e2989ece6dc46df59b0768184028257f913843Evan Cheng          !MI->getOperand(OpNo+1).isRegister())
713a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        return true;
714a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      ++OpNo;   // Return the high-part.
715a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
716a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
717a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
718a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  printOperand(MI, OpNo);
719a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  return false;
720a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
721a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
722a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
723a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  ++EmittedInsts;
724a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
725c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng  int Opc = MI->getOpcode();
726c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng  switch (Opc) {
727c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng  case ARM::CONSTPOOL_ENTRY:
728a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (!InCPMode && AFI->isThumbFunction()) {
729a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      EmitAlignment(2);
730a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      InCPMode = true;
731a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
732c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng    break;
733c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng  default: {
7343bf12d0460cc6dcd5ad9375be9a2b05535b002a6Evan Cheng    if (InCPMode && AFI->isThumbFunction())
735a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      InCPMode = false;
736c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng    switch (Opc) {
737c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng    case ARM::PICADD:
738c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng    case ARM::PICLD:
739c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng    case ARM::tPICADD:
740c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng      break;
741c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng    default:
742c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng      O << "\t";
743c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng      break;
744c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng    }
745c60e76d139a96cc8bb7454929172cdb992e16971Evan Cheng  }}
746a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
747a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Call the autogenerated instruction printer routines.
748a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  printInstruction(MI);
749a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
750a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
7517bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::doInitialization(Module &M) {
7525be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng  if (Subtarget->isTargetDarwin()) {
753a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Emit initial debug information.
754a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    DW.BeginModule(&M);
755a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
756a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
757a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  return AsmPrinter::doInitialization(M);
7587bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
7597bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
7607bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::doFinalization(Module &M) {
761b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola  const TargetData *TD = TM.getTargetData();
762b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola
763b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola  for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
764b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola       I != E; ++I) {
765b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola    if (!I->hasInitializer())   // External global require no code
766b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola      continue;
767b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola
768b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng    if (EmitSpecialLLVMGlobal(I)) {
769b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng      if (Subtarget->isTargetDarwin() &&
770b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng          TM.getRelocationModel() == Reloc::Static) {
771b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng        if (I->getName() == "llvm.global_ctors")
772b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng          O << ".reference .constructors_used\n";
773b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng        else if (I->getName() == "llvm.global_dtors")
774b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng          O << ".reference .destructors_used\n";
775b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng      }
776b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola      continue;
777b267ca17d1351b28d597e7807b5ed398e92d65e4Evan Cheng    }
778b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola
779b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola    std::string name = Mang->getValueName(I);
780b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola    Constant *C = I->getInitializer();
78198ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng    const Type *Type = C->getType();
78298ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng    unsigned Size = TD->getTypeSize(Type);
783a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    unsigned Align = TD->getPreferredAlignmentLog(I);
784b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola
7855be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    if (I->hasHiddenVisibility())
7865be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      if (const char *Directive = TAI->getHiddenDirective())
7875be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        O << Directive << name << "\n";
7885be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    if (Subtarget->isTargetELF())
789b1cc0528232a732b337a4ba2eb0ba64d7538f1efLauro Ramos Venancio      O << "\t.type " << name << ",%object\n";
7905be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng
7915be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    if (C->isNullValue()) {
792a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      if (I->hasExternalLinkage()) {
7935be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        if (const char *Directive = TAI->getZeroFillDirective()) {
794a8e2989ece6dc46df59b0768184028257f913843Evan Cheng          O << "\t.globl\t" << name << "\n";
7955be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng          O << Directive << "__DATA__, __common, " << name << ", "
7965be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng            << Size << ", " << Align << "\n";
7975be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng          continue;
7985be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        }
7995be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      }
8005be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng
8015be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      if (!I->hasSection() &&
8025be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng          (I->hasInternalLinkage() || I->hasWeakLinkage() ||
8035be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng           I->hasLinkOnceLinkage())) {
8045be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
8055be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        if (!NoZerosInBSS && TAI->getBSSSection())
8065be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng          SwitchToDataSection(TAI->getBSSSection(), I);
8075be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        else
8085be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng          SwitchToDataSection(TAI->getDataSection(), I);
809a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        if (TAI->getLCOMMDirective() != NULL) {
810a8e2989ece6dc46df59b0768184028257f913843Evan Cheng          if (I->hasInternalLinkage()) {
811a8e2989ece6dc46df59b0768184028257f913843Evan Cheng            O << TAI->getLCOMMDirective() << name << "," << Size;
8125be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng            if (Subtarget->isTargetDarwin())
813a8e2989ece6dc46df59b0768184028257f913843Evan Cheng              O << "," << Align;
814a8e2989ece6dc46df59b0768184028257f913843Evan Cheng          } else
815a8e2989ece6dc46df59b0768184028257f913843Evan Cheng            O << TAI->getCOMMDirective()  << name << "," << Size;
816a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        } else {
817a8e2989ece6dc46df59b0768184028257f913843Evan Cheng          if (I->hasInternalLinkage())
818a8e2989ece6dc46df59b0768184028257f913843Evan Cheng            O << "\t.local\t" << name << "\n";
819a8e2989ece6dc46df59b0768184028257f913843Evan Cheng          O << TAI->getCOMMDirective()  << name << "," << Size;
820a8e2989ece6dc46df59b0768184028257f913843Evan Cheng          if (TAI->getCOMMDirectiveTakesAlignment())
821a8e2989ece6dc46df59b0768184028257f913843Evan Cheng            O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
822a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        }
8235be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        O << "\t\t" << TAI->getCommentString() << " " << I->getName() << "\n";
8245be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        continue;
825a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      }
8265be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    }
8271366626e08322aaecd60704d02a5d881b0826725Rafael Espindola
8285be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    switch (I->getLinkage()) {
8295be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    case GlobalValue::LinkOnceLinkage:
8305be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    case GlobalValue::WeakLinkage:
8315be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      if (Subtarget->isTargetDarwin()) {
8325be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        O << "\t.globl " << name << "\n"
8335be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng          << "\t.weak_definition " << name << "\n";
8345be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        SwitchToDataSection("\t.section __DATA,__const_coal,coalesced", I);
8355be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      } else {
8365be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        std::string SectionName("\t.section\t.llvm.linkonce.d." +
8375be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng                                name +
8385be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng                                ",\"aw\",%progbits");
8395be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        SwitchToDataSection(SectionName.c_str(), I);
8405be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        O << "\t.weak " << name << "\n";
8415be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      }
8425be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      break;
8435be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    case GlobalValue::AppendingLinkage:
8445be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      // FIXME: appending linkage variables should go into a section of
8455be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      // their name or something.  For now, just emit them as external.
8465be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    case GlobalValue::ExternalLinkage:
8475be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      O << "\t.globl " << name << "\n";
8485be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      // FALL THROUGH
8495be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    case GlobalValue::InternalLinkage: {
8505be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      if (I->isConstant()) {
8515be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
8525be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        if (TAI->getCStringSection() && CVA && CVA->isCString()) {
8535be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng          SwitchToDataSection(TAI->getCStringSection(), I);
8545be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng          break;
855a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        }
8561366626e08322aaecd60704d02a5d881b0826725Rafael Espindola      }
8575be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      // FIXME: special handling for ".ctors" & ".dtors" sections
8585be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      if (I->hasSection() &&
8595be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng          (I->getSection() == ".ctors" ||
8605be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng           I->getSection() == ".dtors")) {
8615be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        assert(!Subtarget->isTargetDarwin());
8625be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        std::string SectionName = ".section " + I->getSection();
8635be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        SectionName += ",\"aw\",%progbits";
8645be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        SwitchToDataSection(SectionName.c_str());
8655be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      } else {
8665be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng        if (C->isNullValue() && !NoZerosInBSS && TAI->getBSSSection())
8675be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng          SwitchToDataSection(TAI->getBSSSection(), I);
86898ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng        else if (!I->isConstant())
8695be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng          SwitchToDataSection(TAI->getDataSection(), I);
87098ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng        else {
87198ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng          // Read-only data.
872032953d74746fa89b62e49b63a38ba6d8827b81aEvan Cheng          bool HasReloc = C->ContainsRelocations();
873032953d74746fa89b62e49b63a38ba6d8827b81aEvan Cheng          if (HasReloc &&
874032953d74746fa89b62e49b63a38ba6d8827b81aEvan Cheng              Subtarget->isTargetDarwin() &&
87598ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng              TM.getRelocationModel() != Reloc::Static)
87698ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng            SwitchToDataSection("\t.const_data\n");
877032953d74746fa89b62e49b63a38ba6d8827b81aEvan Cheng          else if (!HasReloc && Size == 4 &&
87898ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng                   TAI->getFourByteConstantSection())
87998ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng            SwitchToDataSection(TAI->getFourByteConstantSection(), I);
880032953d74746fa89b62e49b63a38ba6d8827b81aEvan Cheng          else if (!HasReloc && Size == 8 &&
88198ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng                   TAI->getEightByteConstantSection())
88298ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng            SwitchToDataSection(TAI->getEightByteConstantSection(), I);
883032953d74746fa89b62e49b63a38ba6d8827b81aEvan Cheng          else if (!HasReloc && Size == 16 &&
88498ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng                   TAI->getSixteenByteConstantSection())
88598ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng            SwitchToDataSection(TAI->getSixteenByteConstantSection(), I);
88698ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng          else if (TAI->getReadOnlySection())
88798ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng            SwitchToDataSection(TAI->getReadOnlySection(), I);
88898ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng          else
88998ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng            SwitchToDataSection(TAI->getDataSection(), I);
89098ded765c2dc2f256e9f11502ca302f2b24f31e8Evan Cheng        }
8915be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      }
8925be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng
8935be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      break;
8945be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    }
8955be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    default:
8965be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      assert(0 && "Unknown linkage type!");
8975be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      break;
898a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
899b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola
900a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    EmitAlignment(Align, I);
9015be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    O << name << ":\t\t\t\t" << TAI->getCommentString() << " " << I->getName()
9025be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng      << "\n";
9035be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    if (TAI->hasDotTypeDotSizeDirective())
904b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola      O << "\t.size " << name << ", " << Size << "\n";
905a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // If the initializer is a extern weak symbol, remember to emit the weak
906a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // reference!
907a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
908a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      if (GV->hasExternalWeakLinkage())
909a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      ExtWeakSymbols.insert(GV);
910a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
911a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    EmitGlobalConstant(C);
912a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << '\n';
913a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
914a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
9155be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng  if (Subtarget->isTargetDarwin()) {
9165be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng    SwitchToDataSection("");
9175be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng
918a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Output stubs for dynamically-linked functions
919a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    unsigned j = 1;
920a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
921a8e2989ece6dc46df59b0768184028257f913843Evan Cheng         i != e; ++i, ++j) {
922a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      if (TM.getRelocationModel() == Reloc::PIC_)
923a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        SwitchToTextSection(".section __TEXT,__picsymbolstub4,symbol_stubs,"
924a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                            "none,16", 0);
925a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      else
926a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        SwitchToTextSection(".section __TEXT,__symbol_stub4,symbol_stubs,"
927a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                            "none,12", 0);
928a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
929a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      EmitAlignment(2);
930a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\t.code\t32\n";
931a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
932a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "L" << *i << "$stub:\n";
933a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\t.indirect_symbol " << *i << "\n";
934a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\tldr ip, L" << *i << "$slp\n";
935a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      if (TM.getRelocationModel() == Reloc::PIC_) {
936a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        O << "L" << *i << "$scv:\n";
937a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        O << "\tadd ip, pc, ip\n";
938a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      }
939a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\tldr pc, [ip, #0]\n";
940a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "L" << *i << "$slp:\n";
941a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      if (TM.getRelocationModel() == Reloc::PIC_)
942a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        O << "\t.long\tL" << *i << "$lazy_ptr-(L" << *i << "$scv+8)\n";
943a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      else
944a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        O << "\t.long\tL" << *i << "$lazy_ptr\n";
945a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      SwitchToDataSection(".lazy_symbol_pointer", 0);
946a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "L" << *i << "$lazy_ptr:\n";
947a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\t.indirect_symbol " << *i << "\n";
948a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\t.long\tdyld_stub_binding_helper\n";
949a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
950a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "\n";
951a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
952a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Output non-lazy-pointers for external and common global variables.
953a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (GVNonLazyPtrs.begin() != GVNonLazyPtrs.end())
954a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      SwitchToDataSection(".non_lazy_symbol_pointer", 0);
955a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    for (std::set<std::string>::iterator i = GVNonLazyPtrs.begin(),
956a8e2989ece6dc46df59b0768184028257f913843Evan Cheng           e = GVNonLazyPtrs.end(); i != e; ++i) {
957a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "L" << *i << "$non_lazy_ptr:\n";
958a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\t.indirect_symbol " << *i << "\n";
959a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << "\t.long\t0\n";
960a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
961a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
962a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Emit initial debug information.
963a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    DW.EndModule();
964a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
965a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Funny Darwin hack: This flag tells the linker that no global symbols
966a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // contain code that falls through to other global symbols (e.g. the obvious
967a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // implementation of multiple entry points).  If this doesn't occur, the
968a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // linker can safely perform dead code stripping.  Since LLVM never
969a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // generates code that does this, it is always safe to set.
970a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "\t.subsections_via_symbols\n";
971b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola  }
972b97809c9a7a4ef681070ab1cbc7bd4fb18d34ba1Rafael Espindola
9737bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  AsmPrinter::doFinalization(M);
9747bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  return false; // success
9757bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
976