ARMAsmPrinter.cpp revision 2317e40539aac11da00bd587b5f0def04d989769
197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===//
297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//
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"
1788ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov#include "ARMBuildAttrs.h"
18a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMAddressingModes.h"
19a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "ARMConstantPoolValue.h"
20f447a5f1446d3f3ccd7f342a54f565ab02a087c8Chris Lattner#include "AsmPrinter/ARMInstPrinter.h"
2197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMMachineFunctionInfo.h"
2297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMMCInstLower.h"
2397f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "ARMTargetMachine.h"
243f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen#include "llvm/Analysis/DebugInfo.h"
257bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Constants.h"
267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Module.h"
27e55b15fa4753ef08cbfa2127d2d220b77aa07d87Benjamin Kramer#include "llvm/Type.h"
28cf20ac4fd12ea3510a8f32a24fff69eebe7b6f4aDan Gohman#include "llvm/Assembly/Writer.h"
297bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/AsmPrinter.h"
30b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/CodeGen/MachineModuleInfoImpls.h"
317bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h"
32a8e2989ece6dc46df59b0768184028257f913843Evan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h"
33362dd0bef5437f85586c046bc53287b6fbe9c099Anton Korobeynikov#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
34b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCAsmInfo.h"
35b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner#include "llvm/MC/MCContext.h"
36becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling#include "llvm/MC/MCExpr.h"
3797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/MC/MCInst.h"
38f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#include "llvm/MC/MCSectionMachO.h"
396c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h"
40325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h"
41d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner#include "llvm/Target/Mangler.h"
42b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola#include "llvm/Target/TargetData.h"
437bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "llvm/Target/TargetMachine.h"
445be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng#include "llvm/Target/TargetOptions.h"
4551b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar#include "llvm/Target/TargetRegistry.h"
46c324ecb7bc93a1f09db29851438ec5ee72b143ebEvan Cheng#include "llvm/ADT/SmallPtrSet.h"
47c40d9f9bae70c83947bf8fa5f9ee97adbf1bb0c0Jim Grosbach#include "llvm/ADT/SmallString.h"
4854c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson#include "llvm/ADT/StringExtras.h"
4997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner#include "llvm/Support/CommandLine.h"
5059135f49e1699daec9a43fc2d15715d55b910f54Devang Patel#include "llvm/Support/Debug.h"
513046470919e648ff7c011bda9c094163062c83dcTorok Edwin#include "llvm/Support/ErrorHandling.h"
52b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner#include "llvm/Support/raw_ostream.h"
537bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include <cctype>
547bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolausing namespace llvm;
557bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
56917290043f87b8efa6ba540bec5963013c517912Jim Grosbachnamespace llvm {
57917290043f87b8efa6ba540bec5963013c517912Jim Grosbach  namespace ARM {
58917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    enum DW_ISA {
59917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      DW_ISA_ARM_thumb = 1,
60917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      DW_ISA_ARM_arm = 2
61917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    };
62917290043f87b8efa6ba540bec5963013c517912Jim Grosbach  }
63917290043f87b8efa6ba540bec5963013c517912Jim Grosbach}
64917290043f87b8efa6ba540bec5963013c517912Jim Grosbach
6595b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace {
664a071d667d995b00e7853243ff9c7c1269324478Chris Lattner  class ARMAsmPrinter : public AsmPrinter {
67a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
68a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
69a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// make the right decision when printing asm code for different targets.
70a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    const ARMSubtarget *Subtarget;
71a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
72a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// AFI - Keep a pointer to ARMFunctionInfo for the current
736d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    /// MachineFunction.
74a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    ARMFunctionInfo *AFI;
75a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
766d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    /// MCP - Keep a pointer to constantpool entries of the current
776d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    /// MachineFunction.
786d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    const MachineConstantPool *MCP;
796d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng
8057f0db833dc30404f1f5d28b23df326e520698ecBill Wendling  public:
81b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner    explicit ARMAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
82b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner      : AsmPrinter(TM, Streamer), AFI(NULL), MCP(NULL) {
8357f0db833dc30404f1f5d28b23df326e520698ecBill Wendling      Subtarget = &TM.getSubtarget<ARMSubtarget>();
8457f0db833dc30404f1f5d28b23df326e520698ecBill Wendling    }
8557f0db833dc30404f1f5d28b23df326e520698ecBill Wendling
867bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    virtual const char *getPassName() const {
877bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola      return "ARM Assembly Printer";
887bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    }
89b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
9035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
91a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                      const char *Modifier = 0);
9254c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson
93055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
94c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                 unsigned AsmVariant, const char *ExtraCode,
95c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                 raw_ostream &O);
96055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
97224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson                                       unsigned AsmVariant,
98c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                       const char *ExtraCode, raw_ostream &O);
997bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
1002317e40539aac11da00bd587b5f0def04d989769Jim Grosbach    void EmitJumpTable(const MachineInstr *MI);
1012317e40539aac11da00bd587b5f0def04d989769Jim Grosbach    void EmitJump2Table(const MachineInstr *MI);
102a786ceac5c888761d83d84d35eb16150be57cc6eChris Lattner    virtual void EmitInstruction(const MachineInstr *MI);
1037bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    bool runOnMachineFunction(MachineFunction &F);
104b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
105a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattner    virtual void EmitConstantPool() {} // we emit constant pools customly!
106953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner    virtual void EmitFunctionEntryLabel();
107812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson    void EmitStartOfAsmFile(Module &M);
1084a071d667d995b00e7853243ff9c7c1269324478Chris Lattner    void EmitEndOfAsmFile(Module &M);
109a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1102d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
1112d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach
11259135f49e1699daec9a43fc2d15715d55b910f54Devang Patel    MachineLocation getDebugValueLocation(const MachineInstr *MI) const {
11359135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      MachineLocation Location;
11459135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      assert (MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
11559135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      // Frame address.  Currently handles register +- offset only.
11659135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm())
11759135f49e1699daec9a43fc2d15715d55b910f54Devang Patel        Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
11859135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      else {
11959135f49e1699daec9a43fc2d15715d55b910f54Devang Patel        DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
12059135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      }
12159135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      return Location;
12259135f49e1699daec9a43fc2d15715d55b910f54Devang Patel    }
12359135f49e1699daec9a43fc2d15715d55b910f54Devang Patel
124917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    virtual unsigned getISAEncoding() {
125917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      // ARM/Darwin adds ISA to the DWARF info for each function.
126917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      if (!Subtarget->isTargetDarwin())
127917290043f87b8efa6ba540bec5963013c517912Jim Grosbach        return 0;
128917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      return Subtarget->isThumb() ?
129917290043f87b8efa6ba540bec5963013c517912Jim Grosbach        llvm::ARM::DW_ISA_ARM_thumb : llvm::ARM::DW_ISA_ARM_arm;
130917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    }
131917290043f87b8efa6ba540bec5963013c517912Jim Grosbach
1320890cf124f00da3dc943c1882f4221955e0281edChris Lattner    MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
1330890cf124f00da3dc943c1882f4221955e0281edChris Lattner                                          const MachineBasicBlock *MBB) const;
1340890cf124f00da3dc943c1882f4221955e0281edChris Lattner    MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const;
135bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner
136433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    MCSymbol *GetARMSJLJEHLabel(void) const;
137433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
138711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    /// EmitMachineConstantPoolValue - Print a machine constantpool value to
139711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    /// the .s file.
140a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
1419d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      SmallString<128> Str;
1429d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      raw_svector_ostream OS(Str);
1439d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      EmitMachineConstantPoolValue(MCPV, OS);
1449d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText(OS.str());
1459d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    }
146b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1479d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV,
1489d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                                      raw_ostream &O) {
149ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      switch (TM.getTargetData()->getTypeAllocSize(MCPV->getType())) {
150ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      case 1: O << MAI->getData8bitsDirective(0); break;
151ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      case 2: O << MAI->getData16bitsDirective(0); break;
152ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      case 4: O << MAI->getData32bitsDirective(0); break;
153ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      default: assert(0 && "Unknown CPV size");
154ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      }
155a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
156711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng      ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
1573fb2b1ede30193b59a651328a946174196b20610Jim Grosbach
1583fb2b1ede30193b59a651328a946174196b20610Jim Grosbach      if (ACPV->isLSDA()) {
1599d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner        O << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
16028989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      } else if (ACPV->isBlockAddress()) {
1610752cda4de245978e14d806831abba4506272cd0Chris Lattner        O << *GetBlockAddressSymbol(ACPV->getBlockAddress());
16228989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      } else if (ACPV->isGlobalValue()) {
16346510a73e977273ec67747eb34cbdb43f815e451Dan Gohman        const GlobalValue *GV = ACPV->getGV();
164e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        bool isIndirect = Subtarget->isTargetDarwin() &&
16563476a80404125e5196b6c09113c1d4796da0604Evan Cheng          Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
166e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        if (!isIndirect)
167d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner          O << *Mang->getSymbol(GV);
168e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        else {
169e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng          // FIXME: Remove this when Darwin transition to @GOT like syntax.
1707a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner          MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
17110b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner          O << *Sym;
172b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
173b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner          MachineModuleInfoMachO &MMIMachO =
174b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner            MMI->getObjFileInfo<MachineModuleInfoMachO>();
175cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling          MachineModuleInfoImpl::StubValueTy &StubSym =
176b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner            GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(Sym) :
177b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner                                        MMIMachO.getGVStubEntry(Sym);
178cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling          if (StubSym.getPointer() == 0)
179cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling            StubSym = MachineModuleInfoImpl::
180d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner              StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
181e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        }
18228989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      } else {
18328989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson        assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
18410b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner        O << *GetExternalSymbolSymbol(ACPV->getSymbol());
18528989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      }
186e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
1870ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
18864f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio      if (ACPV->getPCAdjustment() != 0) {
18933adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner        O << "-(" << MAI->getPrivateGlobalPrefix() << "PC"
190e7e0d62efda2445b735052ca45bd74fb002e34c3Evan Cheng          << getFunctionNumber() << "_"  << ACPV->getLabelId()
19164f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio          << "+" << (unsigned)ACPV->getPCAdjustment();
19264f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio         if (ACPV->mustAddCurrentAddress())
19364f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio           O << "-.";
1948b3787586ed92df55131ad38c16646b7eba401a0Chris Lattner         O << ')';
19564f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio      }
196a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
1977bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  };
1987bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace
1997bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
200953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattnervoid ARMAsmPrinter::EmitFunctionEntryLabel() {
201953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  if (AFI->isThumbFunction()) {
2029d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.EmitRawText(StringRef("\t.code\t16"));
2030752cda4de245978e14d806831abba4506272cd0Chris Lattner    if (!Subtarget->isTargetDarwin())
2049d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText(StringRef("\t.thumb_func"));
2050752cda4de245978e14d806831abba4506272cd0Chris Lattner    else {
2060752cda4de245978e14d806831abba4506272cd0Chris Lattner      // This needs to emit to a temporary string to get properly quoted
2070752cda4de245978e14d806831abba4506272cd0Chris Lattner      // MCSymbols when they have spaces in them.
2080752cda4de245978e14d806831abba4506272cd0Chris Lattner      SmallString<128> Tmp;
2090752cda4de245978e14d806831abba4506272cd0Chris Lattner      raw_svector_ostream OS(Tmp);
2100752cda4de245978e14d806831abba4506272cd0Chris Lattner      OS << "\t.thumb_func\t" << *CurrentFnSym;
2110752cda4de245978e14d806831abba4506272cd0Chris Lattner      OutStreamer.EmitRawText(OS.str());
2120752cda4de245978e14d806831abba4506272cd0Chris Lattner    }
213953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  }
214b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
215953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  OutStreamer.EmitLabel(CurrentFnSym);
216953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner}
217953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner
2182317e40539aac11da00bd587b5f0def04d989769Jim Grosbach/// runOnMachineFunction - This uses the EmitInstruction()
2197bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction.
2207bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola///
2217bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
222a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  AFI = MF.getInfo<ARMFunctionInfo>();
2236d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng  MCP = MF.getConstantPool();
224a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
225d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner  return AsmPrinter::runOnMachineFunction(MF);
22632bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola}
22732bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola
228055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
22935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                 raw_ostream &O, const char *Modifier) {
230055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
2315cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov  unsigned TF = MO.getTargetFlags();
2325cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov
2332f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  switch (MO.getType()) {
2348bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner  default:
2358bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(0 && "<unknown operand type>");
2365bafff36c798608a189c517d37527e4a38863071Bob Wilson  case MachineOperand::MO_Register: {
2375bafff36c798608a189c517d37527e4a38863071Bob Wilson    unsigned Reg = MO.getReg();
2388bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(TargetRegisterInfo::isPhysicalRegister(Reg));
239de0ae8f83dd8eabc831b0631c20ffa3b53a774f2Bob Wilson    if (Modifier && strcmp(Modifier, "lane") == 0) {
240a4c3c8f28d9465dc7c42eb43c2377530f1821574Jim Grosbach      unsigned RegNum = getARMRegisterNumbering(Reg);
2419d1c1ada213c80135fbdda704175aae689daa6f9Chris Lattner      unsigned DReg =
242e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen        TM.getRegisterInfo()->getMatchingSuperReg(Reg,
243e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen          RegNum & 1 ? ARM::ssub_1 : ARM::ssub_0, &ARM::DPR_VFP2RegClass);
2442317e40539aac11da00bd587b5f0def04d989769Jim Grosbach      O << ARMInstPrinter::getRegisterName(DReg) << '[' << (RegNum & 1) << ']';
2458bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    } else {
246e8ea011cc766b37a957d5966655526096bf49feaAnton Korobeynikov      assert(!MO.getSubReg() && "Subregs should be eliminated!");
2472317e40539aac11da00bd587b5f0def04d989769Jim Grosbach      O << ARMInstPrinter::getRegisterName(Reg);
2488bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    }
2492f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
2505bafff36c798608a189c517d37527e4a38863071Bob Wilson  }
251a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_Immediate: {
2525adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng    int64_t Imm = MO.getImm();
253632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << '#';
2545cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
2555cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov        (TF & ARMII::MO_LO16))
2565cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
2575cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
2585cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov             (TF & ARMII::MO_HI16))
2595cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
260632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << Imm;
2612f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
262a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
2632f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_MachineBasicBlock:
2641b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner    O << *MO.getMBB()->getSymbol();
2652f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    return;
26684b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola  case MachineOperand::MO_GlobalAddress: {
267a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    bool isCallOp = Modifier && !strcmp(Modifier, "call");
26846510a73e977273ec67747eb34cbdb43f815e451Dan Gohman    const GlobalValue *GV = MO.getGlobal();
2695cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov
2705cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
2715cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov        (TF & ARMII::MO_LO16))
2725cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
2735cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
2745cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov             (TF & ARMII::MO_HI16))
2755cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
276d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner    O << *Mang->getSymbol(GV);
2777751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
2780c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner    printOffset(MO.getOffset(), O);
2797751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
2800ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio    if (isCallOp && Subtarget->isTargetELF() &&
2810ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio        TM.getRelocationModel() == Reloc::PIC_)
2820ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
2832f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
284a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
285a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_ExternalSymbol: {
286a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    bool isCallOp = Modifier && !strcmp(Modifier, "call");
28710b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner    O << *GetExternalSymbolSymbol(MO.getSymbolName());
288b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
2890ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio    if (isCallOp && Subtarget->isTargetELF() &&
2900ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio        TM.getRelocationModel() == Reloc::PIC_)
2910ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
2922f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
293a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
2942f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_ConstantPoolIndex:
2951b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetCPISymbol(MO.getIndex());
2962f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
297a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_JumpTableIndex:
2981b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetJTISymbol(MO.getIndex());
299a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    break;
3002f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  }
3017bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
3027bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
303055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===//
304055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
3050890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
3060890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
3070890cf124f00da3dc943c1882f4221955e0281edChris Lattner                            const MachineBasicBlock *MBB) const {
3080890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
3090890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
310bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2
3110890cf124f00da3dc943c1882f4221955e0281edChris Lattner    << "_set_" << MBB->getNumber();
3129b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
3130890cf124f00da3dc943c1882f4221955e0281edChris Lattner}
3140890cf124f00da3dc943c1882f4221955e0281edChris Lattner
3150890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
3160890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
3170890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
3180890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
319281e7767df71b3f727ade80a16ff0c4fe5a49dd9Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2;
3209b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
321bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner}
322bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner
323433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
324433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim GrosbachMCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const {
325433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  SmallString<60> Name;
326433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH"
327433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    << getFunctionNumber();
328433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  return OutContext.GetOrCreateSymbol(Name.str());
329433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach}
330433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
331055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
332c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    unsigned AsmVariant, const char *ExtraCode,
333c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    raw_ostream &O) {
334a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Does this asm operand have a single letter operand modifier?
335a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (ExtraCode && ExtraCode[0]) {
336a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ExtraCode[1] != 0) return true; // Unknown modifier.
3378e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov
338a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    switch (ExtraCode[0]) {
339a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    default: return true;  // Unknown modifier.
3409b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'a': // Print as a memory address.
3419b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      if (MI->getOperand(OpNum).isReg()) {
3422317e40539aac11da00bd587b5f0def04d989769Jim Grosbach        O << "[" << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()) << "]";
3439b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson        return false;
3449b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      }
3459b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      // Fallthrough
3469b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'c': // Don't print "#" before an immediate operand.
3474f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson      if (!MI->getOperand(OpNum).isImm())
3484f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson        return true;
3492317e40539aac11da00bd587b5f0def04d989769Jim Grosbach      O << MI->getOperand(OpNum).getImm();
3508f3434647d3d39b49475239e3be1b8afb06415cfBob Wilson      return false;
351e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng    case 'P': // Print a VFP double precision register.
352d831cda3e74235704f163d5a18352584d537517aEvan Cheng    case 'q': // Print a NEON quad precision register.
35335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      printOperand(MI, OpNum, O);
35423a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng      return false;
355a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'Q':
356a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'R':
357d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson    case 'H':
35812616727c71721f480f69026d88a58a067d89824Evan Cheng      report_fatal_error("llvm does not support 'Q', 'R', and 'H' modifiers!");
359d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson      return true;
36084f60b7359e1aa90794bb19de2bbf4d25dc2f01dEvan Cheng    }
361a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
362e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
36335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, OpNum, O);
364a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  return false;
365a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
366a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
367224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilsonbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
368055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng                                          unsigned OpNum, unsigned AsmVariant,
369c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          const char *ExtraCode,
370c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          raw_ostream &O) {
371224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  if (ExtraCode && ExtraCode[0])
372224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson    return true; // Unknown modifier.
373765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson
374765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  const MachineOperand &MO = MI->getOperand(OpNum);
375765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  assert(MO.isReg() && "unexpected inline asm memory operand");
3762317e40539aac11da00bd587b5f0def04d989769Jim Grosbach  O << "[" << ARMInstPrinter::getRegisterName(MO.getReg()) << "]";
377224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  return false;
378224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson}
379224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson
380812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
3810fb34683b9e33238288d2af1e090582464df8387Bob Wilson  if (Subtarget->isTargetDarwin()) {
3820fb34683b9e33238288d2af1e090582464df8387Bob Wilson    Reloc::Model RelocM = TM.getRelocationModel();
3830fb34683b9e33238288d2af1e090582464df8387Bob Wilson    if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
3840fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // Declare all the text sections up front (before the DWARF sections
3850fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // emitted by AsmPrinter::doInitialization) so the assembler will keep
3860fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // them together at the beginning of the object file.  This helps
3870fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // avoid out-of-range branches that are due a fundamental limitation of
3880fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // the way symbol offsets are encoded with the current Darwin ARM
3890fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // relocations.
390b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach      const TargetLoweringObjectFileMachO &TLOFMacho =
3910d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman        static_cast<const TargetLoweringObjectFileMachO &>(
3920d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman          getObjFileLowering());
39329e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextSection());
39429e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
39529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection());
39629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      if (RelocM == Reloc::DynamicNoPIC) {
39729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
39822772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__symbol_stub4",
39922772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
40022772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     12, SectionKind::getText());
40129e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
40229e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      } else {
40329e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
40422772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__picsymbolstub4",
40522772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
40622772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     16, SectionKind::getText());
40729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
40829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      }
40963db594559dc8eac666204c7907bae664f5234daBob Wilson      const MCSection *StaticInitSect =
41063db594559dc8eac666204c7907bae664f5234daBob Wilson        OutContext.getMachOSection("__TEXT", "__StaticInit",
41163db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_REGULAR |
41263db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
41363db594559dc8eac666204c7907bae664f5234daBob Wilson                                   SectionKind::getText());
41463db594559dc8eac666204c7907bae664f5234daBob Wilson      OutStreamer.SwitchSection(StaticInitSect);
4150fb34683b9e33238288d2af1e090582464df8387Bob Wilson    }
4160fb34683b9e33238288d2af1e090582464df8387Bob Wilson  }
4170fb34683b9e33238288d2af1e090582464df8387Bob Wilson
418e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach  // Use unified assembler syntax.
4199d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  OutStreamer.EmitRawText(StringRef("\t.syntax unified"));
420d61eca533081580d56fabee38f86507d8019ca75Anton Korobeynikov
42188ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  // Emit ARM Build Attributes
42288ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  if (Subtarget->isTargetELF()) {
42388ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // CPU Type
424d260c248abd57763aaeeadcab4155655a25d9e97Anton Korobeynikov    std::string CPUString = Subtarget->getCPUString();
425d260c248abd57763aaeeadcab4155655a25d9e97Anton Korobeynikov    if (CPUString != "generic")
4269d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.cpu " + Twine(CPUString));
42788ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
42888ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // FIXME: Emit FPU type
42988ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    if (Subtarget->hasVFP2())
4309d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
4319d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::VFP_arch) + ", 2");
43288ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
43388ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // Signal various FP modes.
4349d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    if (!UnsafeFPMath) {
4359d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
4369d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_denormal) + ", 1");
4379d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
4389d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_exceptions) + ", 1");
4399d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    }
440b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
44160108e96bbc5432f4fe06ba313e64448e97a0e15Evan Cheng    if (NoInfsFPMath && NoNaNsFPMath)
4429d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
4439d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 1");
44488ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    else
4459d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
4469d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 3");
44788ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
44888ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // 8-bytes alignment stuff.
4499d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.EmitRawText("\t.eabi_attribute " +
4509d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                            Twine(ARMBuildAttrs::ABI_align8_needed) + ", 1");
4519d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.EmitRawText("\t.eabi_attribute " +
4529d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                            Twine(ARMBuildAttrs::ABI_align8_preserved) + ", 1");
45388ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
454567d14f07cd62bfb9dd0edd90144a0a840450f7aAnton Korobeynikov    // Hard float.  Use both S and D registers and conform to AAPCS-VFP.
4559d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) {
4569d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
4579d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_HardFP_use) + ", 3");
4589d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
4599d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_VFP_args) + ", 1");
4609d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    }
46188ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // FIXME: Should we signal R9 usage?
46288ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  }
4637bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
4647bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
4650f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
4664a071d667d995b00e7853243ff9c7c1269324478Chris Lattnervoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
4675be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng  if (Subtarget->isTargetDarwin()) {
468f61159b574155b056dbd5d6d44f47f753d424056Chris Lattner    // All darwin targets use mach-o.
4690d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman    const TargetLoweringObjectFileMachO &TLOFMacho =
4700d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman      static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
471b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO &MMIMacho =
472b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      MMI->getObjFileInfo<MachineModuleInfoMachO>();
473e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
474a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Output non-lazy-pointers for external and common global variables.
475b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
476cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling
477b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    if (!Stubs.empty()) {
478ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner      // Switch with ".non_lazy_symbol_pointer" directive.
4796c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
480c076a9793936b140364671a5e39ee53bd266c6c3Chris Lattner      EmitAlignment(2);
481b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
482becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
483becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
484becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .indirect_symbol _foo
48552a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
48652a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol);
487cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
48852a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        if (MCSym.getInt())
489cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // External to current translation unit.
490cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
491cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling        else
492cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // Internal to current translation unit.
4935e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          //
4941b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // When we place the LSDA into the TEXT section, the type info
4951b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // pointers need to be indirect and pc-rel. We accomplish this by
4961b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // using NLPs; however, sometimes the types are local to the file.
4971b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // We need to fill in the value for the NLP in those cases.
49852a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling          OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
49952a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling                                                        OutContext),
500cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling                                4/*size*/, 0/*addrspace*/);
501ae94e594164b193236002516970aeec4c4574768Evan Cheng      }
502becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling
503becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      Stubs.clear();
504becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      OutStreamer.AddBlankLine();
505a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
506a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
507e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    Stubs = MMIMacho.GetHiddenGVStubList();
508e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    if (!Stubs.empty()) {
5096c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
510f3231de60bb64c3f6fc6770b3e6174f4f839a4f3Chris Lattner      EmitAlignment(2);
511becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
512becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
513becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
514becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .long _foo
515cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling        OutStreamer.EmitValue(MCSymbolRefExpr::
516cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                              Create(Stubs[i].second.getPointer(),
517cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                                     OutContext),
518becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling                              4/*size*/, 0/*addrspace*/);
519becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      }
520cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
521cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      Stubs.clear();
522cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      OutStreamer.AddBlankLine();
523ae94e594164b193236002516970aeec4c4574768Evan Cheng    }
524ae94e594164b193236002516970aeec4c4574768Evan Cheng
525a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Funny Darwin hack: This flag tells the linker that no global symbols
526a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // contain code that falls through to other global symbols (e.g. the obvious
527a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // implementation of multiple entry points).  If this doesn't occur, the
528a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // linker can safely perform dead code stripping.  Since LLVM never
529a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // generates code that does this, it is always safe to set.
530a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner    OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
531b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola  }
5327bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
5330bd89712c03c59ea43ce37763685e7f7c0bdd977Anton Korobeynikov
53497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===----------------------------------------------------------------------===//
53597f06937449c593a248dbbb1365e6ae408fb9decChris Lattner
536988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbachstatic MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber,
537988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                             unsigned LabelId, MCContext &Ctx) {
538988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach
539988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach  MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix)
540988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                       + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));
541988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach  return Label;
542988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach}
543988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach
544a2244cb38781e596110023399c7902b5ee5087feJim Grosbachvoid ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) {
545a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  unsigned Opcode = MI->getOpcode();
546a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  int OpNum = 1;
547a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  if (Opcode == ARM::BR_JTadd)
548a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OpNum = 2;
549a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  else if (Opcode == ARM::BR_JTm)
550a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OpNum = 3;
551a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
552a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineOperand &MO1 = MI->getOperand(OpNum);
553a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
554a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  unsigned JTI = MO1.getIndex();
555a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
556a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  // Emit a label for the jump table.
557a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
558a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  OutStreamer.EmitLabel(JTISymbol);
559a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
560a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  // Emit each entry of the table.
561a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
562a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
563a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
564a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
565a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
566a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    MachineBasicBlock *MBB = JTBBs[i];
567a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // Construct an MCExpr for the entry. We want a value of the form:
568a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // (BasicBlockAddr - TableBeginAddr)
569a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //
570a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // For example, a table with entries jumping to basic blocks BB0 and BB1
571a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // would look like:
572a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // LJTI_0_0:
573a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //    .word (LBB0 - LJTI_0_0)
574a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //    .word (LBB1 - LJTI_0_0)
575a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext);
576a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
577a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    if (TM.getRelocationModel() == Reloc::PIC_)
578a2244cb38781e596110023399c7902b5ee5087feJim Grosbach      Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol,
579a2244cb38781e596110023399c7902b5ee5087feJim Grosbach                                                                   OutContext),
580a2244cb38781e596110023399c7902b5ee5087feJim Grosbach                                     OutContext);
581a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OutStreamer.EmitValue(Expr, 4);
582a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  }
583a2244cb38781e596110023399c7902b5ee5087feJim Grosbach}
584a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
585882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbachvoid ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) {
586882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  unsigned Opcode = MI->getOpcode();
587882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1;
588882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineOperand &MO1 = MI->getOperand(OpNum);
589882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
590882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  unsigned JTI = MO1.getIndex();
591882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
592882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  // Emit a label for the jump table.
593882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
594882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  OutStreamer.EmitLabel(JTISymbol);
595882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
596882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  // Emit each entry of the table.
597882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
598882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
599882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
600205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach  unsigned OffsetWidth = 4;
601882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  if (MI->getOpcode() == ARM::t2TBB)
602205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OffsetWidth = 1;
603882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  else if (MI->getOpcode() == ARM::t2TBH)
604205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OffsetWidth = 2;
605882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
606882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
607882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MachineBasicBlock *MBB = JTBBs[i];
608205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(),
609205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                                                      OutContext);
610882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // If this isn't a TBB or TBH, the entries are direct branch instructions.
611205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    if (OffsetWidth == 4) {
612882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      MCInst BrInst;
613882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      BrInst.setOpcode(ARM::t2B);
614205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach      BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr));
615882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      OutStreamer.EmitInstruction(BrInst);
616882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      continue;
617882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    }
618882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // Otherwise it's an offset from the dispatch instruction. Construct an
619205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // MCExpr for the entry. We want a value of the form:
620205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // (BasicBlockAddr - TableBeginAddr) / 2
621205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //
622205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // For example, a TBB table with entries jumping to basic blocks BB0 and BB1
623205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // would look like:
624205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // LJTI_0_0:
625205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //    .byte (LBB0 - LJTI_0_0) / 2
626205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //    .byte (LBB1 - LJTI_0_0) / 2
627205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    const MCExpr *Expr =
628205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach      MCBinaryExpr::CreateSub(MBBSymbolExpr,
629205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                              MCSymbolRefExpr::Create(JTISymbol, OutContext),
630205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                              OutContext);
631205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext),
632205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                                   OutContext);
633205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OutStreamer.EmitValue(Expr, OffsetWidth);
634882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  }
635205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach
636205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach  // Make sure the instruction that follows TBB is 2-byte aligned.
637205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach  // FIXME: Constant island pass should insert an "ALIGN" instruction instead.
638205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach  if (MI->getOpcode() == ARM::t2TBB)
639205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    EmitAlignment(1);
640882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach}
641882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
6422d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbachvoid ARMAsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
6432d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach                                           raw_ostream &OS) {
6442d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  unsigned NOps = MI->getNumOperands();
6452d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  assert(NOps==4);
6462d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
6472d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  // cast away const; DIetc do not take const operands for some reason.
6482d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
6492d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << V.getName();
6502d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << " <- ";
6512d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  // Frame address.  Currently handles register +- offset only.
6522d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
6532d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS);
6542d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << ']';
6552d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  OS << "+";
6562d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  printOperand(MI, NOps-2, OS);
6572d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach}
6582d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach
659b454cdaebc6e4543099955ce043258c3903b1a0eJim Grosbachvoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
66096bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner  ARMMCInstLower MCInstLowering(OutContext, *Mang, *this);
66197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  switch (MI->getOpcode()) {
662c6b8a9920787505468931e56696cef1245e25913Chris Lattner  case ARM::t2MOVi32imm:
663c6b8a9920787505468931e56696cef1245e25913Chris Lattner    assert(0 && "Should be lowered by thumb2it pass");
6644d1522234192704f45dfd2527c2913fa60be616eChris Lattner  default: break;
6652d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  case ARM::DBG_VALUE: {
6662d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    if (isVerbose() && OutStreamer.hasRawTextSupport()) {
6672d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      SmallString<128> TmpStr;
6682d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      raw_svector_ostream OS(TmpStr);
6692d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      PrintDebugValueComment(MI, OS);
6702d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach      OutStreamer.EmitRawText(StringRef(OS.str()));
6712d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    }
6722d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach    return;
6732d0f53bd6348be3b28ffa53c37e3079bb33dd170Jim Grosbach  }
674fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach  case ARM::tPICADD: {
675fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // This is a pseudo op for a label + instruction sequence, which looks like:
676fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // LPC0:
677fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    //     add r0, pc
678fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // This adds the address of LPC0 to r0.
679fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach
680fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Emit the label.
681988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
682988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
683988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
684fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach
685fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Form and emit the add.
686fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    MCInst AddInst;
687fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.setOpcode(ARM::tADDhirr);
688fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
689fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
690fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
691fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Add predicate operands.
692fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
693fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(0));
694fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    OutStreamer.EmitInstruction(AddInst);
695fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    return;
696fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach  }
6974d1522234192704f45dfd2527c2913fa60be616eChris Lattner  case ARM::PICADD: { // FIXME: Remove asm string from td file.
6984d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This is a pseudo op for a label + instruction sequence, which looks like:
6994d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // LPC0:
7004d1522234192704f45dfd2527c2913fa60be616eChris Lattner    //     add r0, pc, r0
7014d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This adds the address of LPC0 to r0.
702b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
7034d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // Emit the label.
704988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
705988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
706988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
707b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
708f3f09527e6484143fcdef2ddfef0b2f016881e36Jim Grosbach    // Form and emit the add.
7094d1522234192704f45dfd2527c2913fa60be616eChris Lattner    MCInst AddInst;
7104d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.setOpcode(ARM::ADDrr);
7114d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
7124d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
7134d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
7145b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add predicate operands.
7155b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
7165b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
7175b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add 's' bit operand (always reg0 for this)
7185b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(0));
719850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner    OutStreamer.EmitInstruction(AddInst);
7204d1522234192704f45dfd2527c2913fa60be616eChris Lattner    return;
721b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach  }
722a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTR:
723a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTRB:
724a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTRH:
725a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDR:
726a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRB:
727a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRH:
728a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRSB:
729a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRSH: {
730b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // This is a pseudo op for a label + instruction sequence, which looks like:
731b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // LPC0:
732a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    //     OP r0, [pc, r0]
733b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // The LCP0 label is referenced by a constant pool entry in order to get
734b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // a PC-relative address at the ldr instruction.
735b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
736b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Emit the label.
737988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
738988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
739988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
740b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
741b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Form and emit the load
742a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    unsigned Opcode;
743a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    switch (MI->getOpcode()) {
744a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    default:
745a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach      llvm_unreachable("Unexpected opcode!");
746a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICSTR:   Opcode = ARM::STR; break;
747a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICSTRB:  Opcode = ARM::STRB; break;
748a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICSTRH:  Opcode = ARM::STRH; break;
749a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDR:   Opcode = ARM::LDR; break;
750a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRB:  Opcode = ARM::LDRB; break;
751a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRH:  Opcode = ARM::LDRH; break;
752a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
753a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
754a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    }
755a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    MCInst LdStInst;
756a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.setOpcode(Opcode);
757a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
758a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(ARM::PC));
759a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
760a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateImm(0));
761b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Add predicate operands.
762a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
763a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
764a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    OutStreamer.EmitInstruction(LdStInst);
765b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
766b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    return;
7674d1522234192704f45dfd2527c2913fa60be616eChris Lattner  }
768a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner  case ARM::CONSTPOOL_ENTRY: { // FIXME: Remove asm string from td file.
769a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
770a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// in the function.  The first operand is the ID# for this instruction, the
771a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// second is the index into the MachineConstantPool that this is, the third
772a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// is the size in bytes of this constant pool entry.
773a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
774a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned CPIdx   = (unsigned)MI->getOperand(1).getIndex();
775a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
776a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    EmitAlignment(2);
7771b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    OutStreamer.EmitLabel(GetCPISymbol(LabelId));
778a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
779a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
780a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    if (MCPE.isMachineConstantPoolEntry())
781a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
782a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    else
783a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitGlobalConstant(MCPE.Val.ConstVal);
784b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
785a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    return;
786a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner  }
787017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner  case ARM::MOVi2pieces: { // FIXME: Remove asmstring from td file.
788017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    // This is a hack that lowers as a two instruction sequence.
789017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned DstReg = MI->getOperand(0).getReg();
790017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
791017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner
792017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(ImmVal);
793017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(ImmVal);
794b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
795017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    {
796017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      MCInst TmpInst;
797017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.setOpcode(ARM::MOVi);
798017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));
799017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(SOImmValV1));
800b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
801017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      // Predicate.
802017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
803017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
804233917c07282564351439df8e7a9c83c9d6c459eChris Lattner
805233917c07282564351439df8e7a9c83c9d6c459eChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out
806850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
807017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    }
808017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner
809017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    {
810017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      MCInst TmpInst;
811017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.setOpcode(ARM::ORRri);
812017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // dstreg
813017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // inreg
814017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(SOImmValV2)); // so_imm
815017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      // Predicate.
816017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
817017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
818b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
819017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out
820850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
821017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    }
822b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach    return;
823017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner  }
824161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner  case ARM::MOVi32imm: { // FIXME: Remove asmstring from td file.
825161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    // This is a hack that lowers as a two instruction sequence.
826161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    unsigned DstReg = MI->getOperand(0).getReg();
82718c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    const MachineOperand &MO = MI->getOperand(1);
82818c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    MCOperand V1, V2;
82918c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    if (MO.isImm()) {
83018c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
83118c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V1 = MCOperand::CreateImm(ImmVal & 65535);
83218c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V2 = MCOperand::CreateImm(ImmVal >> 16);
83318c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    } else if (MO.isGlobal()) {
834c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach      MCSymbol *Symbol = MCInstLowering.GetGlobalAddressSymbol(MO.getGlobal());
83518c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      const MCSymbolRefExpr *SymRef1 =
8363472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        MCSymbolRefExpr::Create(Symbol,
8373472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands                                MCSymbolRefExpr::VK_ARM_LO16, OutContext);
83818c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      const MCSymbolRefExpr *SymRef2 =
8393472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        MCSymbolRefExpr::Create(Symbol,
8403472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands                                MCSymbolRefExpr::VK_ARM_HI16, OutContext);
84118c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V1 = MCOperand::CreateExpr(SymRef1);
84218c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V2 = MCOperand::CreateExpr(SymRef2);
84318c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    } else {
844f0633e48eb9d70d5db31a7498736ba21a9ee410cJim Grosbach      // FIXME: External symbol?
84518c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      MI->dump();
84618c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      llvm_unreachable("cannot handle this operand");
84718c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    }
84818c1021ec108722506125926087b1e5fcfb28046Rafael Espindola
849161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    {
850161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      MCInst TmpInst;
851161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.setOpcode(ARM::MOVi16);
852161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
85318c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      TmpInst.addOperand(V1); // lower16(imm)
854b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
855161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      // Predicate.
856161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
857161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
858b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
859850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
860161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    }
861b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
862161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    {
863161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      MCInst TmpInst;
864161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.setOpcode(ARM::MOVTi16);
865161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
866161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // srcreg
86718c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      TmpInst.addOperand(V2);   // upper16(imm)
868b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
869161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      // Predicate.
870161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
871161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
872b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
873850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
874161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    }
875b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
876161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    return;
877161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner  }
878882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::t2TBB:
879882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::t2TBH:
880882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::t2BR_JT: {
881882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
882882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MCInst TmpInst;
883882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MCInstLowering.Lower(MI, TmpInst);
884882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
885882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    EmitJump2Table(MI);
886882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    return;
887882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  }
888882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::tBR_JTr:
889882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::BR_JTr:
890882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::BR_JTm:
891a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  case ARM::BR_JTadd: {
892a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
893a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    MCInst TmpInst;
894a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    MCInstLowering.Lower(MI, TmpInst);
895a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
896a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    EmitJumpTable(MI);
897a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    return;
898a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  }
8992e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  case ARM::TRAP: {
9002e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // Non-Darwin binutils don't yet support the "trap" mnemonic.
9012e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // FIXME: Remove this special case when they do.
9022e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    if (!Subtarget->isTargetDarwin()) {
9032e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      //.long 0xe7ffdefe ${:comment} trap
904b2dda4bd346fe9a2795f83f659c0e60191b2e6a0Jim Grosbach      uint32_t Val = 0xe7ffdefeUL;
9052e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.AddComment("trap");
9062e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.EmitIntValue(Val, 4);
9072e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      return;
9082e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    }
9092e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    break;
9102e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  }
9112e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  case ARM::tTRAP: {
9122e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // Non-Darwin binutils don't yet support the "trap" mnemonic.
9132e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // FIXME: Remove this special case when they do.
9142e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    if (!Subtarget->isTargetDarwin()) {
915c8ab9eb066f6d35880e3a24436baf21236c921caBenjamin Kramer      //.short 57086 ${:comment} trap
916c8ab9eb066f6d35880e3a24436baf21236c921caBenjamin Kramer      uint16_t Val = 0xdefe;
9172e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.AddComment("trap");
9182e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.EmitIntValue(Val, 2);
9192e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      return;
9202e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    }
9212e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    break;
9222e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  }
923433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  case ARM::t2Int_eh_sjlj_setjmp:
924433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  case ARM::t2Int_eh_sjlj_setjmp_nofp:
925433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  case ARM::tInt_eh_sjlj_setjmp: { // FIXME: Remove asmstring from td file.
926433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // Two incoming args: GPR:$src, GPR:$val
927433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // mov $val, pc
928433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // adds $val, #7
929433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // str $val, [$src, #4]
930433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // movs r0, #0
931433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // b 1f
932433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // movs r0, #1
933433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // 1:
934433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
935433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    unsigned ValReg = MI->getOperand(1).getReg();
936433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    MCSymbol *Label = GetARMSJLJEHLabel();
937433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
938433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
939433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVgpr2tgpr);
940433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
941433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
942433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // 's' bit operand
943433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
944433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.AddComment("eh_setjmp begin");
945433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
946433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
947433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
948433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
949433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tADDi3);
950433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
951433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // 's' bit operand
952433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
953433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
954433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(7));
955433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
956433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
957433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
958433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
959433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
960433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
961433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
962433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tSTR);
963433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
964433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
965433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // The offset immediate is #4. The operand value is scaled by 4 for the
966433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // tSTR instruction.
967433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
968433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
969433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
970433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
971433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
972433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
973433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
974433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
975433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
976433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
977433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
978433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
979433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
980433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
981433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
982433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
983433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
984433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
985433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
986433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext);
987433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
988433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tB);
989433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr));
990433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
991433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
992433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
993433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
994433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
995433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
996433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
997433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
998433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
999433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1000433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1001433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.AddComment("eh_setjmp end");
1002433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1003433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1004433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    OutStreamer.EmitLabel(Label);
1005433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    return;
1006433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  }
1007433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
1008453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach  case ARM::Int_eh_sjlj_setjmp_nofp:
1009453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach  case ARM::Int_eh_sjlj_setjmp: { // FIXME: Remove asmstring from td file.
1010453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // Two incoming args: GPR:$src, GPR:$val
1011453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // add $val, pc, #8
1012453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // str $val, [$src, #+4]
1013453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // mov r0, #0
1014453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // add pc, pc, #0
1015453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // mov r0, #1
1016453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1017453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    unsigned ValReg = MI->getOperand(1).getReg();
1018453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach
1019453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1020453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1021453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::ADDri);
1022453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1023453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1024453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(8));
1025453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1026453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1027453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1028453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1029453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1030453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.AddComment("eh_setjmp begin");
1031453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1032453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1033453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1034453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1035453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::STR);
1036453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1037453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1038453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1039453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
1040453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1041453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1042453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1043453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1044453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1045453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1046453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1047453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::MOVi);
1048453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1049453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1050453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1051453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1052453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1053453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1054453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1055453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1056453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1057453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1058453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1059453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::ADDri);
1060453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1061453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1062453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1063453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1064453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1065453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1066453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1067453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1068453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1069453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1070453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1071453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1072453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::MOVi);
1073453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1074453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1075453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1076453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1077453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1078453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1079453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1080453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.AddComment("eh_setjmp end");
1081453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1082453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1083453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    return;
1084453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach  }
10855acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach  case ARM::Int_eh_sjlj_longjmp: {
10865acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr sp, [$src, #8]
10875acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr $scratch, [$src, #4]
10885acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr r7, [$src]
10895acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // bx $scratch
10905acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
10915acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    unsigned ScratchReg = MI->getOperand(1).getReg();
10925acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
10935acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
10945acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.setOpcode(ARM::LDR);
10955acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
10965acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
10975acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
10985acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(8));
10995acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
11005acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
11015acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
11025acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
11035acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
11045acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
11055acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
11065acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.setOpcode(ARM::LDR);
11075acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
11085acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
11095acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
11105acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
11115acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
11125acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
11135acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
11145acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
11155acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
11165acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
11175acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
11185acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.setOpcode(ARM::LDR);
11195acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
11205acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
11215acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
11225acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
11235acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
11245acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
11255acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
11265acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
11275acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
11285acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
11295acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
11305acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.setOpcode(ARM::BRIND);
11315acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
11325acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
11335acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
11345acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1135385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1136385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1137385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    return;
1138385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach  }
1139385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach  case ARM::tInt_eh_sjlj_longjmp: {
1140385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr $scratch, [$src, #8]
1141385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // mov sp, $scratch
1142385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr $scratch, [$src, #4]
1143385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr r7, [$src]
1144385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // bx $scratch
1145385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1146385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    unsigned ScratchReg = MI->getOperand(1).getReg();
1147385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1148385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1149385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tLDR);
1150385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1151385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1152385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // The offset immediate is #8. The operand value is scaled by 4 for the
1153385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // tSTR instruction.
1154385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(2));
1155385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1156385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1157385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1158385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1159385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1160385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1161385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1162385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1163385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tMOVtgpr2gpr);
1164385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
1165385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1166385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1167385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1168385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1169385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1170385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1171385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1172385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1173385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tLDR);
1174385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1175385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1176385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1177385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1178385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1179385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1180385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1181385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1182385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1183385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1184385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1185385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tLDR);
1186385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
1187385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1188385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1189385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1190385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1191385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1192385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1193385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1194385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1195385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1196385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1197385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tBX_RET_vararg);
1198385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1199385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1200385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1201385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
12025acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
12035acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
12045acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    return;
12055acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach  }
120697f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  }
1207b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
120897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  MCInst TmpInst;
120997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  MCInstLowering.Lower(MI, TmpInst);
1210850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner  OutStreamer.EmitInstruction(TmpInst);
121197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner}
12122685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
12132685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
12142685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Target Registry Stuff
12152685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
12162685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
12172685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarstatic MCInstPrinter *createARMMCInstPrinter(const Target &T,
12182685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar                                             unsigned SyntaxVariant,
1219d374087be5360a353a4239a155b1227057145f48Chris Lattner                                             const MCAsmInfo &MAI) {
12202685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  if (SyntaxVariant == 0)
122174d7e6c64e955f89e6d3d4023d36fd481da4cfc1Jim Grosbach    return new ARMInstPrinter(MAI);
12222685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  return 0;
12232685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
12242685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
12252685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Force static initialization.
12262685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarextern "C" void LLVMInitializeARMAsmPrinter() {
12272685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget);
12282685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget);
12292685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
12302685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter);
12312685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter);
12322685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
12332685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
1234