ARMAsmPrinter.cpp revision 385cc5eede9f81717b03121baf47b7aa185b5128
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
5697f06937449c593a248dbbb1365e6ae408fb9decChris Lattnerstatic cl::opt<bool>
57376ce97baca2bcf97ab420313a876214cde7f9dfJim GrosbachEnableMCInst("enable-arm-mcinst-printer", cl::Hidden, cl::init(true),
5897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner            cl::desc("enable experimental asmprinter gunk in the arm backend"));
5997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner
60917290043f87b8efa6ba540bec5963013c517912Jim Grosbachnamespace llvm {
61917290043f87b8efa6ba540bec5963013c517912Jim Grosbach  namespace ARM {
62917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    enum DW_ISA {
63917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      DW_ISA_ARM_thumb = 1,
64917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      DW_ISA_ARM_arm = 2
65917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    };
66917290043f87b8efa6ba540bec5963013c517912Jim Grosbach  }
67917290043f87b8efa6ba540bec5963013c517912Jim Grosbach}
68917290043f87b8efa6ba540bec5963013c517912Jim Grosbach
6995b2c7da5e83670881270c1cd231a240be0556d9Chris Lattnernamespace {
704a071d667d995b00e7853243ff9c7c1269324478Chris Lattner  class ARMAsmPrinter : public AsmPrinter {
71a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
72a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
73a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// make the right decision when printing asm code for different targets.
74a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    const ARMSubtarget *Subtarget;
75a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
76a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    /// AFI - Keep a pointer to ARMFunctionInfo for the current
776d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    /// MachineFunction.
78a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    ARMFunctionInfo *AFI;
79a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
806d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    /// MCP - Keep a pointer to constantpool entries of the current
816d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    /// MachineFunction.
826d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    const MachineConstantPool *MCP;
836d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng
8457f0db833dc30404f1f5d28b23df326e520698ecBill Wendling  public:
85b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner    explicit ARMAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
86b23569aff0a6d2b231cb93cc4acd0ac060ba560fChris Lattner      : AsmPrinter(TM, Streamer), AFI(NULL), MCP(NULL) {
8757f0db833dc30404f1f5d28b23df326e520698ecBill Wendling      Subtarget = &TM.getSubtarget<ARMSubtarget>();
8857f0db833dc30404f1f5d28b23df326e520698ecBill Wendling    }
8957f0db833dc30404f1f5d28b23df326e520698ecBill Wendling
907bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    virtual const char *getPassName() const {
917bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola      return "ARM Assembly Printer";
927bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    }
93b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
94882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    void EmitJumpTable(const MachineInstr *MI);
95882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    void EmitJump2Table(const MachineInstr *MI);
9697f06937449c593a248dbbb1365e6ae408fb9decChris Lattner    void printInstructionThroughMCStreamer(const MachineInstr *MI);
97b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
987bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
9935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
100a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                      const char *Modifier = 0);
10135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printSOImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
10235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printSOImm2PartOperand(const MachineInstr *MI, int OpNum,
10335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                raw_ostream &O);
10435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printSORegOperand(const MachineInstr *MI, int OpNum,
10535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                           raw_ostream &O);
10635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode2Operand(const MachineInstr *MI, int OpNum,
10735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
10835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNum,
10935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
11035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode3Operand(const MachineInstr *MI, int OpNum,
11135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
11235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode3OffsetOperand(const MachineInstr *MI, int OpNum,
11335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
11435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode4Operand(const MachineInstr *MI, int OpNum,raw_ostream &O,
115a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                               const char *Modifier = 0);
11635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode5Operand(const MachineInstr *MI, int OpNum,raw_ostream &O,
117a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                               const char *Modifier = 0);
11835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode6Operand(const MachineInstr *MI, int OpNum,
11935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
12035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode6OffsetOperand(const MachineInstr *MI, int OpNum,
12135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
122055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    void printAddrModePCOperand(const MachineInstr *MI, int OpNum,
12335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                raw_ostream &O,
124a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                const char *Modifier = 0);
125eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    void printBitfieldInvMaskImmOperand(const MachineInstr *MI, int OpNum,
126eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson                                        raw_ostream &O);
1271adc40cac314b0a77b790b094bca146a3a868452Johnny Chen    void printMemBOption(const MachineInstr *MI, int OpNum,
1281adc40cac314b0a77b790b094bca146a3a868452Johnny Chen                         raw_ostream &O);
12922f5dc79c05d69391b17e14ed912aa8e98a63027Bob Wilson    void printShiftImmOperand(const MachineInstr *MI, int OpNum,
130eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson                              raw_ostream &O);
13135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner
13235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbS4ImmOperand(const MachineInstr *MI, int OpNum,
13335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                raw_ostream &O);
13435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbITMask(const MachineInstr *MI, int OpNum, raw_ostream &O);
13535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNum,
13635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
137055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNum,
13835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O,
139a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                      unsigned Scale);
14035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeS1Operand(const MachineInstr *MI, int OpNum,
14135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
14235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNum,
14335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
14435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNum,
14535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
14635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNum,
14735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
14835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner
14935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2SOOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
15035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm12Operand(const MachineInstr *MI, int OpNum,
15135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
15235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm8Operand(const MachineInstr *MI, int OpNum,
15335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                    raw_ostream &O);
15435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm8s4Operand(const MachineInstr *MI, int OpNum,
15535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O);
15635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm8OffsetOperand(const MachineInstr *MI, int OpNum,
15735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O);
15835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm8s4OffsetOperand(const MachineInstr *MI, int OpNum,
15935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                            raw_ostream &O) {}
16035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeSoRegOperand(const MachineInstr *MI, int OpNum,
16135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
16235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner
16335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printCPSOptionOperand(const MachineInstr *MI, int OpNum,
16435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O) {}
16535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printMSRMaskOperand(const MachineInstr *MI, int OpNum,
16635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                             raw_ostream &O) {}
16735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printNegZeroOperand(const MachineInstr *MI, int OpNum,
16835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                             raw_ostream &O) {}
16935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printPredicateOperand(const MachineInstr *MI, int OpNum,
17035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
17135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printMandatoryPredicateOperand(const MachineInstr *MI, int OpNum,
17235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                        raw_ostream &O);
17335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printSBitModifierOperand(const MachineInstr *MI, int OpNum,
17435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                  raw_ostream &O);
17535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printPCLabel(const MachineInstr *MI, int OpNum,
17635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                      raw_ostream &O);
17735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printRegisterList(const MachineInstr *MI, int OpNum,
17835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                           raw_ostream &O);
179055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    void printCPInstOperand(const MachineInstr *MI, int OpNum,
18035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                            raw_ostream &O,
181a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                            const char *Modifier);
18235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printJTBlockOperand(const MachineInstr *MI, int OpNum,
18335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                             raw_ostream &O);
18435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printJT2BlockOperand(const MachineInstr *MI, int OpNum,
18535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                              raw_ostream &O);
18635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printTBAddrMode(const MachineInstr *MI, int OpNum,
18735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                         raw_ostream &O);
18835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printNoHashImmediate(const MachineInstr *MI, int OpNum,
18935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                              raw_ostream &O);
19035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printVFPf32ImmOperand(const MachineInstr *MI, int OpNum,
19135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
19235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printVFPf64ImmOperand(const MachineInstr *MI, int OpNum,
19335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
1941a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson    void printNEONModImmOperand(const MachineInstr *MI, int OpNum,
1951a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson                                raw_ostream &O);
19654c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson
197055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
198c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                 unsigned AsmVariant, const char *ExtraCode,
199c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                 raw_ostream &O);
200055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
201224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson                                       unsigned AsmVariant,
202c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                       const char *ExtraCode, raw_ostream &O);
2037bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
20435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen
205d95148f073c31924f275a34296da52a7cdefad91Chris Lattner    static const char *getRegisterName(unsigned RegNo);
20605af2616d0df19638e799d3e7afadea26d96a4baChris Lattner
207a786ceac5c888761d83d84d35eb16150be57cc6eChris Lattner    virtual void EmitInstruction(const MachineInstr *MI);
2087bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    bool runOnMachineFunction(MachineFunction &F);
209b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
210a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattner    virtual void EmitConstantPool() {} // we emit constant pools customly!
211953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner    virtual void EmitFunctionEntryLabel();
212812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson    void EmitStartOfAsmFile(Module &M);
2134a071d667d995b00e7853243ff9c7c1269324478Chris Lattner    void EmitEndOfAsmFile(Module &M);
214a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
21559135f49e1699daec9a43fc2d15715d55b910f54Devang Patel    MachineLocation getDebugValueLocation(const MachineInstr *MI) const {
21659135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      MachineLocation Location;
21759135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      assert (MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
21859135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      // Frame address.  Currently handles register +- offset only.
21959135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm())
22059135f49e1699daec9a43fc2d15715d55b910f54Devang Patel        Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
22159135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      else {
22259135f49e1699daec9a43fc2d15715d55b910f54Devang Patel        DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
22359135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      }
22459135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      return Location;
22559135f49e1699daec9a43fc2d15715d55b910f54Devang Patel    }
22659135f49e1699daec9a43fc2d15715d55b910f54Devang Patel
227917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    virtual unsigned getISAEncoding() {
228917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      // ARM/Darwin adds ISA to the DWARF info for each function.
229917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      if (!Subtarget->isTargetDarwin())
230917290043f87b8efa6ba540bec5963013c517912Jim Grosbach        return 0;
231917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      return Subtarget->isThumb() ?
232917290043f87b8efa6ba540bec5963013c517912Jim Grosbach        llvm::ARM::DW_ISA_ARM_thumb : llvm::ARM::DW_ISA_ARM_arm;
233917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    }
234917290043f87b8efa6ba540bec5963013c517912Jim Grosbach
2350890cf124f00da3dc943c1882f4221955e0281edChris Lattner    MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
2360890cf124f00da3dc943c1882f4221955e0281edChris Lattner                                          const MachineBasicBlock *MBB) const;
2370890cf124f00da3dc943c1882f4221955e0281edChris Lattner    MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const;
238bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner
239433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    MCSymbol *GetARMSJLJEHLabel(void) const;
240433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
241711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    /// EmitMachineConstantPoolValue - Print a machine constantpool value to
242711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    /// the .s file.
243a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
2449d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      SmallString<128> Str;
2459d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      raw_svector_ostream OS(Str);
2469d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      EmitMachineConstantPoolValue(MCPV, OS);
2479d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText(OS.str());
2489d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    }
249b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
2509d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV,
2519d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                                      raw_ostream &O) {
252ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      switch (TM.getTargetData()->getTypeAllocSize(MCPV->getType())) {
253ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      case 1: O << MAI->getData8bitsDirective(0); break;
254ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      case 2: O << MAI->getData16bitsDirective(0); break;
255ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      case 4: O << MAI->getData32bitsDirective(0); break;
256ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      default: assert(0 && "Unknown CPV size");
257ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      }
258a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
259711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng      ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
2603fb2b1ede30193b59a651328a946174196b20610Jim Grosbach
2613fb2b1ede30193b59a651328a946174196b20610Jim Grosbach      if (ACPV->isLSDA()) {
2629d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner        O << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
26328989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      } else if (ACPV->isBlockAddress()) {
2640752cda4de245978e14d806831abba4506272cd0Chris Lattner        O << *GetBlockAddressSymbol(ACPV->getBlockAddress());
26528989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      } else if (ACPV->isGlobalValue()) {
26646510a73e977273ec67747eb34cbdb43f815e451Dan Gohman        const GlobalValue *GV = ACPV->getGV();
267e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        bool isIndirect = Subtarget->isTargetDarwin() &&
26863476a80404125e5196b6c09113c1d4796da0604Evan Cheng          Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
269e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        if (!isIndirect)
270d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner          O << *Mang->getSymbol(GV);
271e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        else {
272e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng          // FIXME: Remove this when Darwin transition to @GOT like syntax.
2737a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner          MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
27410b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner          O << *Sym;
275b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
276b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner          MachineModuleInfoMachO &MMIMachO =
277b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner            MMI->getObjFileInfo<MachineModuleInfoMachO>();
278cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling          MachineModuleInfoImpl::StubValueTy &StubSym =
279b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner            GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(Sym) :
280b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner                                        MMIMachO.getGVStubEntry(Sym);
281cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling          if (StubSym.getPointer() == 0)
282cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling            StubSym = MachineModuleInfoImpl::
283d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner              StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
284e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        }
28528989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      } else {
28628989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson        assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
28710b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner        O << *GetExternalSymbolSymbol(ACPV->getSymbol());
28828989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      }
289e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
2900ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
29164f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio      if (ACPV->getPCAdjustment() != 0) {
29233adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner        O << "-(" << MAI->getPrivateGlobalPrefix() << "PC"
293e7e0d62efda2445b735052ca45bd74fb002e34c3Evan Cheng          << getFunctionNumber() << "_"  << ACPV->getLabelId()
29464f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio          << "+" << (unsigned)ACPV->getPCAdjustment();
29564f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio         if (ACPV->mustAddCurrentAddress())
29664f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio           O << "-.";
2978b3787586ed92df55131ad38c16646b7eba401a0Chris Lattner         O << ')';
29864f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio      }
299a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
3007bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  };
3017bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace
3027bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
3037bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMGenAsmWriter.inc"
3047bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
305953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattnervoid ARMAsmPrinter::EmitFunctionEntryLabel() {
306953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  if (AFI->isThumbFunction()) {
3079d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.EmitRawText(StringRef("\t.code\t16"));
3080752cda4de245978e14d806831abba4506272cd0Chris Lattner    if (!Subtarget->isTargetDarwin())
3099d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText(StringRef("\t.thumb_func"));
3100752cda4de245978e14d806831abba4506272cd0Chris Lattner    else {
3110752cda4de245978e14d806831abba4506272cd0Chris Lattner      // This needs to emit to a temporary string to get properly quoted
3120752cda4de245978e14d806831abba4506272cd0Chris Lattner      // MCSymbols when they have spaces in them.
3130752cda4de245978e14d806831abba4506272cd0Chris Lattner      SmallString<128> Tmp;
3140752cda4de245978e14d806831abba4506272cd0Chris Lattner      raw_svector_ostream OS(Tmp);
3150752cda4de245978e14d806831abba4506272cd0Chris Lattner      OS << "\t.thumb_func\t" << *CurrentFnSym;
3160752cda4de245978e14d806831abba4506272cd0Chris Lattner      OutStreamer.EmitRawText(OS.str());
3170752cda4de245978e14d806831abba4506272cd0Chris Lattner    }
318953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  }
319b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
320953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  OutStreamer.EmitLabel(CurrentFnSym);
321953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner}
322953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner
323a8e2989ece6dc46df59b0768184028257f913843Evan Cheng/// runOnMachineFunction - This uses the printInstruction()
3247bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction.
3257bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola///
3267bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
327a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  AFI = MF.getInfo<ARMFunctionInfo>();
3286d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng  MCP = MF.getConstantPool();
329a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
330d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner  return AsmPrinter::runOnMachineFunction(MF);
33132bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola}
33232bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola
333055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
33435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                 raw_ostream &O, const char *Modifier) {
335055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
3365cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov  unsigned TF = MO.getTargetFlags();
3375cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov
3382f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  switch (MO.getType()) {
3398bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner  default:
3408bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(0 && "<unknown operand type>");
3415bafff36c798608a189c517d37527e4a38863071Bob Wilson  case MachineOperand::MO_Register: {
3425bafff36c798608a189c517d37527e4a38863071Bob Wilson    unsigned Reg = MO.getReg();
3438bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(TargetRegisterInfo::isPhysicalRegister(Reg));
344de0ae8f83dd8eabc831b0631c20ffa3b53a774f2Bob Wilson    if (Modifier && strcmp(Modifier, "lane") == 0) {
345a4c3c8f28d9465dc7c42eb43c2377530f1821574Jim Grosbach      unsigned RegNum = getARMRegisterNumbering(Reg);
3469d1c1ada213c80135fbdda704175aae689daa6f9Chris Lattner      unsigned DReg =
347e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen        TM.getRegisterInfo()->getMatchingSuperReg(Reg,
348e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen          RegNum & 1 ? ARM::ssub_1 : ARM::ssub_0, &ARM::DPR_VFP2RegClass);
3498bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner      O << getRegisterName(DReg) << '[' << (RegNum & 1) << ']';
3508bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    } else {
351e8ea011cc766b37a957d5966655526096bf49feaAnton Korobeynikov      assert(!MO.getSubReg() && "Subregs should be eliminated!");
3528bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner      O << getRegisterName(Reg);
3538bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    }
3542f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
3555bafff36c798608a189c517d37527e4a38863071Bob Wilson  }
356a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_Immediate: {
3575adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng    int64_t Imm = MO.getImm();
358632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << '#';
3595cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
3605cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov        (TF & ARMII::MO_LO16))
3615cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
3625cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
3635cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov             (TF & ARMII::MO_HI16))
3645cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
365632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << Imm;
3662f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
367a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
3682f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_MachineBasicBlock:
3691b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner    O << *MO.getMBB()->getSymbol();
3702f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    return;
37184b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola  case MachineOperand::MO_GlobalAddress: {
372a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    bool isCallOp = Modifier && !strcmp(Modifier, "call");
37346510a73e977273ec67747eb34cbdb43f815e451Dan Gohman    const GlobalValue *GV = MO.getGlobal();
3745cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov
3755cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
3765cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov        (TF & ARMII::MO_LO16))
3775cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
3785cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
3795cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov             (TF & ARMII::MO_HI16))
3805cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
381d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner    O << *Mang->getSymbol(GV);
3827751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
3830c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner    printOffset(MO.getOffset(), O);
3847751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
3850ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio    if (isCallOp && Subtarget->isTargetELF() &&
3860ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio        TM.getRelocationModel() == Reloc::PIC_)
3870ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
3882f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
389a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
390a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_ExternalSymbol: {
391a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    bool isCallOp = Modifier && !strcmp(Modifier, "call");
39210b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner    O << *GetExternalSymbolSymbol(MO.getSymbolName());
393b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
3940ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio    if (isCallOp && Subtarget->isTargetELF() &&
3950ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio        TM.getRelocationModel() == Reloc::PIC_)
3960ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
3972f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
398a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
3992f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_ConstantPoolIndex:
4001b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetCPISymbol(MO.getIndex());
4012f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
402a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_JumpTableIndex:
4031b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetJTISymbol(MO.getIndex());
404a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    break;
4052f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  }
4067bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
4077bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
40835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnerstatic void printSOImm(raw_ostream &O, int64_t V, bool VerboseAsm,
40933adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner                       const MCAsmInfo *MAI) {
410e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng  // Break it up into two parts that make up a shifter immediate.
411e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng  V = ARM_AM::getSOImmVal(V);
412e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng  assert(V != -1 && "Not a valid so_imm value!");
413e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng
414c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  unsigned Imm = ARM_AM::getSOImmValImm(V);
415c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  unsigned Rot = ARM_AM::getSOImmValRot(V);
4167751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
417a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Print low-level immediate formation info, per
418a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // A5.1.3: "Data-processing operands - Immediate".
419a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Rot) {
420a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "#" << Imm << ", " << Rot;
421a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Pretty printed version.
42239382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng    if (VerboseAsm) {
42335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      O << "\t" << MAI->getCommentString() << ' ';
42439382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng      O << (int)ARM_AM::rotr32(Imm, Rot);
42539382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng    }
426a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
427a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "#" << Imm;
428a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
429a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
430a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
431c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
432c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// immediate in bits 0-7.
43335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum,
43435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O) {
435c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
436d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  assert(MO.isImm() && "Not a valid so_imm value!");
4373f53c8398d81065736a784469c9dd5afff85673fChris Lattner  printSOImm(O, MO.getImm(), isVerbose(), MAI);
438c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng}
439c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng
4409092213a5e50d4991f900d2df009d27bddfd9941Evan Cheng/// printSOImm2PartOperand - SOImm is broken into two pieces using a 'mov'
4419092213a5e50d4991f900d2df009d27bddfd9941Evan Cheng/// followed by an 'orr' to materialize.
44235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum,
44335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
444c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
445d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  assert(MO.isImm() && "Not a valid so_imm value!");
4469a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner  unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImm());
4479a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner  unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImm());
4483f53c8398d81065736a784469c9dd5afff85673fChris Lattner  printSOImm(O, V1, isVerbose(), MAI);
4495e148a37d3432f83ccc4dbebe08d4f1b4717034cEvan Cheng  O << "\n\torr";
45035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printPredicateOperand(MI, 2, O);
451162e30921da0ce1863672d4ca5fef541498fe6beEvan Cheng  O << "\t";
45235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, 0, O);
453c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  O << ", ";
45435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, 0, O);
455c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  O << ", ";
4563f53c8398d81065736a784469c9dd5afff85673fChris Lattner  printSOImm(O, V2, isVerbose(), MAI);
457c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng}
458c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng
459a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// so_reg is a 4-operand unit corresponding to register forms of the A5.1
460a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// "Addressing Mode 1 - Data-processing operands" forms.  This includes:
4619cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng//    REG 0   0           - e.g. R5
4629cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng//    REG REG 0,SH_OPC    - e.g. R5, ROR R3
463a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
46435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op,
46535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O) {
466a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
467a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
468a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
469a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
470762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << getRegisterName(MO1.getReg());
471a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
472a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Print the shift opc.
4731d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm());
4741d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
475a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (MO2.getReg()) {
4761d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson    O << ' ' << getRegisterName(MO2.getReg());
477a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
4781d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  } else if (ShOpc != ARM_AM::rrx) {
4791d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson    O << " #" << ARM_AM::getSORegOffset(MO3.getImm());
480a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
481a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
482a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
48335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op,
48435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
485a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
486a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
487a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
488a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
489d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
49035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, Op, O);
491a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
492a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
493a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
494762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
495a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
496a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!MO2.getReg()) {
4979e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0.
498a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << ", #"
4999e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen        << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
500a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        << ARM_AM::getAM2Offset(MO3.getImm());
501a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "]";
502a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
503a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
504a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
505a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << ", "
5069e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
507762ccea600158bb317dcccdff3303e942426cb71Chris Lattner    << getRegisterName(MO2.getReg());
508e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
509a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
510a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", "
5119a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
512a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << " #" << ShImm;
513a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
514a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
515a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
51635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op,
51735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O) {
518a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
519a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
520a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
521a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!MO1.getReg()) {
522bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng    unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
523bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng    O << "#"
5249e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen      << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
525bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng      << ImmOffs;
526a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
527a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
528a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
5299e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen  O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
530762ccea600158bb317dcccdff3303e942426cb71Chris Lattner    << getRegisterName(MO1.getReg());
531e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
532a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
533a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", "
5349a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm()))
535a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << " #" << ShImm;
536a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
537a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
53835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op,
53935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
540a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
541a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
542a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
543e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
5446f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
545762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
546a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
547a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (MO2.getReg()) {
548a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", "
549a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << (char)ARM_AM::getAM3Op(MO3.getImm())
550762ccea600158bb317dcccdff3303e942426cb71Chris Lattner      << getRegisterName(MO2.getReg())
551a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << "]";
552a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
553a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
554e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
555a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
556a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", #"
5579e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen      << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()))
558a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << ImmOffs;
559a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
560a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
561a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
56235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op,
56335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O){
564a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
565a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
566a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
567a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (MO1.getReg()) {
568a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << (char)ARM_AM::getAM3Op(MO2.getImm())
569762ccea600158bb317dcccdff3303e942426cb71Chris Lattner      << getRegisterName(MO1.getReg());
570a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
571a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
572a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
573a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
574a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "#"
5759e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()))
576a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    << ImmOffs;
577a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
578e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
579a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
58035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O,
581a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                          const char *Modifier) {
582a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
583a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
584a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Modifier && strcmp(Modifier, "submode") == 0) {
585ea7f22c31d0d12923eaab6840322431cc0222ae9Bob Wilson    O << ARM_AM::getAMSubModeStr(Mode);
586d77c7aba83bb290b9b62ede38b6ddbc9b790c6efEvan Cheng  } else if (Modifier && strcmp(Modifier, "wide") == 0) {
587d77c7aba83bb290b9b62ede38b6ddbc9b790c6efEvan Cheng    ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
588d77c7aba83bb290b9b62ede38b6ddbc9b790c6efEvan Cheng    if (Mode == ARM_AM::ia)
589d77c7aba83bb290b9b62ede38b6ddbc9b790c6efEvan Cheng      O << ".w";
590a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
59135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, Op, O);
592a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
593a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
594a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
595a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
59635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O,
597a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                          const char *Modifier) {
598a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
599a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
600a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
601d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
60235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, Op, O);
603a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
604a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
605e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
6066f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
607a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
608762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
609e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
610a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
611a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", #"
6129e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen      << ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2.getImm()))
613a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << ImmOffs*4;
614a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
615a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
616a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
617a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
61835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode6Operand(const MachineInstr *MI, int Op,
61935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
6208b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson  const MachineOperand &MO1 = MI->getOperand(Op);
6218b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson  const MachineOperand &MO2 = MI->getOperand(Op+1);
6228b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson
6238a5ec86a3d4d599984e52c0c5a3a6a436607cf3eJim Grosbach  O << "[" << getRegisterName(MO1.getReg());
624226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson  if (MO2.getImm()) {
625bce3dbd9be29a42f32eb888086050cd620f2133bAnton Korobeynikov    // FIXME: Both darwin as and GNU as violate ARM docs here.
626273ff31e134d48c8247e981d30e214e82568ff86Bob Wilson    O << ", :" << (MO2.getImm() << 3);
6278a5ec86a3d4d599984e52c0c5a3a6a436607cf3eJim Grosbach  }
6288a5ec86a3d4d599984e52c0c5a3a6a436607cf3eJim Grosbach  O << "]";
629226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson}
630a43e6bf69093b9870548e7d782ea148e2ddd6449Bob Wilson
63135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode6OffsetOperand(const MachineInstr *MI, int Op,
63235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O){
633226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson  const MachineOperand &MO = MI->getOperand(Op);
634226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson  if (MO.getReg() == 0)
635226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson    O << "!";
636226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson  else
637226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson    O << ", " << getRegisterName(MO.getReg());
6388b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson}
6398b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson
640a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
64135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O,
642a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                           const char *Modifier) {
643a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Modifier && strcmp(Modifier, "label") == 0) {
64435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printPCLabel(MI, Op+1, O);
645a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
646a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
647a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
648a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
6496f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
6509e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen  O << "[pc, " << getRegisterName(MO1.getReg()) << "]";
651a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
652a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
653a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
65435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printBitfieldInvMaskImmOperand(const MachineInstr *MI, int Op,
65535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                              raw_ostream &O) {
656f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng  const MachineOperand &MO = MI->getOperand(Op);
657f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng  uint32_t v = ~MO.getImm();
6589e03cbefc5b3b8772a18d9bd25593ce62137ac85Evan Cheng  int32_t lsb = CountTrailingZeros_32(v);
659b825aaa0289206a63f7e6ce7b5ca7c2d6a2c063eNick Lewycky  int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb;
660f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng  assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
661f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng  O << "#" << lsb << ", #" << width;
662f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng}
663f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng
6641adc40cac314b0a77b790b094bca146a3a868452Johnny Chenvoid
6651adc40cac314b0a77b790b094bca146a3a868452Johnny ChenARMAsmPrinter::printMemBOption(const MachineInstr *MI, int OpNum,
6661adc40cac314b0a77b790b094bca146a3a868452Johnny Chen                               raw_ostream &O) {
6671adc40cac314b0a77b790b094bca146a3a868452Johnny Chen  unsigned val = MI->getOperand(OpNum).getImm();
6681adc40cac314b0a77b790b094bca146a3a868452Johnny Chen  O << ARM_MB::MemBOptToString(val);
6691adc40cac314b0a77b790b094bca146a3a868452Johnny Chen}
6701adc40cac314b0a77b790b094bca146a3a868452Johnny Chen
67122f5dc79c05d69391b17e14ed912aa8e98a63027Bob Wilsonvoid ARMAsmPrinter::printShiftImmOperand(const MachineInstr *MI, int OpNum,
672eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson                                         raw_ostream &O) {
673eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  unsigned ShiftOp = MI->getOperand(OpNum).getImm();
674eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  ARM_AM::ShiftOpc Opc = ARM_AM::getSORegShOp(ShiftOp);
675eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  switch (Opc) {
676eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  case ARM_AM::no_shift:
677eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    return;
678eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  case ARM_AM::lsl:
679eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    O << ", lsl #";
680eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    break;
681eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  case ARM_AM::asr:
682eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    O << ", asr #";
683eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    break;
684eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  default:
68522f5dc79c05d69391b17e14ed912aa8e98a63027Bob Wilson    assert(0 && "unexpected shift opcode for shift immediate operand");
686eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  }
687eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  O << ARM_AM::getSORegOffset(ShiftOp);
688eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson}
689eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson
690055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===//
691055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
69235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printThumbS4ImmOperand(const MachineInstr *MI, int Op,
69335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
6942ef9c8a43d1030bf65cafedf4b4b3f04d30180ceEvan Cheng  O << "#" <<  MI->getOperand(Op).getImm() * 4;
6952ef9c8a43d1030bf65cafedf4b4b3f04d30180ceEvan Cheng}
6962ef9c8a43d1030bf65cafedf4b4b3f04d30180ceEvan Cheng
697f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Chengvoid
69835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbITMask(const MachineInstr *MI, int Op,
69935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                raw_ostream &O) {
700e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  // (3 - the number of trailing zeros) is the number of then / else.
701e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  unsigned Mask = MI->getOperand(Op).getImm();
7029e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen  unsigned CondBit0 = Mask >> 4 & 1;
703e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  unsigned NumTZ = CountTrailingZeros_32(Mask);
704e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  assert(NumTZ <= 3 && "Invalid IT mask!");
70506e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
7069e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    bool T = ((Mask >> Pos) & 1) == CondBit0;
707e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng    if (T)
708e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng      O << 't';
709e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng    else
710e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng      O << 'e';
711e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  }
712e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng}
713e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng
714e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Chengvoid
71535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op,
71635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
717a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
718a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
719762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
720762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << ", " << getRegisterName(MO2.getReg()) << "]";
721a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
722a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
723a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
724a8e2989ece6dc46df59b0768184028257f913843Evan ChengARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
72535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                            raw_ostream &O,
726a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                            unsigned Scale) {
727a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
728cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
729cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
730a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
731d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
73235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, Op, O);
733a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
734a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
735a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
736762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
737cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  if (MO3.getReg())
738762ccea600158bb317dcccdff3303e942426cb71Chris Lattner    O << ", " << getRegisterName(MO3.getReg());
7394b6bbe1e9c40fb58eccaf3671432661016663aabEvan Cheng  else if (unsigned ImmOffs = MO2.getImm())
7409e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << ImmOffs * Scale;
741a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
742a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
743a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
744a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
74535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op,
74635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
74735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printThumbAddrModeRI5Operand(MI, Op, O, 1);
748a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
749a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
75035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op,
75135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
75235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printThumbAddrModeRI5Operand(MI, Op, O, 2);
753a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
754a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
75535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op,
75635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
75735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printThumbAddrModeRI5Operand(MI, Op, O, 4);
758a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
759a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
76035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op,
76135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O) {
762a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
763a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
764762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
765a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ImmOffs = MO2.getImm())
7669e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << ImmOffs*4;
767a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
7687bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
7697bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
770055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===//
771055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
7729cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
7739cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng// register with shift forms.
7749cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng// REG 0   0           - e.g. R5
7759cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng// REG IMM, SH_OPC     - e.g. R5, LSL #3
77635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printT2SOOperand(const MachineInstr *MI, int OpNum,
77735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O) {
7789cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
7799cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
7809cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng
7819cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  unsigned Reg = MO1.getReg();
7829cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  assert(TargetRegisterInfo::isPhysicalRegister(Reg));
783762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << getRegisterName(Reg);
7849cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng
7859cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  // Print the shift opc.
7869cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  assert(MO2.isImm() && "Not a valid t2_so_reg value!");
7871d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO2.getImm());
7881d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
7891d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  if (ShOpc != ARM_AM::rrx)
7901d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson    O << " #" << ARM_AM::getSORegOffset(MO2.getImm());
7919cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng}
7929cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng
793055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printT2AddrModeImm12Operand(const MachineInstr *MI,
79435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                int OpNum,
79535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O) {
796055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
797055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
798055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
799762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
800055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
801055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  unsigned OffImm = MO2.getImm();
802055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  if (OffImm)  // Don't print +0.
8039e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << OffImm;
804055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  O << "]";
805055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng}
806055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
807055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printT2AddrModeImm8Operand(const MachineInstr *MI,
80835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                               int OpNum,
80935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                               raw_ostream &O) {
810055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
811055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
812055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
813762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
814055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
815055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  int32_t OffImm = (int32_t)MO2.getImm();
816055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  // Don't print +0.
817055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  if (OffImm < 0)
818055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    O << ", #-" << -OffImm;
819055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  else if (OffImm > 0)
8209e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << OffImm;
821055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  O << "]";
822055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng}
823055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
8245c874172ac8fd563867efc54022ac4c1571e1313Evan Chengvoid ARMAsmPrinter::printT2AddrModeImm8s4Operand(const MachineInstr *MI,
82535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                 int OpNum,
82635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                 raw_ostream &O) {
8275c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
8285c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
8295c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng
830762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
8315c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng
8325c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  int32_t OffImm = (int32_t)MO2.getImm() / 4;
8335c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  // Don't print +0.
8345c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  if (OffImm < 0)
835a64ce4591762b93030cd2a2ff202bbd5badfecddEvan Cheng    O << ", #-" << -OffImm * 4;
8365c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  else if (OffImm > 0)
8379e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << OffImm * 4;
8385c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  O << "]";
8395c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng}
8405c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng
841e88d5cee9d6b02bc786df806395a718464908064Evan Chengvoid ARMAsmPrinter::printT2AddrModeImm8OffsetOperand(const MachineInstr *MI,
84235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                     int OpNum,
84335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                     raw_ostream &O) {
844e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
845e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  int32_t OffImm = (int32_t)MO1.getImm();
846e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  // Don't print +0.
847e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  if (OffImm < 0)
848e88d5cee9d6b02bc786df806395a718464908064Evan Cheng    O << "#-" << -OffImm;
849e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  else if (OffImm > 0)
8509e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << "#" << OffImm;
8519e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen}
8529e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen
853055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printT2AddrModeSoRegOperand(const MachineInstr *MI,
85435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                int OpNum,
85535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O) {
856055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
857055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
858055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO3 = MI->getOperand(OpNum+2);
859055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
860762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
861055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
8623a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng  assert(MO2.getReg() && "Invalid so_reg load / store address!");
863762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << ", " << getRegisterName(MO2.getReg());
8649cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng
8653a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng  unsigned ShAmt = MO3.getImm();
8663a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng  if (ShAmt) {
8673a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng    assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
8683a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng    O << ", lsl #" << ShAmt;
869055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  }
870055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  O << "]";
871055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng}
872055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
873055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
874055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===//
875055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
87635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printPredicateOperand(const MachineInstr *MI, int OpNum,
87735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
878055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
87944bec52b1b7e9a3ac1efbae90db240b8c1ca2ad4Evan Cheng  if (CC != ARMCC::AL)
88044bec52b1b7e9a3ac1efbae90db240b8c1ca2ad4Evan Cheng    O << ARMCondCodeToString(CC);
8817bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
8827bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
8839d3acaa1a015c4499595eaff529686a517c14e15Johnny Chenvoid ARMAsmPrinter::printMandatoryPredicateOperand(const MachineInstr *MI,
88435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                   int OpNum,
88535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                   raw_ostream &O) {
8869d3acaa1a015c4499595eaff529686a517c14e15Johnny Chen  ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
8879d3acaa1a015c4499595eaff529686a517c14e15Johnny Chen  O << ARMCondCodeToString(CC);
8889d3acaa1a015c4499595eaff529686a517c14e15Johnny Chen}
8899d3acaa1a015c4499595eaff529686a517c14e15Johnny Chen
89035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printSBitModifierOperand(const MachineInstr *MI, int OpNum,
89135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                             raw_ostream &O){
892055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  unsigned Reg = MI->getOperand(OpNum).getReg();
893dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng  if (Reg) {
894dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng    assert(Reg == ARM::CPSR && "Expect ARM CPSR register!");
895dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng    O << 's';
896dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng  }
897dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng}
898dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng
89935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int OpNum,
90035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                 raw_ostream &O) {
901055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  int Id = (int)MI->getOperand(OpNum).getImm();
902e7e0d62efda2445b735052ca45bd74fb002e34c3Evan Cheng  O << MAI->getPrivateGlobalPrefix()
903e7e0d62efda2445b735052ca45bd74fb002e34c3Evan Cheng    << "PC" << getFunctionNumber() << "_" << Id;
904a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
905a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
90635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int OpNum,
90735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O) {
908a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "{";
909815baebe1c8dc02accf128ae10dff9a1742d3244Bob Wilson  for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
9104b322e58b77d16f103d88a3af3a4ebd2675245a0Evan Cheng    if (MI->getOperand(i).isImplicit())
9114b322e58b77d16f103d88a3af3a4ebd2675245a0Evan Cheng      continue;
912815baebe1c8dc02accf128ae10dff9a1742d3244Bob Wilson    if ((int)i != OpNum) O << ", ";
91335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, i, O);
914a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
915a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "}";
916a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
917a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
918055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNum,
91935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                       raw_ostream &O, const char *Modifier) {
920a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  assert(Modifier && "This operand only works with a modifier!");
921a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
922a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // data itself.
923a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!strcmp(Modifier, "label")) {
924055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    unsigned ID = MI->getOperand(OpNum).getImm();
9258e089a9e4d6b7aa2b3968c38644f926f60a7c670Chris Lattner    OutStreamer.EmitLabel(GetCPISymbol(ID));
926a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
927a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
928055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    unsigned CPI = MI->getOperand(OpNum).getIndex();
929a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
9306d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI];
931e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
932711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    if (MCPE.isMachineConstantPoolEntry()) {
933a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
934711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    } else {
935a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      EmitGlobalConstant(MCPE.Val.ConstVal);
936305b8a5f62c9d027f3d8a870fc12fc2abf69aeeaLauro Ramos Venancio    }
937a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
938a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
939a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
9400890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
9410890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
9420890cf124f00da3dc943c1882f4221955e0281edChris Lattner                            const MachineBasicBlock *MBB) const {
9430890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
9440890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
945bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2
9460890cf124f00da3dc943c1882f4221955e0281edChris Lattner    << "_set_" << MBB->getNumber();
9479b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
9480890cf124f00da3dc943c1882f4221955e0281edChris Lattner}
9490890cf124f00da3dc943c1882f4221955e0281edChris Lattner
9500890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
9510890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
9520890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
9530890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
954281e7767df71b3f727ade80a16ff0c4fe5a49dd9Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2;
9559b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
956bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner}
957bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner
958433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
959433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim GrosbachMCSymbol *ARMAsmPrinter::GetARMSJLJEHLabel(void) const {
960433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  SmallString<60> Name;
961433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "SJLJEH"
962433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    << getFunctionNumber();
963433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  return OutContext.GetOrCreateSymbol(Name.str());
964433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach}
965433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
96635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum,
96735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                        raw_ostream &O) {
96866ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  assert(!Subtarget->isThumb2() && "Thumb2 should use double-jump jumptables!");
96966ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng
970055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
971055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
972b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
9738aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner  unsigned JTI = MO1.getIndex();
9740890cf124f00da3dc943c1882f4221955e0281edChris Lattner  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
97503335350547b5d3521f9912d301bbb799d7eea31Chris Lattner  // Can't use EmitLabel until instprinter happens, label comes out in the wrong
97603335350547b5d3521f9912d301bbb799d7eea31Chris Lattner  // order.
977d4d188e5029801ef2a76ee756dcba49f313004f0Bob Wilson  O << "\n" << *JTISymbol << ":\n";
978a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
97933adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner  const char *JTEntryDirective = MAI->getData32bitsDirective();
980a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
9814542611bb9793e8376d7d5f33b4a1e2d11712894Dan Gohman  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
982a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
983a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
984cee63322eaccc2f1067bdf5eab506e440f867da1Chris Lattner  bool UseSet= MAI->hasSetDirective() && TM.getRelocationModel() == Reloc::PIC_;
985c324ecb7bc93a1f09db29851438ec5ee72b143ebEvan Cheng  SmallPtrSet<MachineBasicBlock*, 8> JTSets;
986a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
987a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    MachineBasicBlock *MBB = JTBBs[i];
98866ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng    bool isNew = JTSets.insert(MBB);
98966ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng
9900890cf124f00da3dc943c1882f4221955e0281edChris Lattner    if (UseSet && isNew) {
991cee63322eaccc2f1067bdf5eab506e440f867da1Chris Lattner      O << "\t.set\t"
9921f9b48ad87a5dab4a6c3805c369414c831e4451dJim Grosbach        << *GetARMSetPICJumpTableLabel2(JTI, MO2.getImm(), MBB) << ','
9931b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner        << *MBB->getSymbol() << '-' << *JTISymbol << '\n';
9940890cf124f00da3dc943c1882f4221955e0281edChris Lattner    }
995a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
996a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << JTEntryDirective << ' ';
997a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (UseSet)
9980890cf124f00da3dc943c1882f4221955e0281edChris Lattner      O << *GetARMSetPICJumpTableLabel2(JTI, MO2.getImm(), MBB);
9990890cf124f00da3dc943c1882f4221955e0281edChris Lattner    else if (TM.getRelocationModel() == Reloc::PIC_)
10001b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner      O << *MBB->getSymbol() << '-' << *JTISymbol;
10010890cf124f00da3dc943c1882f4221955e0281edChris Lattner    else
10021b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner      O << *MBB->getSymbol();
10030890cf124f00da3dc943c1882f4221955e0281edChris Lattner
1004d85ac4d07966a56b3101598f29393f4532acc50fEvan Cheng    if (i != e-1)
1005d85ac4d07966a56b3101598f29393f4532acc50fEvan Cheng      O << '\n';
1006a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
1007a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
1008a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
100935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printJT2BlockOperand(const MachineInstr *MI, int OpNum,
101035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                         raw_ostream &O) {
101166ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
101266ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
101366ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  unsigned JTI = MO1.getIndex();
1014b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
10150890cf124f00da3dc943c1882f4221955e0281edChris Lattner  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
1016b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
101703335350547b5d3521f9912d301bbb799d7eea31Chris Lattner  // Can't use EmitLabel until instprinter happens, label comes out in the wrong
101803335350547b5d3521f9912d301bbb799d7eea31Chris Lattner  // order.
1019d4d188e5029801ef2a76ee756dcba49f313004f0Bob Wilson  O << "\n" << *JTISymbol << ":\n";
102066ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng
102166ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
102266ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
102366ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
10245657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  bool ByteOffset = false, HalfWordOffset = false;
10255657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  if (MI->getOpcode() == ARM::t2TBB)
10265657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    ByteOffset = true;
10275657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  else if (MI->getOpcode() == ARM::t2TBH)
10285657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    HalfWordOffset = true;
10295657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng
103066ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
103166ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng    MachineBasicBlock *MBB = JTBBs[i];
10325657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    if (ByteOffset)
103333adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner      O << MAI->getData8bitsDirective();
10345657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    else if (HalfWordOffset)
103533adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner      O << MAI->getData16bitsDirective();
1036b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
10370890cf124f00da3dc943c1882f4221955e0281edChris Lattner    if (ByteOffset || HalfWordOffset)
10381b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner      O << '(' << *MBB->getSymbol() << "-" << *JTISymbol << ")/2";
10390890cf124f00da3dc943c1882f4221955e0281edChris Lattner    else
10401b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner      O << "\tb.w " << *MBB->getSymbol();
10410890cf124f00da3dc943c1882f4221955e0281edChris Lattner
104266ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng    if (i != e-1)
104366ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng      O << '\n';
104466ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  }
104566ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng}
104666ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng
104735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printTBAddrMode(const MachineInstr *MI, int OpNum,
104835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                    raw_ostream &O) {
1049762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[pc, " << getRegisterName(MI->getOperand(OpNum).getReg());
10505657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  if (MI->getOpcode() == ARM::t2TBH)
10515657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    O << ", lsl #1";
10525657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  O << ']';
10535657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng}
10545657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng
105535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printNoHashImmediate(const MachineInstr *MI, int OpNum,
105635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                         raw_ostream &O) {
10578e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov  O << MI->getOperand(OpNum).getImm();
10588e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov}
1059a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
106035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printVFPf32ImmOperand(const MachineInstr *MI, int OpNum,
106135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
106239382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng  const ConstantFP *FP = MI->getOperand(OpNum).getFPImm();
106377b02beb1fa3a96efc05081889d1ae4ffecb44a7Jim Grosbach  O << '#' << FP->getValueAPF().convertToFloat();
10643f53c8398d81065736a784469c9dd5afff85673fChris Lattner  if (isVerbose()) {
106535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    O << "\t\t" << MAI->getCommentString() << ' ';
106639382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng    WriteAsOperand(O, FP, /*PrintType=*/false);
106739382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng  }
106839382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng}
106939382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng
107035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printVFPf64ImmOperand(const MachineInstr *MI, int OpNum,
107135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
107239382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng  const ConstantFP *FP = MI->getOperand(OpNum).getFPImm();
107377b02beb1fa3a96efc05081889d1ae4ffecb44a7Jim Grosbach  O << '#' << FP->getValueAPF().convertToDouble();
10743f53c8398d81065736a784469c9dd5afff85673fChris Lattner  if (isVerbose()) {
107535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    O << "\t\t" << MAI->getCommentString() << ' ';
107639382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng    WriteAsOperand(O, FP, /*PrintType=*/false);
107739382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng  }
107839382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng}
107939382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng
10801a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilsonvoid ARMAsmPrinter::printNEONModImmOperand(const MachineInstr *MI, int OpNum,
10811a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson                                           raw_ostream &O) {
10826dce00ced45b5bd1b7f34fe6f2d70c50fc090664Bob Wilson  unsigned EncodedImm = MI->getOperand(OpNum).getImm();
10836dce00ced45b5bd1b7f34fe6f2d70c50fc090664Bob Wilson  unsigned EltBits;
10846dce00ced45b5bd1b7f34fe6f2d70c50fc090664Bob Wilson  uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits);
10851a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson  O << "#0x" << utohexstr(Val);
10861a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson}
10871a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson
1088055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
1089c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    unsigned AsmVariant, const char *ExtraCode,
1090c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    raw_ostream &O) {
1091a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Does this asm operand have a single letter operand modifier?
1092a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (ExtraCode && ExtraCode[0]) {
1093a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ExtraCode[1] != 0) return true; // Unknown modifier.
10948e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov
1095a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    switch (ExtraCode[0]) {
1096a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    default: return true;  // Unknown modifier.
10979b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'a': // Print as a memory address.
10989b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      if (MI->getOperand(OpNum).isReg()) {
1099762ccea600158bb317dcccdff3303e942426cb71Chris Lattner        O << "[" << getRegisterName(MI->getOperand(OpNum).getReg()) << "]";
11009b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson        return false;
11019b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      }
11029b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      // Fallthrough
11039b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'c': // Don't print "#" before an immediate operand.
11044f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson      if (!MI->getOperand(OpNum).isImm())
11054f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson        return true;
110635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      printNoHashImmediate(MI, OpNum, O);
11078f3434647d3d39b49475239e3be1b8afb06415cfBob Wilson      return false;
1108e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng    case 'P': // Print a VFP double precision register.
1109d831cda3e74235704f163d5a18352584d537517aEvan Cheng    case 'q': // Print a NEON quad precision register.
111035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      printOperand(MI, OpNum, O);
111123a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng      return false;
1112a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'Q':
1113a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'R':
1114d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson    case 'H':
111512616727c71721f480f69026d88a58a067d89824Evan Cheng      report_fatal_error("llvm does not support 'Q', 'R', and 'H' modifiers!");
1116d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson      return true;
111784f60b7359e1aa90794bb19de2bbf4d25dc2f01dEvan Cheng    }
1118a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
1119e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
112035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, OpNum, O);
1121a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  return false;
1122a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
1123a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1124224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilsonbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
1125055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng                                          unsigned OpNum, unsigned AsmVariant,
1126c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          const char *ExtraCode,
1127c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          raw_ostream &O) {
1128224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  if (ExtraCode && ExtraCode[0])
1129224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson    return true; // Unknown modifier.
1130765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson
1131765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  const MachineOperand &MO = MI->getOperand(OpNum);
1132765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  assert(MO.isReg() && "unexpected inline asm memory operand");
1133765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  O << "[" << getRegisterName(MO.getReg()) << "]";
1134224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  return false;
1135224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson}
1136224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson
1137a786ceac5c888761d83d84d35eb16150be57cc6eChris Lattnervoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
113897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  if (EnableMCInst) {
113997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner    printInstructionThroughMCStreamer(MI);
11407ad07c46362500f7291a92742569e94fd3538dfdChris Lattner    return;
114197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  }
1142b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
11437ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  if (MI->getOpcode() == ARM::CONSTPOOL_ENTRY)
11447ad07c46362500f7291a92742569e94fd3538dfdChris Lattner    EmitAlignment(2);
1145b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
11467ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  SmallString<128> Str;
11477ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  raw_svector_ostream OS(Str);
11483f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen  if (MI->getOpcode() == ARM::DBG_VALUE) {
11493f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    unsigned NOps = MI->getNumOperands();
11503f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    assert(NOps==4);
11513f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
11523f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    // cast away const; DIetc do not take const operands for some reason.
11533f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
11543f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << V.getName();
11553f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << " <- ";
11563f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    // Frame address.  Currently handles register +- offset only.
11573f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
11583f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS);
11593f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << ']';
11603f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << "+";
11613f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    printOperand(MI, NOps-2, OS);
1162e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  } else if (MI->getOpcode() == ARM::MOVs) {
1163e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    // FIXME: Thumb variants?
1164e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    const MachineOperand &Dst = MI->getOperand(0);
1165e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    const MachineOperand &MO1 = MI->getOperand(1);
1166e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    const MachineOperand &MO2 = MI->getOperand(2);
1167e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    const MachineOperand &MO3 = MI->getOperand(3);
1168e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach
1169e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    OS << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()));
1170e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    printSBitModifierOperand(MI, 6, OS);
1171e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    printPredicateOperand(MI, 4, OS);
1172e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach
1173e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    OS << '\t' << getRegisterName(Dst.getReg())
1174e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach       << ", " << getRegisterName(MO1.getReg());
1175e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach
1176e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    if (ARM_AM::getSORegShOp(MO3.getImm()) != ARM_AM::rrx) {
1177e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach      OS << ", ";
1178e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach
1179e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach      if (MO2.getReg()) {
1180e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach        OS << getRegisterName(MO2.getReg());
1181e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach        assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
1182e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach      } else {
1183e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach        OS << "#" << ARM_AM::getSORegOffset(MO3.getImm());
1184e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach      }
1185e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    }
1186e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  } else
1187e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  // A8.6.123 PUSH
1188e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  if ((MI->getOpcode() == ARM::STM_UPD || MI->getOpcode() == ARM::t2STM_UPD) &&
1189532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach      MI->getOperand(0).getReg() == ARM::SP &&
1190532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach      ARM_AM::getAM4SubMode(MI->getOperand(2).getImm()) == ARM_AM::db) {
1191532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    OS << '\t' << "push";
1192532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    printPredicateOperand(MI, 3, OS);
1193532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    OS << '\t';
1194532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    printRegisterList(MI, 5, OS);
1195e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  } else
1196e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  // A8.6.122 POP
1197e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  if ((MI->getOpcode() == ARM::LDM_UPD || MI->getOpcode() == ARM::t2LDM_UPD) &&
1198532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach      MI->getOperand(0).getReg() == ARM::SP &&
1199532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach      ARM_AM::getAM4SubMode(MI->getOperand(2).getImm()) == ARM_AM::ia) {
1200532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    OS << '\t' << "pop";
1201532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    printPredicateOperand(MI, 3, OS);
1202532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    OS << '\t';
1203532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    printRegisterList(MI, 5, OS);
1204e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  } else
1205e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  // A8.6.355 VPUSH
1206e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  if ((MI->getOpcode() == ARM::VSTMS_UPD || MI->getOpcode() ==ARM::VSTMD_UPD) &&
1207532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach      MI->getOperand(0).getReg() == ARM::SP &&
1208532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach      ARM_AM::getAM4SubMode(MI->getOperand(2).getImm()) == ARM_AM::db) {
1209532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    OS << '\t' << "vpush";
1210532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    printPredicateOperand(MI, 3, OS);
1211532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    OS << '\t';
1212532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    printRegisterList(MI, 5, OS);
1213e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  } else
1214e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  // A8.6.354 VPOP
1215e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  if ((MI->getOpcode() == ARM::VLDMS_UPD || MI->getOpcode() ==ARM::VLDMD_UPD) &&
1216532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach      MI->getOperand(0).getReg() == ARM::SP &&
1217532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach      ARM_AM::getAM4SubMode(MI->getOperand(2).getImm()) == ARM_AM::ia) {
1218532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    OS << '\t' << "vpop";
1219532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    printPredicateOperand(MI, 3, OS);
1220532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    OS << '\t';
1221532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    printRegisterList(MI, 5, OS);
1222e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  } else
12232e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  // TRAP and tTRAP need special handling for non-Darwin. The GNU binutils
12242e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  // don't (yet) support the 'trap' mnemonic. (Use decimal, not hex, to
12252e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  // be consistent with the MC instruction printer.)
12262e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  // FIXME: This really should be in AsmPrinter/ARMInstPrinter.cpp, not here.
12272e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  //        Need a way to ask "isTargetDarwin()" there, first, though.
12282e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  if (MI->getOpcode() == ARM::TRAP && !Subtarget->isTargetDarwin()) {
1229c8ab9eb066f6d35880e3a24436baf21236c921caBenjamin Kramer    OS << "\t.long\t3892305662\t\t" << MAI->getCommentString() << "trap";
12302e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  } else if (MI->getOpcode() == ARM::tTRAP && !Subtarget->isTargetDarwin()) {
12312e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    OS << "\t.short\t57086\t\t\t" << MAI->getCommentString() << " trap";
12322e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  } else
1233e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    printInstruction(MI, OS);
12343f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen
1235e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  // Output the instruction to the stream
12367ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  OutStreamer.EmitRawText(OS.str());
1237b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
12387ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  // Make sure the instruction that follows TBB is 2-byte aligned.
12397ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  // FIXME: Constant island pass should insert an "ALIGN" instruction instead.
12407ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  if (MI->getOpcode() == ARM::t2TBB)
12417ad07c46362500f7291a92742569e94fd3538dfdChris Lattner    EmitAlignment(1);
1242a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
1243a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1244812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
12450fb34683b9e33238288d2af1e090582464df8387Bob Wilson  if (Subtarget->isTargetDarwin()) {
12460fb34683b9e33238288d2af1e090582464df8387Bob Wilson    Reloc::Model RelocM = TM.getRelocationModel();
12470fb34683b9e33238288d2af1e090582464df8387Bob Wilson    if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
12480fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // Declare all the text sections up front (before the DWARF sections
12490fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // emitted by AsmPrinter::doInitialization) so the assembler will keep
12500fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // them together at the beginning of the object file.  This helps
12510fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // avoid out-of-range branches that are due a fundamental limitation of
12520fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // the way symbol offsets are encoded with the current Darwin ARM
12530fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // relocations.
1254b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach      const TargetLoweringObjectFileMachO &TLOFMacho =
12550d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman        static_cast<const TargetLoweringObjectFileMachO &>(
12560d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman          getObjFileLowering());
125729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextSection());
125829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
125929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection());
126029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      if (RelocM == Reloc::DynamicNoPIC) {
126129e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
126222772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__symbol_stub4",
126322772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
126422772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     12, SectionKind::getText());
126529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
126629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      } else {
126729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
126822772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__picsymbolstub4",
126922772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
127022772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     16, SectionKind::getText());
127129e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
127229e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      }
127363db594559dc8eac666204c7907bae664f5234daBob Wilson      const MCSection *StaticInitSect =
127463db594559dc8eac666204c7907bae664f5234daBob Wilson        OutContext.getMachOSection("__TEXT", "__StaticInit",
127563db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_REGULAR |
127663db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
127763db594559dc8eac666204c7907bae664f5234daBob Wilson                                   SectionKind::getText());
127863db594559dc8eac666204c7907bae664f5234daBob Wilson      OutStreamer.SwitchSection(StaticInitSect);
12790fb34683b9e33238288d2af1e090582464df8387Bob Wilson    }
12800fb34683b9e33238288d2af1e090582464df8387Bob Wilson  }
12810fb34683b9e33238288d2af1e090582464df8387Bob Wilson
1282e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach  // Use unified assembler syntax.
12839d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  OutStreamer.EmitRawText(StringRef("\t.syntax unified"));
1284d61eca533081580d56fabee38f86507d8019ca75Anton Korobeynikov
128588ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  // Emit ARM Build Attributes
128688ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  if (Subtarget->isTargetELF()) {
128788ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // CPU Type
1288d260c248abd57763aaeeadcab4155655a25d9e97Anton Korobeynikov    std::string CPUString = Subtarget->getCPUString();
1289d260c248abd57763aaeeadcab4155655a25d9e97Anton Korobeynikov    if (CPUString != "generic")
12909d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.cpu " + Twine(CPUString));
129188ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
129288ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // FIXME: Emit FPU type
129388ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    if (Subtarget->hasVFP2())
12949d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12959d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::VFP_arch) + ", 2");
129688ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
129788ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // Signal various FP modes.
12989d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    if (!UnsafeFPMath) {
12999d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
13009d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_denormal) + ", 1");
13019d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
13029d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_exceptions) + ", 1");
13039d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    }
1304b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
130560108e96bbc5432f4fe06ba313e64448e97a0e15Evan Cheng    if (NoInfsFPMath && NoNaNsFPMath)
13069d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
13079d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 1");
130888ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    else
13099d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
13109d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 3");
131188ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
131288ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // 8-bytes alignment stuff.
13139d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.EmitRawText("\t.eabi_attribute " +
13149d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                            Twine(ARMBuildAttrs::ABI_align8_needed) + ", 1");
13159d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.EmitRawText("\t.eabi_attribute " +
13169d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                            Twine(ARMBuildAttrs::ABI_align8_preserved) + ", 1");
131788ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
1318567d14f07cd62bfb9dd0edd90144a0a840450f7aAnton Korobeynikov    // Hard float.  Use both S and D registers and conform to AAPCS-VFP.
13199d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) {
13209d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
13219d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_HardFP_use) + ", 3");
13229d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
13239d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_VFP_args) + ", 1");
13249d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    }
132588ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // FIXME: Should we signal R9 usage?
132688ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  }
13277bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
13287bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
13290f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
13304a071d667d995b00e7853243ff9c7c1269324478Chris Lattnervoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
13315be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng  if (Subtarget->isTargetDarwin()) {
1332f61159b574155b056dbd5d6d44f47f753d424056Chris Lattner    // All darwin targets use mach-o.
13330d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman    const TargetLoweringObjectFileMachO &TLOFMacho =
13340d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman      static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
1335b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO &MMIMacho =
1336b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      MMI->getObjFileInfo<MachineModuleInfoMachO>();
1337e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
1338a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Output non-lazy-pointers for external and common global variables.
1339b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
1340cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling
1341b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    if (!Stubs.empty()) {
1342ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner      // Switch with ".non_lazy_symbol_pointer" directive.
13436c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
1344c076a9793936b140364671a5e39ee53bd266c6c3Chris Lattner      EmitAlignment(2);
1345b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1346becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
1347becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
1348becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .indirect_symbol _foo
134952a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
135052a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol);
1351cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
135252a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        if (MCSym.getInt())
1353cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // External to current translation unit.
1354cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
1355cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling        else
1356cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // Internal to current translation unit.
13575e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          //
13581b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // When we place the LSDA into the TEXT section, the type info
13591b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // pointers need to be indirect and pc-rel. We accomplish this by
13601b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // using NLPs; however, sometimes the types are local to the file.
13611b935a3d2e2619c7de2488163fc1501285b53fa3Jim Grosbach          // We need to fill in the value for the NLP in those cases.
136252a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling          OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
136352a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling                                                        OutContext),
1364cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling                                4/*size*/, 0/*addrspace*/);
1365ae94e594164b193236002516970aeec4c4574768Evan Cheng      }
1366becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling
1367becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      Stubs.clear();
1368becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      OutStreamer.AddBlankLine();
1369a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
1370a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1371e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    Stubs = MMIMacho.GetHiddenGVStubList();
1372e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    if (!Stubs.empty()) {
13736c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
1374f3231de60bb64c3f6fc6770b3e6174f4f839a4f3Chris Lattner      EmitAlignment(2);
1375becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1376becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
1377becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
1378becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .long _foo
1379cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling        OutStreamer.EmitValue(MCSymbolRefExpr::
1380cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                              Create(Stubs[i].second.getPointer(),
1381cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                                     OutContext),
1382becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling                              4/*size*/, 0/*addrspace*/);
1383becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      }
1384cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
1385cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      Stubs.clear();
1386cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      OutStreamer.AddBlankLine();
1387ae94e594164b193236002516970aeec4c4574768Evan Cheng    }
1388ae94e594164b193236002516970aeec4c4574768Evan Cheng
1389a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Funny Darwin hack: This flag tells the linker that no global symbols
1390a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // contain code that falls through to other global symbols (e.g. the obvious
1391a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // implementation of multiple entry points).  If this doesn't occur, the
1392a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // linker can safely perform dead code stripping.  Since LLVM never
1393a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // generates code that does this, it is always safe to set.
1394a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner    OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
1395b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola  }
13967bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
13970bd89712c03c59ea43ce37763685e7f7c0bdd977Anton Korobeynikov
139897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===----------------------------------------------------------------------===//
139997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner
1400988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbachstatic MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber,
1401988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                             unsigned LabelId, MCContext &Ctx) {
1402988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach
1403988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach  MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix)
1404988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                       + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));
1405988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach  return Label;
1406988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach}
1407988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach
1408a2244cb38781e596110023399c7902b5ee5087feJim Grosbachvoid ARMAsmPrinter::EmitJumpTable(const MachineInstr *MI) {
1409a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  unsigned Opcode = MI->getOpcode();
1410a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  int OpNum = 1;
1411a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  if (Opcode == ARM::BR_JTadd)
1412a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OpNum = 2;
1413a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  else if (Opcode == ARM::BR_JTm)
1414a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OpNum = 3;
1415a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
1416a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineOperand &MO1 = MI->getOperand(OpNum);
1417a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
1418a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  unsigned JTI = MO1.getIndex();
1419a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
1420a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  // Emit a label for the jump table.
1421a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
1422a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  OutStreamer.EmitLabel(JTISymbol);
1423a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
1424a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  // Emit each entry of the table.
1425a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1426a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1427a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1428a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
1429a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
1430a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    MachineBasicBlock *MBB = JTBBs[i];
1431a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // Construct an MCExpr for the entry. We want a value of the form:
1432a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // (BasicBlockAddr - TableBeginAddr)
1433a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //
1434a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // For example, a table with entries jumping to basic blocks BB0 and BB1
1435a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // would look like:
1436a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // LJTI_0_0:
1437a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //    .word (LBB0 - LJTI_0_0)
1438a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    //    .word (LBB1 - LJTI_0_0)
1439a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    const MCExpr *Expr = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext);
1440a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
1441a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    if (TM.getRelocationModel() == Reloc::PIC_)
1442a2244cb38781e596110023399c7902b5ee5087feJim Grosbach      Expr = MCBinaryExpr::CreateSub(Expr, MCSymbolRefExpr::Create(JTISymbol,
1443a2244cb38781e596110023399c7902b5ee5087feJim Grosbach                                                                   OutContext),
1444a2244cb38781e596110023399c7902b5ee5087feJim Grosbach                                     OutContext);
1445a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OutStreamer.EmitValue(Expr, 4);
1446a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  }
1447a2244cb38781e596110023399c7902b5ee5087feJim Grosbach}
1448a2244cb38781e596110023399c7902b5ee5087feJim Grosbach
1449882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbachvoid ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) {
1450882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  unsigned Opcode = MI->getOpcode();
1451882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1;
1452882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineOperand &MO1 = MI->getOperand(OpNum);
1453882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
1454882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  unsigned JTI = MO1.getIndex();
1455882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
1456882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  // Emit a label for the jump table.
1457882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
1458882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  OutStreamer.EmitLabel(JTISymbol);
1459882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
1460882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  // Emit each entry of the table.
1461882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1462882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1463882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1464205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach  unsigned OffsetWidth = 4;
1465882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  if (MI->getOpcode() == ARM::t2TBB)
1466205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OffsetWidth = 1;
1467882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  else if (MI->getOpcode() == ARM::t2TBH)
1468205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OffsetWidth = 2;
1469882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
1470882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
1471882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MachineBasicBlock *MBB = JTBBs[i];
1472205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    const MCExpr *MBBSymbolExpr = MCSymbolRefExpr::Create(MBB->getSymbol(),
1473205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                                                      OutContext);
1474882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // If this isn't a TBB or TBH, the entries are direct branch instructions.
1475205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    if (OffsetWidth == 4) {
1476882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      MCInst BrInst;
1477882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      BrInst.setOpcode(ARM::t2B);
1478205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach      BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr));
1479882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      OutStreamer.EmitInstruction(BrInst);
1480882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      continue;
1481882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    }
1482882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // Otherwise it's an offset from the dispatch instruction. Construct an
1483205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // MCExpr for the entry. We want a value of the form:
1484205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // (BasicBlockAddr - TableBeginAddr) / 2
1485205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //
1486205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // For example, a TBB table with entries jumping to basic blocks BB0 and BB1
1487205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // would look like:
1488205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    // LJTI_0_0:
1489205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //    .byte (LBB0 - LJTI_0_0) / 2
1490205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    //    .byte (LBB1 - LJTI_0_0) / 2
1491205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    const MCExpr *Expr =
1492205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach      MCBinaryExpr::CreateSub(MBBSymbolExpr,
1493205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                              MCSymbolRefExpr::Create(JTISymbol, OutContext),
1494205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                              OutContext);
1495205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    Expr = MCBinaryExpr::CreateDiv(Expr, MCConstantExpr::Create(2, OutContext),
1496205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach                                   OutContext);
1497205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    OutStreamer.EmitValue(Expr, OffsetWidth);
1498882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  }
1499205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach
1500205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach  // Make sure the instruction that follows TBB is 2-byte aligned.
1501205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach  // FIXME: Constant island pass should insert an "ALIGN" instruction instead.
1502205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach  if (MI->getOpcode() == ARM::t2TBB)
1503205a5fa8e4233cdcdc71152c0f8c4334ea9ce2ebJim Grosbach    EmitAlignment(1);
1504882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach}
1505882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
150697f06937449c593a248dbbb1365e6ae408fb9decChris Lattnervoid ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
150796bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner  ARMMCInstLower MCInstLowering(OutContext, *Mang, *this);
150897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  switch (MI->getOpcode()) {
1509c6b8a9920787505468931e56696cef1245e25913Chris Lattner  case ARM::t2MOVi32imm:
1510c6b8a9920787505468931e56696cef1245e25913Chris Lattner    assert(0 && "Should be lowered by thumb2it pass");
15114d1522234192704f45dfd2527c2913fa60be616eChris Lattner  default: break;
1512fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach  case ARM::tPICADD: {
1513fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // This is a pseudo op for a label + instruction sequence, which looks like:
1514fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // LPC0:
1515fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    //     add r0, pc
1516fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // This adds the address of LPC0 to r0.
1517fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach
1518fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Emit the label.
1519988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1520988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
1521988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
1522fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach
1523fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Form and emit the add.
1524fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    MCInst AddInst;
1525fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.setOpcode(ARM::tADDhirr);
1526fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1527fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1528fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
1529fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Add predicate operands.
1530fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1531fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(0));
1532fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    OutStreamer.EmitInstruction(AddInst);
1533fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    return;
1534fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach  }
15354d1522234192704f45dfd2527c2913fa60be616eChris Lattner  case ARM::PICADD: { // FIXME: Remove asm string from td file.
15364d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This is a pseudo op for a label + instruction sequence, which looks like:
15374d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // LPC0:
15384d1522234192704f45dfd2527c2913fa60be616eChris Lattner    //     add r0, pc, r0
15394d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This adds the address of LPC0 to r0.
1540b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
15414d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // Emit the label.
1542988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1543988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
1544988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
1545b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1546f3f09527e6484143fcdef2ddfef0b2f016881e36Jim Grosbach    // Form and emit the add.
15474d1522234192704f45dfd2527c2913fa60be616eChris Lattner    MCInst AddInst;
15484d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.setOpcode(ARM::ADDrr);
15494d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
15504d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
15514d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
15525b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add predicate operands.
15535b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
15545b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
15555b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add 's' bit operand (always reg0 for this)
15565b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(0));
1557850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner    OutStreamer.EmitInstruction(AddInst);
15584d1522234192704f45dfd2527c2913fa60be616eChris Lattner    return;
1559b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach  }
1560a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTR:
1561a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTRB:
1562a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTRH:
1563a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDR:
1564a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRB:
1565a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRH:
1566a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRSB:
1567a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRSH: {
1568b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // This is a pseudo op for a label + instruction sequence, which looks like:
1569b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // LPC0:
1570a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    //     OP r0, [pc, r0]
1571b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // The LCP0 label is referenced by a constant pool entry in order to get
1572b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // a PC-relative address at the ldr instruction.
1573b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1574b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Emit the label.
1575988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1576988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
1577988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
1578b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1579b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Form and emit the load
1580a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    unsigned Opcode;
1581a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    switch (MI->getOpcode()) {
1582a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    default:
1583a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach      llvm_unreachable("Unexpected opcode!");
1584a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICSTR:   Opcode = ARM::STR; break;
1585a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICSTRB:  Opcode = ARM::STRB; break;
1586a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICSTRH:  Opcode = ARM::STRH; break;
1587a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDR:   Opcode = ARM::LDR; break;
1588a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRB:  Opcode = ARM::LDRB; break;
1589a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRH:  Opcode = ARM::LDRH; break;
1590a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
1591a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
1592a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    }
1593a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    MCInst LdStInst;
1594a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.setOpcode(Opcode);
1595a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1596a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(ARM::PC));
1597a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1598a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateImm(0));
1599b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Add predicate operands.
1600a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
1601a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
1602a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    OutStreamer.EmitInstruction(LdStInst);
1603b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1604b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    return;
16054d1522234192704f45dfd2527c2913fa60be616eChris Lattner  }
1606a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner  case ARM::CONSTPOOL_ENTRY: { // FIXME: Remove asm string from td file.
1607a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
1608a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// in the function.  The first operand is the ID# for this instruction, the
1609a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// second is the index into the MachineConstantPool that this is, the third
1610a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// is the size in bytes of this constant pool entry.
1611a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
1612a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned CPIdx   = (unsigned)MI->getOperand(1).getIndex();
1613a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
1614a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    EmitAlignment(2);
16151b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    OutStreamer.EmitLabel(GetCPISymbol(LabelId));
1616a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
1617a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
1618a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    if (MCPE.isMachineConstantPoolEntry())
1619a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
1620a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    else
1621a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitGlobalConstant(MCPE.Val.ConstVal);
1622b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1623a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    return;
1624a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner  }
1625017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner  case ARM::MOVi2pieces: { // FIXME: Remove asmstring from td file.
1626017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    // This is a hack that lowers as a two instruction sequence.
1627017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned DstReg = MI->getOperand(0).getReg();
1628017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
1629017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner
1630017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(ImmVal);
1631017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(ImmVal);
1632b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1633017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    {
1634017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      MCInst TmpInst;
1635017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.setOpcode(ARM::MOVi);
1636017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));
1637017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(SOImmValV1));
1638b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1639017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      // Predicate.
1640017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1641017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1642233917c07282564351439df8e7a9c83c9d6c459eChris Lattner
1643233917c07282564351439df8e7a9c83c9d6c459eChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out
1644850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
1645017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    }
1646017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner
1647017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    {
1648017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      MCInst TmpInst;
1649017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.setOpcode(ARM::ORRri);
1650017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // dstreg
1651017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // inreg
1652017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(SOImmValV2)); // so_imm
1653017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      // Predicate.
1654017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1655017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1656b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1657017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out
1658850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
1659017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    }
1660b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach    return;
1661017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner  }
1662161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner  case ARM::MOVi32imm: { // FIXME: Remove asmstring from td file.
1663161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    // This is a hack that lowers as a two instruction sequence.
1664161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    unsigned DstReg = MI->getOperand(0).getReg();
166518c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    const MachineOperand &MO = MI->getOperand(1);
166618c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    MCOperand V1, V2;
166718c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    if (MO.isImm()) {
166818c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
166918c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V1 = MCOperand::CreateImm(ImmVal & 65535);
167018c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V2 = MCOperand::CreateImm(ImmVal >> 16);
167118c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    } else if (MO.isGlobal()) {
1672c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach      MCSymbol *Symbol = MCInstLowering.GetGlobalAddressSymbol(MO.getGlobal());
167318c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      const MCSymbolRefExpr *SymRef1 =
16743472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        MCSymbolRefExpr::Create(Symbol,
16753472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands                                MCSymbolRefExpr::VK_ARM_LO16, OutContext);
167618c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      const MCSymbolRefExpr *SymRef2 =
16773472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        MCSymbolRefExpr::Create(Symbol,
16783472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands                                MCSymbolRefExpr::VK_ARM_HI16, OutContext);
167918c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V1 = MCOperand::CreateExpr(SymRef1);
168018c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V2 = MCOperand::CreateExpr(SymRef2);
168118c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    } else {
1682f0633e48eb9d70d5db31a7498736ba21a9ee410cJim Grosbach      // FIXME: External symbol?
168318c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      MI->dump();
168418c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      llvm_unreachable("cannot handle this operand");
168518c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    }
168618c1021ec108722506125926087b1e5fcfb28046Rafael Espindola
1687161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    {
1688161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      MCInst TmpInst;
1689161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.setOpcode(ARM::MOVi16);
1690161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
169118c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      TmpInst.addOperand(V1); // lower16(imm)
1692b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1693161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      // Predicate.
1694161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1695161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1696b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1697850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
1698161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    }
1699b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1700161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    {
1701161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      MCInst TmpInst;
1702161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.setOpcode(ARM::MOVTi16);
1703161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
1704161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // srcreg
170518c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      TmpInst.addOperand(V2);   // upper16(imm)
1706b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1707161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      // Predicate.
1708161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1709161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1710b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1711850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
1712161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    }
1713b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1714161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    return;
1715161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner  }
1716882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::t2TBB:
1717882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::t2TBH:
1718882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::t2BR_JT: {
1719882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
1720882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MCInst TmpInst;
1721882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MCInstLowering.Lower(MI, TmpInst);
1722882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
1723882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    EmitJump2Table(MI);
1724882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    return;
1725882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  }
1726882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::tBR_JTr:
1727882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::BR_JTr:
1728882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::BR_JTm:
1729a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  case ARM::BR_JTadd: {
1730a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
1731a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    MCInst TmpInst;
1732a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    MCInstLowering.Lower(MI, TmpInst);
1733a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    OutStreamer.EmitInstruction(TmpInst);
1734a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    EmitJumpTable(MI);
1735a2244cb38781e596110023399c7902b5ee5087feJim Grosbach    return;
1736a2244cb38781e596110023399c7902b5ee5087feJim Grosbach  }
17372e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  case ARM::TRAP: {
17382e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // Non-Darwin binutils don't yet support the "trap" mnemonic.
17392e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // FIXME: Remove this special case when they do.
17402e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    if (!Subtarget->isTargetDarwin()) {
17412e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      //.long 0xe7ffdefe ${:comment} trap
1742b2dda4bd346fe9a2795f83f659c0e60191b2e6a0Jim Grosbach      uint32_t Val = 0xe7ffdefeUL;
17432e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.AddComment("trap");
17442e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.EmitIntValue(Val, 4);
17452e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      return;
17462e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    }
17472e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    break;
17482e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  }
17492e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  case ARM::tTRAP: {
17502e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // Non-Darwin binutils don't yet support the "trap" mnemonic.
17512e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    // FIXME: Remove this special case when they do.
17522e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    if (!Subtarget->isTargetDarwin()) {
1753c8ab9eb066f6d35880e3a24436baf21236c921caBenjamin Kramer      //.short 57086 ${:comment} trap
1754c8ab9eb066f6d35880e3a24436baf21236c921caBenjamin Kramer      uint16_t Val = 0xdefe;
17552e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.AddComment("trap");
17562e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      OutStreamer.EmitIntValue(Val, 2);
17572e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach      return;
17582e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    }
17592e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach    break;
17602e6ae13bf6e09d844b76b0a12861d25be0842b03Jim Grosbach  }
1761433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  case ARM::t2Int_eh_sjlj_setjmp:
1762433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  case ARM::t2Int_eh_sjlj_setjmp_nofp:
1763433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  case ARM::tInt_eh_sjlj_setjmp: { // FIXME: Remove asmstring from td file.
1764433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // Two incoming args: GPR:$src, GPR:$val
1765433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // mov $val, pc
1766433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // adds $val, #7
1767433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // str $val, [$src, #4]
1768433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // movs r0, #0
1769433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // b 1f
1770433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // movs r0, #1
1771433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    // 1:
1772433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1773433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    unsigned ValReg = MI->getOperand(1).getReg();
1774433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    MCSymbol *Label = GetARMSJLJEHLabel();
1775433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1776433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1777433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVgpr2tgpr);
1778433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1779433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1780433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // 's' bit operand
1781433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1782433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.AddComment("eh_setjmp begin");
1783433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1784433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1785433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1786433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1787433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tADDi3);
1788433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1789433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // 's' bit operand
1790433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1791433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1792433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(7));
1793433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1794433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1795433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1796433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1797433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1798433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1799433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1800433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tSTR);
1801433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1802433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1803433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // The offset immediate is #4. The operand value is scaled by 4 for the
1804433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // tSTR instruction.
1805433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1806433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1807433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1808433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1809433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1810433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1811433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1812433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1813433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1814433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
1815433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1816433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1817433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1818433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1819433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1820433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1821433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1822433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1823433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1824433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      const MCExpr *SymbolExpr = MCSymbolRefExpr::Create(Label, OutContext);
1825433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1826433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tB);
1827433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr));
1828433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1829433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1830433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    {
1831433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      MCInst TmpInst;
1832433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.setOpcode(ARM::tMOVi8);
1833433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1834433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1835433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1836433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      // Predicate.
1837433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1838433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1839433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.AddComment("eh_setjmp end");
1840433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1841433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    }
1842433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    OutStreamer.EmitLabel(Label);
1843433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach    return;
1844433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach  }
1845433a5785cc8201a8a384f0a5648d3dbac87f9fbcJim Grosbach
1846453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach  case ARM::Int_eh_sjlj_setjmp_nofp:
1847453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach  case ARM::Int_eh_sjlj_setjmp: { // FIXME: Remove asmstring from td file.
1848453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // Two incoming args: GPR:$src, GPR:$val
1849453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // add $val, pc, #8
1850453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // str $val, [$src, #+4]
1851453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // mov r0, #0
1852453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // add pc, pc, #0
1853453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    // mov r0, #1
1854453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1855453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    unsigned ValReg = MI->getOperand(1).getReg();
1856453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach
1857453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1858453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1859453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::ADDri);
1860453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1861453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1862453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(8));
1863453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1864453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1865453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1866453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1867453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1868453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.AddComment("eh_setjmp begin");
1869453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1870453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1871453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1872453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1873453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::STR);
1874453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ValReg));
1875453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1876453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1877453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
1878453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1879453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1880453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1881453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1882453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1883453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1884453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1885453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::MOVi);
1886453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1887453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1888453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1889453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1890453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1891453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1892453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1893453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1894453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1895453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1896453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1897453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::ADDri);
1898453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1899453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::PC));
1900453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
1901453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1902453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1903453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1904453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1905453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1906453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1907453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1908453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    {
1909453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      MCInst TmpInst;
1910453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.setOpcode(ARM::MOVi);
1911453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R0));
1912453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
1913453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // Predicate.
1914453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1915453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1916453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      // 's' bit operand (always reg0 for this).
1917453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1918453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.AddComment("eh_setjmp end");
1919453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1920453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    }
1921453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach    return;
1922453900814e5245fd823b2b24ee9da9b5e8b4bfc4Jim Grosbach  }
19235acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach  case ARM::Int_eh_sjlj_longjmp: {
19245acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr sp, [$src, #8]
19255acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr $scratch, [$src, #4]
19265acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // ldr r7, [$src]
19275acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    // bx $scratch
19285acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
19295acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    unsigned ScratchReg = MI->getOperand(1).getReg();
19305acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
19315acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
19325acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.setOpcode(ARM::LDR);
19335acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
19345acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
19355acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
19365acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(8));
19375acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
19385acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
19395acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
19405acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
19415acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
19425acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
19435acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
19445acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.setOpcode(ARM::LDR);
19455acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
19465acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
19475acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
19485acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(4));
19495acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
19505acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
19515acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
19525acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
19535acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
19545acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
19555acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
19565acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.setOpcode(ARM::LDR);
19575acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
19585acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
19595acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
19605acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
19615acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
19625acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
19635acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
19645acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
19655acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
19665acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    {
19675acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      MCInst TmpInst;
19685acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.setOpcode(ARM::BRIND);
19695acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
19705acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      // Predicate.
19715acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
19725acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1973385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1974385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1975385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    return;
1976385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach  }
1977385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach  case ARM::tInt_eh_sjlj_longjmp: {
1978385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr $scratch, [$src, #8]
1979385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // mov sp, $scratch
1980385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr $scratch, [$src, #4]
1981385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // ldr r7, [$src]
1982385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    // bx $scratch
1983385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    unsigned SrcReg = MI->getOperand(0).getReg();
1984385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    unsigned ScratchReg = MI->getOperand(1).getReg();
1985385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
1986385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
1987385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tLDR);
1988385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
1989385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1990385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // The offset immediate is #8. The operand value is scaled by 4 for the
1991385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // tSTR instruction.
1992385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(2));
1993385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1994385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
1995385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1996385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
1997385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
1998385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
1999385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
2000385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
2001385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tMOVtgpr2gpr);
2002385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::SP));
2003385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
2004385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
2005385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
2006385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
2007385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
2008385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
2009385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
2010385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
2011385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tLDR);
2012385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
2013385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
2014385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(1));
2015385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
2016385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
2017385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
2018385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
2019385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
2020385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
2021385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
2022385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
2023385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tLDR);
2024385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ARM::R7));
2025385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
2026385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(0));
2027385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
2028385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
2029385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
2030385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
2031385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      OutStreamer.EmitInstruction(TmpInst);
2032385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    }
2033385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach    {
2034385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      MCInst TmpInst;
2035385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.setOpcode(ARM::tBX_RET_vararg);
2036385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(ScratchReg));
2037385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      // Predicate.
2038385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
2039385cc5eede9f81717b03121baf47b7aa185b5128Jim Grosbach      TmpInst.addOperand(MCOperand::CreateReg(0));
20405acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach      OutStreamer.EmitInstruction(TmpInst);
20415acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    }
20425acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach    return;
20435acb3de8b7cfd5a104722526b731a3c87bb1a46eJim Grosbach  }
204497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  }
2045b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
204697f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  MCInst TmpInst;
204797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  MCInstLowering.Lower(MI, TmpInst);
2048850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner  OutStreamer.EmitInstruction(TmpInst);
204997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner}
20502685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
20512685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
20522685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Target Registry Stuff
20532685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
20542685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
20552685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarstatic MCInstPrinter *createARMMCInstPrinter(const Target &T,
20562685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar                                             unsigned SyntaxVariant,
2057d374087be5360a353a4239a155b1227057145f48Chris Lattner                                             const MCAsmInfo &MAI) {
20582685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  if (SyntaxVariant == 0)
205974d7e6c64e955f89e6d3d4023d36fd481da4cfc1Jim Grosbach    return new ARMInstPrinter(MAI);
20602685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  return 0;
20612685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
20622685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
20632685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Force static initialization.
20642685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarextern "C" void LLVMInitializeARMAsmPrinter() {
20652685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget);
20662685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget);
20672685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
20682685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter);
20692685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter);
20702685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
20712685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
2072