ARMAsmPrinter.cpp revision 1adc40cac314b0a77b790b094bca146a3a868452
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>
5797f06937449c593a248dbbb1365e6ae408fb9decChris LattnerEnableMCInst("enable-arm-mcinst-printer", cl::Hidden,
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    }
936a71afaec18e5bcbdb838a5e094f51e9f8ea864dChris Lattner
9497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner    void printInstructionThroughMCStreamer(const MachineInstr *MI);
9597f06937449c593a248dbbb1365e6ae408fb9decChris Lattner
967bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
9735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
98a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                      const char *Modifier = 0);
9935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printSOImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
10035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printSOImm2PartOperand(const MachineInstr *MI, int OpNum,
10135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                raw_ostream &O);
10235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printSORegOperand(const MachineInstr *MI, int OpNum,
10335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                           raw_ostream &O);
10435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode2Operand(const MachineInstr *MI, int OpNum,
10535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
10635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNum,
10735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
10835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode3Operand(const MachineInstr *MI, int OpNum,
10935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
11035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode3OffsetOperand(const MachineInstr *MI, int OpNum,
11135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
11235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode4Operand(const MachineInstr *MI, int OpNum,raw_ostream &O,
113a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                               const char *Modifier = 0);
11435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode5Operand(const MachineInstr *MI, int OpNum,raw_ostream &O,
115a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                               const char *Modifier = 0);
11635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode6Operand(const MachineInstr *MI, int OpNum,
11735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
11835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode6OffsetOperand(const MachineInstr *MI, int OpNum,
11935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
120055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    void printAddrModePCOperand(const MachineInstr *MI, int OpNum,
12135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                raw_ostream &O,
122a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                const char *Modifier = 0);
123eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    void printBitfieldInvMaskImmOperand(const MachineInstr *MI, int OpNum,
124eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson                                        raw_ostream &O);
1251adc40cac314b0a77b790b094bca146a3a868452Johnny Chen    void printMemBOption(const MachineInstr *MI, int OpNum,
1261adc40cac314b0a77b790b094bca146a3a868452Johnny Chen                         raw_ostream &O);
127eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    void printSatShiftOperand(const MachineInstr *MI, int OpNum,
128eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson                              raw_ostream &O);
12935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner
13035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbS4ImmOperand(const MachineInstr *MI, int OpNum,
13135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                raw_ostream &O);
13235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbITMask(const MachineInstr *MI, int OpNum, raw_ostream &O);
13335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNum,
13435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
135055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNum,
13635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O,
137a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                      unsigned Scale);
13835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeS1Operand(const MachineInstr *MI, int OpNum,
13935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
14035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNum,
14135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
14235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNum,
14335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
14435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNum,
14535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
14635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner
14735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2SOOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
14835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm12Operand(const MachineInstr *MI, int OpNum,
14935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
15035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm8Operand(const MachineInstr *MI, int OpNum,
15135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                    raw_ostream &O);
15235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm8s4Operand(const MachineInstr *MI, int OpNum,
15335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O);
15435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm8OffsetOperand(const MachineInstr *MI, int OpNum,
15535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O);
15635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm8s4OffsetOperand(const MachineInstr *MI, int OpNum,
15735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                            raw_ostream &O) {}
15835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeSoRegOperand(const MachineInstr *MI, int OpNum,
15935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
16035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner
16135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printCPSOptionOperand(const MachineInstr *MI, int OpNum,
16235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O) {}
16335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printMSRMaskOperand(const MachineInstr *MI, int OpNum,
16435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                             raw_ostream &O) {}
16535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printNegZeroOperand(const MachineInstr *MI, int OpNum,
16635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                             raw_ostream &O) {}
16735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printPredicateOperand(const MachineInstr *MI, int OpNum,
16835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
16935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printMandatoryPredicateOperand(const MachineInstr *MI, int OpNum,
17035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                        raw_ostream &O);
17135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printSBitModifierOperand(const MachineInstr *MI, int OpNum,
17235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                  raw_ostream &O);
17335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printPCLabel(const MachineInstr *MI, int OpNum,
17435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                      raw_ostream &O);
17535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printRegisterList(const MachineInstr *MI, int OpNum,
17635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                           raw_ostream &O);
177055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    void printCPInstOperand(const MachineInstr *MI, int OpNum,
17835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                            raw_ostream &O,
179a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                            const char *Modifier);
18035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printJTBlockOperand(const MachineInstr *MI, int OpNum,
18135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                             raw_ostream &O);
18235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printJT2BlockOperand(const MachineInstr *MI, int OpNum,
18335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                              raw_ostream &O);
18435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printTBAddrMode(const MachineInstr *MI, int OpNum,
18535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                         raw_ostream &O);
18635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printNoHashImmediate(const MachineInstr *MI, int OpNum,
18735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                              raw_ostream &O);
18835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printVFPf32ImmOperand(const MachineInstr *MI, int OpNum,
18935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
19035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printVFPf64ImmOperand(const MachineInstr *MI, int OpNum,
19135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
1921a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson    void printNEONModImmOperand(const MachineInstr *MI, int OpNum,
1931a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson                                raw_ostream &O);
19454c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson
195055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
196c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                 unsigned AsmVariant, const char *ExtraCode,
197c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                 raw_ostream &O);
198055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
199224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson                                       unsigned AsmVariant,
200c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                       const char *ExtraCode, raw_ostream &O);
2017bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
20235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen
203d95148f073c31924f275a34296da52a7cdefad91Chris Lattner    static const char *getRegisterName(unsigned RegNo);
20405af2616d0df19638e799d3e7afadea26d96a4baChris Lattner
205a786ceac5c888761d83d84d35eb16150be57cc6eChris Lattner    virtual void EmitInstruction(const MachineInstr *MI);
2067bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    bool runOnMachineFunction(MachineFunction &F);
207a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattner
208a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattner    virtual void EmitConstantPool() {} // we emit constant pools customly!
209953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner    virtual void EmitFunctionEntryLabel();
210812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson    void EmitStartOfAsmFile(Module &M);
2114a071d667d995b00e7853243ff9c7c1269324478Chris Lattner    void EmitEndOfAsmFile(Module &M);
212a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
21359135f49e1699daec9a43fc2d15715d55b910f54Devang Patel    MachineLocation getDebugValueLocation(const MachineInstr *MI) const {
21459135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      MachineLocation Location;
21559135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      assert (MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
21659135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      // Frame address.  Currently handles register +- offset only.
21759135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm())
21859135f49e1699daec9a43fc2d15715d55b910f54Devang Patel        Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
21959135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      else {
22059135f49e1699daec9a43fc2d15715d55b910f54Devang Patel        DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
22159135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      }
22259135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      return Location;
22359135f49e1699daec9a43fc2d15715d55b910f54Devang Patel    }
22459135f49e1699daec9a43fc2d15715d55b910f54Devang Patel
225917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    virtual unsigned getISAEncoding() {
226917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      // ARM/Darwin adds ISA to the DWARF info for each function.
227917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      if (!Subtarget->isTargetDarwin())
228917290043f87b8efa6ba540bec5963013c517912Jim Grosbach        return 0;
229917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      return Subtarget->isThumb() ?
230917290043f87b8efa6ba540bec5963013c517912Jim Grosbach        llvm::ARM::DW_ISA_ARM_thumb : llvm::ARM::DW_ISA_ARM_arm;
231917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    }
232917290043f87b8efa6ba540bec5963013c517912Jim Grosbach
2330890cf124f00da3dc943c1882f4221955e0281edChris Lattner    MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
2340890cf124f00da3dc943c1882f4221955e0281edChris Lattner                                          const MachineBasicBlock *MBB) const;
2350890cf124f00da3dc943c1882f4221955e0281edChris Lattner    MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const;
236bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner
237711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    /// EmitMachineConstantPoolValue - Print a machine constantpool value to
238711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    /// the .s file.
239a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
2409d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      SmallString<128> Str;
2419d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      raw_svector_ostream OS(Str);
2429d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      EmitMachineConstantPoolValue(MCPV, OS);
2439d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText(OS.str());
2449d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    }
2459d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner
2469d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV,
2479d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                                      raw_ostream &O) {
248ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      switch (TM.getTargetData()->getTypeAllocSize(MCPV->getType())) {
249ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      case 1: O << MAI->getData8bitsDirective(0); break;
250ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      case 2: O << MAI->getData16bitsDirective(0); break;
251ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      case 4: O << MAI->getData32bitsDirective(0); break;
252ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      default: assert(0 && "Unknown CPV size");
253ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      }
254a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
255711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng      ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
2563fb2b1ede30193b59a651328a946174196b20610Jim Grosbach
2573fb2b1ede30193b59a651328a946174196b20610Jim Grosbach      if (ACPV->isLSDA()) {
2589d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner        O << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
25928989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      } else if (ACPV->isBlockAddress()) {
2600752cda4de245978e14d806831abba4506272cd0Chris Lattner        O << *GetBlockAddressSymbol(ACPV->getBlockAddress());
26128989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      } else if (ACPV->isGlobalValue()) {
26246510a73e977273ec67747eb34cbdb43f815e451Dan Gohman        const GlobalValue *GV = ACPV->getGV();
263e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        bool isIndirect = Subtarget->isTargetDarwin() &&
26463476a80404125e5196b6c09113c1d4796da0604Evan Cheng          Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
265e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        if (!isIndirect)
266d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner          O << *Mang->getSymbol(GV);
267e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        else {
268e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng          // FIXME: Remove this when Darwin transition to @GOT like syntax.
2697a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner          MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
27010b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner          O << *Sym;
271b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner
272b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner          MachineModuleInfoMachO &MMIMachO =
273b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner            MMI->getObjFileInfo<MachineModuleInfoMachO>();
274cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling          MachineModuleInfoImpl::StubValueTy &StubSym =
275b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner            GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(Sym) :
276b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner                                        MMIMachO.getGVStubEntry(Sym);
277cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling          if (StubSym.getPointer() == 0)
278cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling            StubSym = MachineModuleInfoImpl::
279d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner              StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
280e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        }
28128989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      } else {
28228989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson        assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
28310b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner        O << *GetExternalSymbolSymbol(ACPV->getSymbol());
28428989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      }
285e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
2860ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
28764f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio      if (ACPV->getPCAdjustment() != 0) {
28833adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner        O << "-(" << MAI->getPrivateGlobalPrefix() << "PC"
289e7e0d62efda2445b735052ca45bd74fb002e34c3Evan Cheng          << getFunctionNumber() << "_"  << ACPV->getLabelId()
29064f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio          << "+" << (unsigned)ACPV->getPCAdjustment();
29164f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio         if (ACPV->mustAddCurrentAddress())
29264f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio           O << "-.";
2938b3787586ed92df55131ad38c16646b7eba401a0Chris Lattner         O << ')';
29464f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio      }
295a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
2967bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  };
2977bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace
2987bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
2997bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMGenAsmWriter.inc"
3007bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
301953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattnervoid ARMAsmPrinter::EmitFunctionEntryLabel() {
302953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  if (AFI->isThumbFunction()) {
3039d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.EmitRawText(StringRef("\t.code\t16"));
3040752cda4de245978e14d806831abba4506272cd0Chris Lattner    if (!Subtarget->isTargetDarwin())
3059d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText(StringRef("\t.thumb_func"));
3060752cda4de245978e14d806831abba4506272cd0Chris Lattner    else {
3070752cda4de245978e14d806831abba4506272cd0Chris Lattner      // This needs to emit to a temporary string to get properly quoted
3080752cda4de245978e14d806831abba4506272cd0Chris Lattner      // MCSymbols when they have spaces in them.
3090752cda4de245978e14d806831abba4506272cd0Chris Lattner      SmallString<128> Tmp;
3100752cda4de245978e14d806831abba4506272cd0Chris Lattner      raw_svector_ostream OS(Tmp);
3110752cda4de245978e14d806831abba4506272cd0Chris Lattner      OS << "\t.thumb_func\t" << *CurrentFnSym;
3120752cda4de245978e14d806831abba4506272cd0Chris Lattner      OutStreamer.EmitRawText(OS.str());
3130752cda4de245978e14d806831abba4506272cd0Chris Lattner    }
314953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  }
315953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner
316953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  OutStreamer.EmitLabel(CurrentFnSym);
317953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner}
318953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner
319a8e2989ece6dc46df59b0768184028257f913843Evan Cheng/// runOnMachineFunction - This uses the printInstruction()
3207bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction.
3217bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola///
3227bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
323a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  AFI = MF.getInfo<ARMFunctionInfo>();
3246d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng  MCP = MF.getConstantPool();
325a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
326d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner  return AsmPrinter::runOnMachineFunction(MF);
32732bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola}
32832bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola
329055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
33035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                 raw_ostream &O, const char *Modifier) {
331055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
3325cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov  unsigned TF = MO.getTargetFlags();
3335cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov
3342f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  switch (MO.getType()) {
3358bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner  default:
3368bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(0 && "<unknown operand type>");
3375bafff36c798608a189c517d37527e4a38863071Bob Wilson  case MachineOperand::MO_Register: {
3385bafff36c798608a189c517d37527e4a38863071Bob Wilson    unsigned Reg = MO.getReg();
3398bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(TargetRegisterInfo::isPhysicalRegister(Reg));
3408bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    if (Modifier && strcmp(Modifier, "dregpair") == 0) {
341558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen      unsigned DRegLo = TM.getRegisterInfo()->getSubReg(Reg, ARM::dsub_0);
342558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen      unsigned DRegHi = TM.getRegisterInfo()->getSubReg(Reg, ARM::dsub_1);
3438bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner      O << '{'
344a0148c360e9bb4badabf1a2397cfd70907618f87Bob Wilson        << getRegisterName(DRegLo) << ", " << getRegisterName(DRegHi)
3458bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner        << '}';
3468bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    } else if (Modifier && strcmp(Modifier, "lane") == 0) {
3478bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner      unsigned RegNum = ARMRegisterInfo::getRegisterNumbering(Reg);
3489d1c1ada213c80135fbdda704175aae689daa6f9Chris Lattner      unsigned DReg =
349e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen        TM.getRegisterInfo()->getMatchingSuperReg(Reg,
350e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen          RegNum & 1 ? ARM::ssub_1 : ARM::ssub_0, &ARM::DPR_VFP2RegClass);
3518bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner      O << getRegisterName(DReg) << '[' << (RegNum & 1) << ']';
3528bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    } else {
353e8ea011cc766b37a957d5966655526096bf49feaAnton Korobeynikov      assert(!MO.getSubReg() && "Subregs should be eliminated!");
3548bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner      O << getRegisterName(Reg);
3558bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    }
3562f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
3575bafff36c798608a189c517d37527e4a38863071Bob Wilson  }
358a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_Immediate: {
3595adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng    int64_t Imm = MO.getImm();
360632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << '#';
3615cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
3625cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov        (TF & ARMII::MO_LO16))
3635cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
3645cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
3655cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov             (TF & ARMII::MO_HI16))
3665cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
367632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << Imm;
3682f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
369a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
3702f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_MachineBasicBlock:
3711b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner    O << *MO.getMBB()->getSymbol();
3722f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    return;
37384b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola  case MachineOperand::MO_GlobalAddress: {
374a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    bool isCallOp = Modifier && !strcmp(Modifier, "call");
37546510a73e977273ec67747eb34cbdb43f815e451Dan Gohman    const GlobalValue *GV = MO.getGlobal();
3765cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov
3775cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
3785cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov        (TF & ARMII::MO_LO16))
3795cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
3805cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
3815cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov             (TF & ARMII::MO_HI16))
3825cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
383d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner    O << *Mang->getSymbol(GV);
3847751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
3850c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner    printOffset(MO.getOffset(), O);
3867751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
3870ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio    if (isCallOp && Subtarget->isTargetELF() &&
3880ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio        TM.getRelocationModel() == Reloc::PIC_)
3890ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
3902f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
391a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
392a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_ExternalSymbol: {
393a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    bool isCallOp = Modifier && !strcmp(Modifier, "call");
39410b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner    O << *GetExternalSymbolSymbol(MO.getSymbolName());
39509533a404c7a80c1ca619c627bfc636b243ecd16Chris Lattner
3960ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio    if (isCallOp && Subtarget->isTargetELF() &&
3970ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio        TM.getRelocationModel() == Reloc::PIC_)
3980ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
3992f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
400a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
4012f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_ConstantPoolIndex:
4021b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetCPISymbol(MO.getIndex());
4032f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
404a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_JumpTableIndex:
4051b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetJTISymbol(MO.getIndex());
406a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    break;
4072f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  }
4087bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
4097bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
41035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnerstatic void printSOImm(raw_ostream &O, int64_t V, bool VerboseAsm,
41133adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner                       const MCAsmInfo *MAI) {
412e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng  // Break it up into two parts that make up a shifter immediate.
413e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng  V = ARM_AM::getSOImmVal(V);
414e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng  assert(V != -1 && "Not a valid so_imm value!");
415e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng
416c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  unsigned Imm = ARM_AM::getSOImmValImm(V);
417c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  unsigned Rot = ARM_AM::getSOImmValRot(V);
4187751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
419a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Print low-level immediate formation info, per
420a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // A5.1.3: "Data-processing operands - Immediate".
421a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Rot) {
422a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "#" << Imm << ", " << Rot;
423a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Pretty printed version.
42439382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng    if (VerboseAsm) {
42535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      O << "\t" << MAI->getCommentString() << ' ';
42639382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng      O << (int)ARM_AM::rotr32(Imm, Rot);
42739382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng    }
428a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
429a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "#" << Imm;
430a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
431a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
432a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
433c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
434c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// immediate in bits 0-7.
43535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum,
43635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O) {
437c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
438d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  assert(MO.isImm() && "Not a valid so_imm value!");
4393f53c8398d81065736a784469c9dd5afff85673fChris Lattner  printSOImm(O, MO.getImm(), isVerbose(), MAI);
440c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng}
441c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng
4429092213a5e50d4991f900d2df009d27bddfd9941Evan Cheng/// printSOImm2PartOperand - SOImm is broken into two pieces using a 'mov'
4439092213a5e50d4991f900d2df009d27bddfd9941Evan Cheng/// followed by an 'orr' to materialize.
44435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum,
44535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
446c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
447d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  assert(MO.isImm() && "Not a valid so_imm value!");
4489a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner  unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImm());
4499a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner  unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImm());
4503f53c8398d81065736a784469c9dd5afff85673fChris Lattner  printSOImm(O, V1, isVerbose(), MAI);
4515e148a37d3432f83ccc4dbebe08d4f1b4717034cEvan Cheng  O << "\n\torr";
45235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printPredicateOperand(MI, 2, O);
453162e30921da0ce1863672d4ca5fef541498fe6beEvan Cheng  O << "\t";
45435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, 0, O);
455c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  O << ", ";
45635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, 0, O);
457c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  O << ", ";
4583f53c8398d81065736a784469c9dd5afff85673fChris Lattner  printSOImm(O, V2, isVerbose(), MAI);
459c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng}
460c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng
461a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// so_reg is a 4-operand unit corresponding to register forms of the A5.1
462a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// "Addressing Mode 1 - Data-processing operands" forms.  This includes:
4639cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng//    REG 0   0           - e.g. R5
4649cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng//    REG REG 0,SH_OPC    - e.g. R5, ROR R3
465a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
46635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op,
46735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O) {
468a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
469a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
470a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
471a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
472762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << getRegisterName(MO1.getReg());
473a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
474a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Print the shift opc.
4751d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm());
4761d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
477a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (MO2.getReg()) {
4781d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson    O << ' ' << getRegisterName(MO2.getReg());
479a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
4801d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  } else if (ShOpc != ARM_AM::rrx) {
4811d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson    O << " #" << ARM_AM::getSORegOffset(MO3.getImm());
482a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
483a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
484a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
48535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op,
48635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
487a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
488a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
489a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
490a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
491d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
49235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, Op, O);
493a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
494a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
495a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
496762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
497a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
498a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!MO2.getReg()) {
4999e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0.
500a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << ", #"
5019e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen        << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
502a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        << ARM_AM::getAM2Offset(MO3.getImm());
503a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "]";
504a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
505a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
506a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
507a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << ", "
5089e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
509762ccea600158bb317dcccdff3303e942426cb71Chris Lattner    << getRegisterName(MO2.getReg());
510e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
511a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
512a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", "
5139a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
514a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << " #" << ShImm;
515a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
516a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
517a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
51835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op,
51935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O) {
520a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
521a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
522a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
523a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!MO1.getReg()) {
524bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng    unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
525bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng    O << "#"
5269e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen      << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
527bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng      << ImmOffs;
528a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
529a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
530a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
5319e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen  O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
532762ccea600158bb317dcccdff3303e942426cb71Chris Lattner    << getRegisterName(MO1.getReg());
533e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
534a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
535a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", "
5369a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm()))
537a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << " #" << ShImm;
538a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
539a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
54035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op,
54135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
542a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
543a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
544a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
545e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
5466f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
547762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
548a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
549a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (MO2.getReg()) {
550a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", "
551a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << (char)ARM_AM::getAM3Op(MO3.getImm())
552762ccea600158bb317dcccdff3303e942426cb71Chris Lattner      << getRegisterName(MO2.getReg())
553a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << "]";
554a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
555a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
556e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
557a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
558a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", #"
5599e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen      << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()))
560a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << ImmOffs;
561a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
562a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
563a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
56435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op,
56535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O){
566a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
567a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
568a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
569a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (MO1.getReg()) {
570a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << (char)ARM_AM::getAM3Op(MO2.getImm())
571762ccea600158bb317dcccdff3303e942426cb71Chris Lattner      << getRegisterName(MO1.getReg());
572a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
573a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
574a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
575a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
576a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "#"
5779e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()))
578a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    << ImmOffs;
579a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
580e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
581a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
58235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O,
583a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                          const char *Modifier) {
584a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
585a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
586a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Modifier && strcmp(Modifier, "submode") == 0) {
587ea7f22c31d0d12923eaab6840322431cc0222ae9Bob Wilson    O << ARM_AM::getAMSubModeStr(Mode);
588d77c7aba83bb290b9b62ede38b6ddbc9b790c6efEvan Cheng  } else if (Modifier && strcmp(Modifier, "wide") == 0) {
589d77c7aba83bb290b9b62ede38b6ddbc9b790c6efEvan Cheng    ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
590d77c7aba83bb290b9b62ede38b6ddbc9b790c6efEvan Cheng    if (Mode == ARM_AM::ia)
591d77c7aba83bb290b9b62ede38b6ddbc9b790c6efEvan Cheng      O << ".w";
592a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
59335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, Op, O);
594a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
595a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
596a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
597a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
59835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O,
599a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                          const char *Modifier) {
600a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
601a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
602a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
603d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
60435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, Op, O);
605a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
606a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
607e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
6086f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
609a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
610a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Modifier && strcmp(Modifier, "submode") == 0) {
611a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MO2.getImm());
612e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach    O << ARM_AM::getAMSubModeStr(Mode);
613a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
614a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else if (Modifier && strcmp(Modifier, "base") == 0) {
615a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Used for FSTM{D|S} and LSTM{D|S} operations.
616762ccea600158bb317dcccdff3303e942426cb71Chris Lattner    O << getRegisterName(MO1.getReg());
617a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
618a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
619e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
620762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
621e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
622a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
623a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", #"
6249e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen      << ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2.getImm()))
625a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << ImmOffs*4;
626a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
627a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
628a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
629a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
63035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode6Operand(const MachineInstr *MI, int Op,
63135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
6328b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson  const MachineOperand &MO1 = MI->getOperand(Op);
6338b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson  const MachineOperand &MO2 = MI->getOperand(Op+1);
6348b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson
6358a5ec86a3d4d599984e52c0c5a3a6a436607cf3eJim Grosbach  O << "[" << getRegisterName(MO1.getReg());
636226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson  if (MO2.getImm()) {
637bce3dbd9be29a42f32eb888086050cd620f2133bAnton Korobeynikov    // FIXME: Both darwin as and GNU as violate ARM docs here.
638273ff31e134d48c8247e981d30e214e82568ff86Bob Wilson    O << ", :" << (MO2.getImm() << 3);
6398a5ec86a3d4d599984e52c0c5a3a6a436607cf3eJim Grosbach  }
6408a5ec86a3d4d599984e52c0c5a3a6a436607cf3eJim Grosbach  O << "]";
641226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson}
642a43e6bf69093b9870548e7d782ea148e2ddd6449Bob Wilson
64335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode6OffsetOperand(const MachineInstr *MI, int Op,
64435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O){
645226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson  const MachineOperand &MO = MI->getOperand(Op);
646226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson  if (MO.getReg() == 0)
647226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson    O << "!";
648226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson  else
649226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson    O << ", " << getRegisterName(MO.getReg());
6508b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson}
6518b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson
652a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
65335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O,
654a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                           const char *Modifier) {
655a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Modifier && strcmp(Modifier, "label") == 0) {
65635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printPCLabel(MI, Op+1, O);
657a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
658a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
659a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
660a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
6616f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
6629e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen  O << "[pc, " << getRegisterName(MO1.getReg()) << "]";
663a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
664a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
665a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
66635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printBitfieldInvMaskImmOperand(const MachineInstr *MI, int Op,
66735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                              raw_ostream &O) {
668f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng  const MachineOperand &MO = MI->getOperand(Op);
669f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng  uint32_t v = ~MO.getImm();
6709e03cbefc5b3b8772a18d9bd25593ce62137ac85Evan Cheng  int32_t lsb = CountTrailingZeros_32(v);
671b825aaa0289206a63f7e6ce7b5ca7c2d6a2c063eNick Lewycky  int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb;
672f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng  assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
673f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng  O << "#" << lsb << ", #" << width;
674f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng}
675f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng
6761adc40cac314b0a77b790b094bca146a3a868452Johnny Chenvoid
6771adc40cac314b0a77b790b094bca146a3a868452Johnny ChenARMAsmPrinter::printMemBOption(const MachineInstr *MI, int OpNum,
6781adc40cac314b0a77b790b094bca146a3a868452Johnny Chen                               raw_ostream &O) {
6791adc40cac314b0a77b790b094bca146a3a868452Johnny Chen  unsigned val = MI->getOperand(OpNum).getImm();
6801adc40cac314b0a77b790b094bca146a3a868452Johnny Chen  O << ARM_MB::MemBOptToString(val);
6811adc40cac314b0a77b790b094bca146a3a868452Johnny Chen}
6821adc40cac314b0a77b790b094bca146a3a868452Johnny Chen
683eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilsonvoid ARMAsmPrinter::printSatShiftOperand(const MachineInstr *MI, int OpNum,
684eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson                                         raw_ostream &O) {
685eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  unsigned ShiftOp = MI->getOperand(OpNum).getImm();
686eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  ARM_AM::ShiftOpc Opc = ARM_AM::getSORegShOp(ShiftOp);
687eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  switch (Opc) {
688eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  case ARM_AM::no_shift:
689eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    return;
690eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  case ARM_AM::lsl:
691eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    O << ", lsl #";
692eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    break;
693eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  case ARM_AM::asr:
694eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    O << ", asr #";
695eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    break;
696eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  default:
697eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    assert(0 && "unexpected shift opcode for saturate shift operand");
698eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  }
699eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  O << ARM_AM::getSORegOffset(ShiftOp);
700eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson}
701eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson
702055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===//
703055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
70435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printThumbS4ImmOperand(const MachineInstr *MI, int Op,
70535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
7062ef9c8a43d1030bf65cafedf4b4b3f04d30180ceEvan Cheng  O << "#" <<  MI->getOperand(Op).getImm() * 4;
7072ef9c8a43d1030bf65cafedf4b4b3f04d30180ceEvan Cheng}
7082ef9c8a43d1030bf65cafedf4b4b3f04d30180ceEvan Cheng
709f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Chengvoid
71035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbITMask(const MachineInstr *MI, int Op,
71135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                raw_ostream &O) {
712e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  // (3 - the number of trailing zeros) is the number of then / else.
713e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  unsigned Mask = MI->getOperand(Op).getImm();
7149e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen  unsigned CondBit0 = Mask >> 4 & 1;
715e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  unsigned NumTZ = CountTrailingZeros_32(Mask);
716e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  assert(NumTZ <= 3 && "Invalid IT mask!");
71706e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
7189e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    bool T = ((Mask >> Pos) & 1) == CondBit0;
719e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng    if (T)
720e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng      O << 't';
721e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng    else
722e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng      O << 'e';
723e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  }
724e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng}
725e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng
726e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Chengvoid
72735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op,
72835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
729a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
730a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
731762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
732762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << ", " << getRegisterName(MO2.getReg()) << "]";
733a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
734a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
735a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
736a8e2989ece6dc46df59b0768184028257f913843Evan ChengARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
73735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                            raw_ostream &O,
738a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                            unsigned Scale) {
739a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
740cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
741cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
742a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
743d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
74435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, Op, O);
745a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
746a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
747a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
748762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
749cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  if (MO3.getReg())
750762ccea600158bb317dcccdff3303e942426cb71Chris Lattner    O << ", " << getRegisterName(MO3.getReg());
7514b6bbe1e9c40fb58eccaf3671432661016663aabEvan Cheng  else if (unsigned ImmOffs = MO2.getImm())
7529e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << ImmOffs * Scale;
753a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
754a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
755a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
756a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
75735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op,
75835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
75935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printThumbAddrModeRI5Operand(MI, Op, O, 1);
760a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
761a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
76235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op,
76335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
76435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printThumbAddrModeRI5Operand(MI, Op, O, 2);
765a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
766a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
76735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op,
76835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
76935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printThumbAddrModeRI5Operand(MI, Op, O, 4);
770a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
771a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
77235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op,
77335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O) {
774a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
775a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
776762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
777a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ImmOffs = MO2.getImm())
7789e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << ImmOffs*4;
779a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
7807bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
7817bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
782055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===//
783055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
7849cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
7859cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng// register with shift forms.
7869cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng// REG 0   0           - e.g. R5
7879cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng// REG IMM, SH_OPC     - e.g. R5, LSL #3
78835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printT2SOOperand(const MachineInstr *MI, int OpNum,
78935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O) {
7909cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
7919cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
7929cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng
7939cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  unsigned Reg = MO1.getReg();
7949cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  assert(TargetRegisterInfo::isPhysicalRegister(Reg));
795762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << getRegisterName(Reg);
7969cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng
7979cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  // Print the shift opc.
7989cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  assert(MO2.isImm() && "Not a valid t2_so_reg value!");
7991d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO2.getImm());
8001d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
8011d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  if (ShOpc != ARM_AM::rrx)
8021d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson    O << " #" << ARM_AM::getSORegOffset(MO2.getImm());
8039cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng}
8049cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng
805055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printT2AddrModeImm12Operand(const MachineInstr *MI,
80635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                int OpNum,
80735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O) {
808055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
809055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
810055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
811762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
812055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
813055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  unsigned OffImm = MO2.getImm();
814055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  if (OffImm)  // Don't print +0.
8159e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << OffImm;
816055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  O << "]";
817055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng}
818055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
819055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printT2AddrModeImm8Operand(const MachineInstr *MI,
82035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                               int OpNum,
82135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                               raw_ostream &O) {
822055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
823055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
824055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
825762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
826055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
827055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  int32_t OffImm = (int32_t)MO2.getImm();
828055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  // Don't print +0.
829055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  if (OffImm < 0)
830055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    O << ", #-" << -OffImm;
831055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  else if (OffImm > 0)
8329e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << OffImm;
833055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  O << "]";
834055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng}
835055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
8365c874172ac8fd563867efc54022ac4c1571e1313Evan Chengvoid ARMAsmPrinter::printT2AddrModeImm8s4Operand(const MachineInstr *MI,
83735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                 int OpNum,
83835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                 raw_ostream &O) {
8395c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
8405c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
8415c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng
842762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
8435c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng
8445c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  int32_t OffImm = (int32_t)MO2.getImm() / 4;
8455c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  // Don't print +0.
8465c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  if (OffImm < 0)
847a64ce4591762b93030cd2a2ff202bbd5badfecddEvan Cheng    O << ", #-" << -OffImm * 4;
8485c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  else if (OffImm > 0)
8499e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << OffImm * 4;
8505c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  O << "]";
8515c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng}
8525c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng
853e88d5cee9d6b02bc786df806395a718464908064Evan Chengvoid ARMAsmPrinter::printT2AddrModeImm8OffsetOperand(const MachineInstr *MI,
85435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                     int OpNum,
85535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                     raw_ostream &O) {
856e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
857e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  int32_t OffImm = (int32_t)MO1.getImm();
858e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  // Don't print +0.
859e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  if (OffImm < 0)
860e88d5cee9d6b02bc786df806395a718464908064Evan Cheng    O << "#-" << -OffImm;
861e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  else if (OffImm > 0)
8629e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << "#" << OffImm;
8639e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen}
8649e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen
865055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printT2AddrModeSoRegOperand(const MachineInstr *MI,
86635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                int OpNum,
86735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O) {
868055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
869055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
870055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO3 = MI->getOperand(OpNum+2);
871055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
872762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
873055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
8743a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng  assert(MO2.getReg() && "Invalid so_reg load / store address!");
875762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << ", " << getRegisterName(MO2.getReg());
8769cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng
8773a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng  unsigned ShAmt = MO3.getImm();
8783a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng  if (ShAmt) {
8793a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng    assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
8803a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng    O << ", lsl #" << ShAmt;
881055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  }
882055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  O << "]";
883055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng}
884055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
885055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
886055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===//
887055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
88835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printPredicateOperand(const MachineInstr *MI, int OpNum,
88935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
890055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
89144bec52b1b7e9a3ac1efbae90db240b8c1ca2ad4Evan Cheng  if (CC != ARMCC::AL)
89244bec52b1b7e9a3ac1efbae90db240b8c1ca2ad4Evan Cheng    O << ARMCondCodeToString(CC);
8937bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
8947bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
8959d3acaa1a015c4499595eaff529686a517c14e15Johnny Chenvoid ARMAsmPrinter::printMandatoryPredicateOperand(const MachineInstr *MI,
89635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                   int OpNum,
89735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                   raw_ostream &O) {
8989d3acaa1a015c4499595eaff529686a517c14e15Johnny Chen  ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
8999d3acaa1a015c4499595eaff529686a517c14e15Johnny Chen  O << ARMCondCodeToString(CC);
9009d3acaa1a015c4499595eaff529686a517c14e15Johnny Chen}
9019d3acaa1a015c4499595eaff529686a517c14e15Johnny Chen
90235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printSBitModifierOperand(const MachineInstr *MI, int OpNum,
90335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                             raw_ostream &O){
904055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  unsigned Reg = MI->getOperand(OpNum).getReg();
905dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng  if (Reg) {
906dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng    assert(Reg == ARM::CPSR && "Expect ARM CPSR register!");
907dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng    O << 's';
908dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng  }
909dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng}
910dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng
91135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int OpNum,
91235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                 raw_ostream &O) {
913055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  int Id = (int)MI->getOperand(OpNum).getImm();
914e7e0d62efda2445b735052ca45bd74fb002e34c3Evan Cheng  O << MAI->getPrivateGlobalPrefix()
915e7e0d62efda2445b735052ca45bd74fb002e34c3Evan Cheng    << "PC" << getFunctionNumber() << "_" << Id;
916a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
917a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
91835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int OpNum,
91935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O) {
920a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "{";
921815baebe1c8dc02accf128ae10dff9a1742d3244Bob Wilson  for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
9224b322e58b77d16f103d88a3af3a4ebd2675245a0Evan Cheng    if (MI->getOperand(i).isImplicit())
9234b322e58b77d16f103d88a3af3a4ebd2675245a0Evan Cheng      continue;
924815baebe1c8dc02accf128ae10dff9a1742d3244Bob Wilson    if ((int)i != OpNum) O << ", ";
92535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, i, O);
926a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
927a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "}";
928a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
929a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
930055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNum,
93135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                       raw_ostream &O, const char *Modifier) {
932a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  assert(Modifier && "This operand only works with a modifier!");
933a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
934a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // data itself.
935a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!strcmp(Modifier, "label")) {
936055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    unsigned ID = MI->getOperand(OpNum).getImm();
9378e089a9e4d6b7aa2b3968c38644f926f60a7c670Chris Lattner    OutStreamer.EmitLabel(GetCPISymbol(ID));
938a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
939a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
940055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    unsigned CPI = MI->getOperand(OpNum).getIndex();
941a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
9426d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI];
943e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
944711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    if (MCPE.isMachineConstantPoolEntry()) {
945a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
946711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    } else {
947a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      EmitGlobalConstant(MCPE.Val.ConstVal);
948305b8a5f62c9d027f3d8a870fc12fc2abf69aeeaLauro Ramos Venancio    }
949a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
950a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
951a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
9520890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
9530890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
9540890cf124f00da3dc943c1882f4221955e0281edChris Lattner                            const MachineBasicBlock *MBB) const {
9550890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
9560890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
957bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2
9580890cf124f00da3dc943c1882f4221955e0281edChris Lattner    << "_set_" << MBB->getNumber();
9599b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
9600890cf124f00da3dc943c1882f4221955e0281edChris Lattner}
9610890cf124f00da3dc943c1882f4221955e0281edChris Lattner
9620890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
9630890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
9640890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
9650890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
966281e7767df71b3f727ade80a16ff0c4fe5a49dd9Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2;
9679b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
968bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner}
969bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner
97035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum,
97135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                        raw_ostream &O) {
97266ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  assert(!Subtarget->isThumb2() && "Thumb2 should use double-jump jumptables!");
97366ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng
974055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
975055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
9761b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner
9778aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner  unsigned JTI = MO1.getIndex();
9780890cf124f00da3dc943c1882f4221955e0281edChris Lattner  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
97903335350547b5d3521f9912d301bbb799d7eea31Chris Lattner  // Can't use EmitLabel until instprinter happens, label comes out in the wrong
98003335350547b5d3521f9912d301bbb799d7eea31Chris Lattner  // order.
981d4d188e5029801ef2a76ee756dcba49f313004f0Bob Wilson  O << "\n" << *JTISymbol << ":\n";
982a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
98333adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner  const char *JTEntryDirective = MAI->getData32bitsDirective();
984a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
9854542611bb9793e8376d7d5f33b4a1e2d11712894Dan Gohman  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
986a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
987a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
988cee63322eaccc2f1067bdf5eab506e440f867da1Chris Lattner  bool UseSet= MAI->hasSetDirective() && TM.getRelocationModel() == Reloc::PIC_;
989c324ecb7bc93a1f09db29851438ec5ee72b143ebEvan Cheng  SmallPtrSet<MachineBasicBlock*, 8> JTSets;
990a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
991a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    MachineBasicBlock *MBB = JTBBs[i];
99266ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng    bool isNew = JTSets.insert(MBB);
99366ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng
9940890cf124f00da3dc943c1882f4221955e0281edChris Lattner    if (UseSet && isNew) {
995cee63322eaccc2f1067bdf5eab506e440f867da1Chris Lattner      O << "\t.set\t"
9961f9b48ad87a5dab4a6c3805c369414c831e4451dJim Grosbach        << *GetARMSetPICJumpTableLabel2(JTI, MO2.getImm(), MBB) << ','
9971b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner        << *MBB->getSymbol() << '-' << *JTISymbol << '\n';
9980890cf124f00da3dc943c1882f4221955e0281edChris Lattner    }
999a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1000a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << JTEntryDirective << ' ';
1001a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (UseSet)
10020890cf124f00da3dc943c1882f4221955e0281edChris Lattner      O << *GetARMSetPICJumpTableLabel2(JTI, MO2.getImm(), MBB);
10030890cf124f00da3dc943c1882f4221955e0281edChris Lattner    else if (TM.getRelocationModel() == Reloc::PIC_)
10041b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner      O << *MBB->getSymbol() << '-' << *JTISymbol;
10050890cf124f00da3dc943c1882f4221955e0281edChris Lattner    else
10061b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner      O << *MBB->getSymbol();
10070890cf124f00da3dc943c1882f4221955e0281edChris Lattner
1008d85ac4d07966a56b3101598f29393f4532acc50fEvan Cheng    if (i != e-1)
1009d85ac4d07966a56b3101598f29393f4532acc50fEvan Cheng      O << '\n';
1010a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
1011a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
1012a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
101335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printJT2BlockOperand(const MachineInstr *MI, int OpNum,
101435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                         raw_ostream &O) {
101566ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
101666ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
101766ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  unsigned JTI = MO1.getIndex();
10180890cf124f00da3dc943c1882f4221955e0281edChris Lattner
10190890cf124f00da3dc943c1882f4221955e0281edChris Lattner  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
102003335350547b5d3521f9912d301bbb799d7eea31Chris Lattner
102103335350547b5d3521f9912d301bbb799d7eea31Chris Lattner  // Can't use EmitLabel until instprinter happens, label comes out in the wrong
102203335350547b5d3521f9912d301bbb799d7eea31Chris Lattner  // order.
1023d4d188e5029801ef2a76ee756dcba49f313004f0Bob Wilson  O << "\n" << *JTISymbol << ":\n";
102466ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng
102566ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
102666ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
102766ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
10285657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  bool ByteOffset = false, HalfWordOffset = false;
10295657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  if (MI->getOpcode() == ARM::t2TBB)
10305657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    ByteOffset = true;
10315657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  else if (MI->getOpcode() == ARM::t2TBH)
10325657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    HalfWordOffset = true;
10335657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng
103466ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
103566ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng    MachineBasicBlock *MBB = JTBBs[i];
10365657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    if (ByteOffset)
103733adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner      O << MAI->getData8bitsDirective();
10385657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    else if (HalfWordOffset)
103933adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner      O << MAI->getData16bitsDirective();
10400890cf124f00da3dc943c1882f4221955e0281edChris Lattner
10410890cf124f00da3dc943c1882f4221955e0281edChris Lattner    if (ByteOffset || HalfWordOffset)
10421b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner      O << '(' << *MBB->getSymbol() << "-" << *JTISymbol << ")/2";
10430890cf124f00da3dc943c1882f4221955e0281edChris Lattner    else
10441b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner      O << "\tb.w " << *MBB->getSymbol();
10450890cf124f00da3dc943c1882f4221955e0281edChris Lattner
104666ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng    if (i != e-1)
104766ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng      O << '\n';
104866ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  }
104966ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng}
105066ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng
105135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printTBAddrMode(const MachineInstr *MI, int OpNum,
105235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                    raw_ostream &O) {
1053762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[pc, " << getRegisterName(MI->getOperand(OpNum).getReg());
10545657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  if (MI->getOpcode() == ARM::t2TBH)
10555657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    O << ", lsl #1";
10565657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  O << ']';
10575657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng}
10585657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng
105935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printNoHashImmediate(const MachineInstr *MI, int OpNum,
106035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                         raw_ostream &O) {
10618e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov  O << MI->getOperand(OpNum).getImm();
10628e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov}
1063a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
106435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printVFPf32ImmOperand(const MachineInstr *MI, int OpNum,
106535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
106639382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng  const ConstantFP *FP = MI->getOperand(OpNum).getFPImm();
106777b02beb1fa3a96efc05081889d1ae4ffecb44a7Jim Grosbach  O << '#' << FP->getValueAPF().convertToFloat();
10683f53c8398d81065736a784469c9dd5afff85673fChris Lattner  if (isVerbose()) {
106935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    O << "\t\t" << MAI->getCommentString() << ' ';
107039382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng    WriteAsOperand(O, FP, /*PrintType=*/false);
107139382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng  }
107239382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng}
107339382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng
107435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printVFPf64ImmOperand(const MachineInstr *MI, int OpNum,
107535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
107639382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng  const ConstantFP *FP = MI->getOperand(OpNum).getFPImm();
107777b02beb1fa3a96efc05081889d1ae4ffecb44a7Jim Grosbach  O << '#' << FP->getValueAPF().convertToDouble();
10783f53c8398d81065736a784469c9dd5afff85673fChris Lattner  if (isVerbose()) {
107935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    O << "\t\t" << MAI->getCommentString() << ' ';
108039382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng    WriteAsOperand(O, FP, /*PrintType=*/false);
108139382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng  }
108239382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng}
108339382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng
10841a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilsonvoid ARMAsmPrinter::printNEONModImmOperand(const MachineInstr *MI, int OpNum,
10851a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson                                           raw_ostream &O) {
10866dce00ced45b5bd1b7f34fe6f2d70c50fc090664Bob Wilson  unsigned EncodedImm = MI->getOperand(OpNum).getImm();
10876dce00ced45b5bd1b7f34fe6f2d70c50fc090664Bob Wilson  unsigned EltBits;
10886dce00ced45b5bd1b7f34fe6f2d70c50fc090664Bob Wilson  uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits);
10891a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson  O << "#0x" << utohexstr(Val);
10901a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson}
10911a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson
1092055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
1093c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    unsigned AsmVariant, const char *ExtraCode,
1094c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    raw_ostream &O) {
1095a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Does this asm operand have a single letter operand modifier?
1096a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (ExtraCode && ExtraCode[0]) {
1097a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ExtraCode[1] != 0) return true; // Unknown modifier.
10988e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov
1099a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    switch (ExtraCode[0]) {
1100a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    default: return true;  // Unknown modifier.
11019b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'a': // Print as a memory address.
11029b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      if (MI->getOperand(OpNum).isReg()) {
1103762ccea600158bb317dcccdff3303e942426cb71Chris Lattner        O << "[" << getRegisterName(MI->getOperand(OpNum).getReg()) << "]";
11049b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson        return false;
11059b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      }
11069b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      // Fallthrough
11079b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'c': // Don't print "#" before an immediate operand.
11084f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson      if (!MI->getOperand(OpNum).isImm())
11094f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson        return true;
111035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      printNoHashImmediate(MI, OpNum, O);
11118f3434647d3d39b49475239e3be1b8afb06415cfBob Wilson      return false;
1112e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng    case 'P': // Print a VFP double precision register.
1113d831cda3e74235704f163d5a18352584d537517aEvan Cheng    case 'q': // Print a NEON quad precision register.
111435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      printOperand(MI, OpNum, O);
111523a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng      return false;
1116a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'Q':
1117a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'R':
1118d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson    case 'H':
111912616727c71721f480f69026d88a58a067d89824Evan Cheng      report_fatal_error("llvm does not support 'Q', 'R', and 'H' modifiers!");
1120d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson      return true;
112184f60b7359e1aa90794bb19de2bbf4d25dc2f01dEvan Cheng    }
1122a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
1123e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
112435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, OpNum, O);
1125a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  return false;
1126a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
1127a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1128224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilsonbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
1129055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng                                          unsigned OpNum, unsigned AsmVariant,
1130c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          const char *ExtraCode,
1131c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          raw_ostream &O) {
1132224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  if (ExtraCode && ExtraCode[0])
1133224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson    return true; // Unknown modifier.
1134765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson
1135765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  const MachineOperand &MO = MI->getOperand(OpNum);
1136765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  assert(MO.isReg() && "unexpected inline asm memory operand");
1137765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  O << "[" << getRegisterName(MO.getReg()) << "]";
1138224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  return false;
1139224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson}
1140224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson
1141a786ceac5c888761d83d84d35eb16150be57cc6eChris Lattnervoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
114297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  if (EnableMCInst) {
114397f06937449c593a248dbbb1365e6ae408fb9decChris Lattner    printInstructionThroughMCStreamer(MI);
11447ad07c46362500f7291a92742569e94fd3538dfdChris Lattner    return;
114597f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  }
11467ad07c46362500f7291a92742569e94fd3538dfdChris Lattner
11477ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  if (MI->getOpcode() == ARM::CONSTPOOL_ENTRY)
11487ad07c46362500f7291a92742569e94fd3538dfdChris Lattner    EmitAlignment(2);
11497ad07c46362500f7291a92742569e94fd3538dfdChris Lattner
11507ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  SmallString<128> Str;
11517ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  raw_svector_ostream OS(Str);
11523f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen  if (MI->getOpcode() == ARM::DBG_VALUE) {
11533f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    unsigned NOps = MI->getNumOperands();
11543f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    assert(NOps==4);
11553f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
11563f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    // cast away const; DIetc do not take const operands for some reason.
11573f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
11583f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << V.getName();
11593f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << " <- ";
11603f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    // Frame address.  Currently handles register +- offset only.
11613f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
11623f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS);
11633f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << ']';
11643f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << "+";
11653f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    printOperand(MI, NOps-2, OS);
11663f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OutStreamer.EmitRawText(OS.str());
11673f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    return;
11683f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen  }
11693f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen
11707ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  printInstruction(MI, OS);
11717ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  OutStreamer.EmitRawText(OS.str());
11727ad07c46362500f7291a92742569e94fd3538dfdChris Lattner
11737ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  // Make sure the instruction that follows TBB is 2-byte aligned.
11747ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  // FIXME: Constant island pass should insert an "ALIGN" instruction instead.
11757ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  if (MI->getOpcode() == ARM::t2TBB)
11767ad07c46362500f7291a92742569e94fd3538dfdChris Lattner    EmitAlignment(1);
1177a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
1178a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1179812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
11800fb34683b9e33238288d2af1e090582464df8387Bob Wilson  if (Subtarget->isTargetDarwin()) {
11810fb34683b9e33238288d2af1e090582464df8387Bob Wilson    Reloc::Model RelocM = TM.getRelocationModel();
11820fb34683b9e33238288d2af1e090582464df8387Bob Wilson    if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
11830fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // Declare all the text sections up front (before the DWARF sections
11840fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // emitted by AsmPrinter::doInitialization) so the assembler will keep
11850fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // them together at the beginning of the object file.  This helps
11860fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // avoid out-of-range branches that are due a fundamental limitation of
11870fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // the way symbol offsets are encoded with the current Darwin ARM
11880fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // relocations.
11890d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman      const TargetLoweringObjectFileMachO &TLOFMacho =
11900d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman        static_cast<const TargetLoweringObjectFileMachO &>(
11910d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman          getObjFileLowering());
119229e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextSection());
119329e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
119429e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection());
119529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      if (RelocM == Reloc::DynamicNoPIC) {
119629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
119722772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__symbol_stub4",
119822772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
119922772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     12, SectionKind::getText());
120029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
120129e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      } else {
120229e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
120322772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__picsymbolstub4",
120422772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
120522772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     16, SectionKind::getText());
120629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
120729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      }
120863db594559dc8eac666204c7907bae664f5234daBob Wilson      const MCSection *StaticInitSect =
120963db594559dc8eac666204c7907bae664f5234daBob Wilson        OutContext.getMachOSection("__TEXT", "__StaticInit",
121063db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_REGULAR |
121163db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
121263db594559dc8eac666204c7907bae664f5234daBob Wilson                                   SectionKind::getText());
121363db594559dc8eac666204c7907bae664f5234daBob Wilson      OutStreamer.SwitchSection(StaticInitSect);
12140fb34683b9e33238288d2af1e090582464df8387Bob Wilson    }
12150fb34683b9e33238288d2af1e090582464df8387Bob Wilson  }
12160fb34683b9e33238288d2af1e090582464df8387Bob Wilson
1217e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach  // Use unified assembler syntax.
12189d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  OutStreamer.EmitRawText(StringRef("\t.syntax unified"));
1219d61eca533081580d56fabee38f86507d8019ca75Anton Korobeynikov
122088ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  // Emit ARM Build Attributes
122188ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  if (Subtarget->isTargetELF()) {
122288ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // CPU Type
1223d260c248abd57763aaeeadcab4155655a25d9e97Anton Korobeynikov    std::string CPUString = Subtarget->getCPUString();
1224d260c248abd57763aaeeadcab4155655a25d9e97Anton Korobeynikov    if (CPUString != "generic")
12259d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.cpu " + Twine(CPUString));
122688ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
122788ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // FIXME: Emit FPU type
122888ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    if (Subtarget->hasVFP2())
12299d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12309d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::VFP_arch) + ", 2");
123188ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
123288ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // Signal various FP modes.
12339d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    if (!UnsafeFPMath) {
12349d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12359d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_denormal) + ", 1");
12369d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12379d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_exceptions) + ", 1");
12389d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    }
12399d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner
124060108e96bbc5432f4fe06ba313e64448e97a0e15Evan Cheng    if (NoInfsFPMath && NoNaNsFPMath)
12419d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12429d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 1");
124388ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    else
12449d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12459d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 3");
124688ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
124788ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // 8-bytes alignment stuff.
12489d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.EmitRawText("\t.eabi_attribute " +
12499d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                            Twine(ARMBuildAttrs::ABI_align8_needed) + ", 1");
12509d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.EmitRawText("\t.eabi_attribute " +
12519d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                            Twine(ARMBuildAttrs::ABI_align8_preserved) + ", 1");
125288ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
1253567d14f07cd62bfb9dd0edd90144a0a840450f7aAnton Korobeynikov    // Hard float.  Use both S and D registers and conform to AAPCS-VFP.
12549d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) {
12559d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12569d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_HardFP_use) + ", 3");
12579d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12589d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_VFP_args) + ", 1");
12599d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    }
126088ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // FIXME: Should we signal R9 usage?
126188ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  }
12627bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
12637bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
12640f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
12654a071d667d995b00e7853243ff9c7c1269324478Chris Lattnervoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
12665be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng  if (Subtarget->isTargetDarwin()) {
1267f61159b574155b056dbd5d6d44f47f753d424056Chris Lattner    // All darwin targets use mach-o.
12680d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman    const TargetLoweringObjectFileMachO &TLOFMacho =
12690d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman      static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
1270b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO &MMIMacho =
1271b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      MMI->getObjFileInfo<MachineModuleInfoMachO>();
1272e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
1273a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Output non-lazy-pointers for external and common global variables.
1274b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
1275cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling
1276b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    if (!Stubs.empty()) {
1277ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner      // Switch with ".non_lazy_symbol_pointer" directive.
12786c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
1279c076a9793936b140364671a5e39ee53bd266c6c3Chris Lattner      EmitAlignment(2);
1280b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1281becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
1282becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
1283becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .indirect_symbol _foo
128452a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
128552a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol);
1286cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
128752a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        if (MCSym.getInt())
1288cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // External to current translation unit.
1289cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
1290cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling        else
1291cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // Internal to current translation unit.
12925e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          //
12935e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          // When we place the LSDA into the TEXT section, the type info pointers
12945e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          // need to be indirect and pc-rel. We accomplish this by using NLPs.
12955e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          // However, sometimes the types are local to the file. So we need to
12965e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          // fill in the value for the NLP in those cases.
129752a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling          OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
129852a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling                                                        OutContext),
1299cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling                                4/*size*/, 0/*addrspace*/);
1300ae94e594164b193236002516970aeec4c4574768Evan Cheng      }
1301becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling
1302becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      Stubs.clear();
1303becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      OutStreamer.AddBlankLine();
1304a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
1305a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1306e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    Stubs = MMIMacho.GetHiddenGVStubList();
1307e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    if (!Stubs.empty()) {
13086c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
1309f3231de60bb64c3f6fc6770b3e6174f4f839a4f3Chris Lattner      EmitAlignment(2);
1310becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1311becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
1312becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
1313becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .long _foo
1314cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling        OutStreamer.EmitValue(MCSymbolRefExpr::
1315cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                              Create(Stubs[i].second.getPointer(),
1316cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                                     OutContext),
1317becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling                              4/*size*/, 0/*addrspace*/);
1318becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      }
1319cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
1320cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      Stubs.clear();
1321cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      OutStreamer.AddBlankLine();
1322ae94e594164b193236002516970aeec4c4574768Evan Cheng    }
1323ae94e594164b193236002516970aeec4c4574768Evan Cheng
1324a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Funny Darwin hack: This flag tells the linker that no global symbols
1325a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // contain code that falls through to other global symbols (e.g. the obvious
1326a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // implementation of multiple entry points).  If this doesn't occur, the
1327a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // linker can safely perform dead code stripping.  Since LLVM never
1328a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // generates code that does this, it is always safe to set.
1329a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner    OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
1330b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola  }
13317bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
13320bd89712c03c59ea43ce37763685e7f7c0bdd977Anton Korobeynikov
133397f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===----------------------------------------------------------------------===//
133497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner
133597f06937449c593a248dbbb1365e6ae408fb9decChris Lattnervoid ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
133696bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner  ARMMCInstLower MCInstLowering(OutContext, *Mang, *this);
133797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  switch (MI->getOpcode()) {
1338c6b8a9920787505468931e56696cef1245e25913Chris Lattner  case ARM::t2MOVi32imm:
1339c6b8a9920787505468931e56696cef1245e25913Chris Lattner    assert(0 && "Should be lowered by thumb2it pass");
13404d1522234192704f45dfd2527c2913fa60be616eChris Lattner  default: break;
13414d1522234192704f45dfd2527c2913fa60be616eChris Lattner  case ARM::PICADD: { // FIXME: Remove asm string from td file.
13424d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This is a pseudo op for a label + instruction sequence, which looks like:
13434d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // LPC0:
13444d1522234192704f45dfd2527c2913fa60be616eChris Lattner    //     add r0, pc, r0
13454d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This adds the address of LPC0 to r0.
13464d1522234192704f45dfd2527c2913fa60be616eChris Lattner
13474d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // Emit the label.
13484d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // FIXME: MOVE TO SHARED PLACE.
1349a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned Id = (unsigned)MI->getOperand(2).getImm();
13507c5b021793e8c8184c655040ea5e169b55c55063Chris Lattner    const char *Prefix = MAI->getPrivateGlobalPrefix();
13519b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner    MCSymbol *Label =OutContext.GetOrCreateSymbol(Twine(Prefix)
1352e7e0d62efda2445b735052ca45bd74fb002e34c3Evan Cheng                         + "PC" + Twine(getFunctionNumber()) + "_" + Twine(Id));
13537c5b021793e8c8184c655040ea5e169b55c55063Chris Lattner    OutStreamer.EmitLabel(Label);
13544d1522234192704f45dfd2527c2913fa60be616eChris Lattner
13554d1522234192704f45dfd2527c2913fa60be616eChris Lattner
13564d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // Form and emit tha dd.
13574d1522234192704f45dfd2527c2913fa60be616eChris Lattner    MCInst AddInst;
13584d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.setOpcode(ARM::ADDrr);
13594d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
13604d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
13614d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1362850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner    OutStreamer.EmitInstruction(AddInst);
13634d1522234192704f45dfd2527c2913fa60be616eChris Lattner    return;
13644d1522234192704f45dfd2527c2913fa60be616eChris Lattner  }
1365a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner  case ARM::CONSTPOOL_ENTRY: { // FIXME: Remove asm string from td file.
1366a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
1367a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// in the function.  The first operand is the ID# for this instruction, the
1368a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// second is the index into the MachineConstantPool that this is, the third
1369a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// is the size in bytes of this constant pool entry.
1370a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
1371a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned CPIdx   = (unsigned)MI->getOperand(1).getIndex();
1372a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
1373a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    EmitAlignment(2);
13741b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    OutStreamer.EmitLabel(GetCPISymbol(LabelId));
1375a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
1376a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
1377a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    if (MCPE.isMachineConstantPoolEntry())
1378a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
1379a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    else
1380a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitGlobalConstant(MCPE.Val.ConstVal);
1381a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
1382a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    return;
1383a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner  }
1384017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner  case ARM::MOVi2pieces: { // FIXME: Remove asmstring from td file.
1385017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    // This is a hack that lowers as a two instruction sequence.
1386017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned DstReg = MI->getOperand(0).getReg();
1387017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
1388017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner
1389017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(ImmVal);
1390017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(ImmVal);
1391017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner
1392017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    {
1393017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      MCInst TmpInst;
1394017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.setOpcode(ARM::MOVi);
1395017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));
1396017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(SOImmValV1));
1397017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner
1398017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      // Predicate.
1399017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1400017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1401233917c07282564351439df8e7a9c83c9d6c459eChris Lattner
1402233917c07282564351439df8e7a9c83c9d6c459eChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out
1403850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
1404017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    }
1405017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner
1406017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    {
1407017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      MCInst TmpInst;
1408017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.setOpcode(ARM::ORRri);
1409017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // dstreg
1410017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // inreg
1411017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(SOImmValV2)); // so_imm
1412017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      // Predicate.
1413017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1414017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1415017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner
1416017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out
1417850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
1418017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    }
1419017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    return;
1420017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner  }
1421161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner  case ARM::MOVi32imm: { // FIXME: Remove asmstring from td file.
1422161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    // This is a hack that lowers as a two instruction sequence.
1423161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    unsigned DstReg = MI->getOperand(0).getReg();
142418c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    const MachineOperand &MO = MI->getOperand(1);
142518c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    MCOperand V1, V2;
142618c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    if (MO.isImm()) {
142718c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
142818c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V1 = MCOperand::CreateImm(ImmVal & 65535);
142918c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V2 = MCOperand::CreateImm(ImmVal >> 16);
143018c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    } else if (MO.isGlobal()) {
143118c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      MCSymbol *Symbol = MCInstLowering.GetGlobalAddressSymbol(MO);
143218c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      const MCSymbolRefExpr *SymRef1 =
14333472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        MCSymbolRefExpr::Create(Symbol,
14343472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands                                MCSymbolRefExpr::VK_ARM_LO16, OutContext);
143518c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      const MCSymbolRefExpr *SymRef2 =
14363472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        MCSymbolRefExpr::Create(Symbol,
14373472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands                                MCSymbolRefExpr::VK_ARM_HI16, OutContext);
143818c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V1 = MCOperand::CreateExpr(SymRef1);
143918c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V2 = MCOperand::CreateExpr(SymRef2);
144018c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    } else {
144118c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      MI->dump();
144218c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      llvm_unreachable("cannot handle this operand");
144318c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    }
144418c1021ec108722506125926087b1e5fcfb28046Rafael Espindola
1445161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    {
1446161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      MCInst TmpInst;
1447161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.setOpcode(ARM::MOVi16);
1448161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
144918c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      TmpInst.addOperand(V1); // lower16(imm)
1450161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner
1451161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      // Predicate.
1452161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1453161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1454161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner
1455850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
1456161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    }
1457161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner
1458161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    {
1459161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      MCInst TmpInst;
1460161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.setOpcode(ARM::MOVTi16);
1461161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
1462161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // srcreg
146318c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      TmpInst.addOperand(V2);   // upper16(imm)
1464161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner
1465161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      // Predicate.
1466161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1467161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1468161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner
1469850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
1470161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    }
1471161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner
1472161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    return;
1473161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner  }
147497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  }
147597f06937449c593a248dbbb1365e6ae408fb9decChris Lattner
147697f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  MCInst TmpInst;
147797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  MCInstLowering.Lower(MI, TmpInst);
1478850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner  OutStreamer.EmitInstruction(TmpInst);
147997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner}
14802685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
14812685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
14822685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Target Registry Stuff
14832685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
14842685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
14852685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarstatic MCInstPrinter *createARMMCInstPrinter(const Target &T,
14862685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar                                             unsigned SyntaxVariant,
1487d374087be5360a353a4239a155b1227057145f48Chris Lattner                                             const MCAsmInfo &MAI) {
14882685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  if (SyntaxVariant == 0)
1489d374087be5360a353a4239a155b1227057145f48Chris Lattner    return new ARMInstPrinter(MAI, false);
14902685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  return 0;
14912685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
14922685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
14932685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Force static initialization.
14942685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarextern "C" void LLVMInitializeARMAsmPrinter() {
14952685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget);
14962685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget);
14972685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
14982685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter);
14992685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter);
15002685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
15012685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
1502