ARMAsmPrinter.cpp revision 882ef2b76a09cdc39d38756fca71cf6cf25ae590
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    }
93b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
94882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    void EmitJumpTable(const MachineInstr *MI);
95882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    void EmitJump2Table(const MachineInstr *MI);
9697f06937449c593a248dbbb1365e6ae408fb9decChris Lattner    void printInstructionThroughMCStreamer(const MachineInstr *MI);
97b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
987bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
9935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
100a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                      const char *Modifier = 0);
10135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printSOImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
10235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printSOImm2PartOperand(const MachineInstr *MI, int OpNum,
10335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                raw_ostream &O);
10435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printSORegOperand(const MachineInstr *MI, int OpNum,
10535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                           raw_ostream &O);
10635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode2Operand(const MachineInstr *MI, int OpNum,
10735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
10835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNum,
10935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
11035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode3Operand(const MachineInstr *MI, int OpNum,
11135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
11235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode3OffsetOperand(const MachineInstr *MI, int OpNum,
11335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
11435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode4Operand(const MachineInstr *MI, int OpNum,raw_ostream &O,
115a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                               const char *Modifier = 0);
11635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode5Operand(const MachineInstr *MI, int OpNum,raw_ostream &O,
117a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                               const char *Modifier = 0);
11835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode6Operand(const MachineInstr *MI, int OpNum,
11935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
12035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode6OffsetOperand(const MachineInstr *MI, int OpNum,
12135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
122055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    void printAddrModePCOperand(const MachineInstr *MI, int OpNum,
12335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                raw_ostream &O,
124a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                const char *Modifier = 0);
125eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    void printBitfieldInvMaskImmOperand(const MachineInstr *MI, int OpNum,
126eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson                                        raw_ostream &O);
1271adc40cac314b0a77b790b094bca146a3a868452Johnny Chen    void printMemBOption(const MachineInstr *MI, int OpNum,
1281adc40cac314b0a77b790b094bca146a3a868452Johnny Chen                         raw_ostream &O);
12922f5dc79c05d69391b17e14ed912aa8e98a63027Bob Wilson    void printShiftImmOperand(const MachineInstr *MI, int OpNum,
130eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson                              raw_ostream &O);
13135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner
13235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbS4ImmOperand(const MachineInstr *MI, int OpNum,
13335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                raw_ostream &O);
13435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbITMask(const MachineInstr *MI, int OpNum, raw_ostream &O);
13535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNum,
13635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
137055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNum,
13835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O,
139a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                      unsigned Scale);
14035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeS1Operand(const MachineInstr *MI, int OpNum,
14135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
14235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNum,
14335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
14435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNum,
14535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
14635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNum,
14735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
14835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner
14935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2SOOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
15035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm12Operand(const MachineInstr *MI, int OpNum,
15135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
15235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm8Operand(const MachineInstr *MI, int OpNum,
15335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                    raw_ostream &O);
15435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm8s4Operand(const MachineInstr *MI, int OpNum,
15535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O);
15635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm8OffsetOperand(const MachineInstr *MI, int OpNum,
15735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O);
15835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm8s4OffsetOperand(const MachineInstr *MI, int OpNum,
15935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                            raw_ostream &O) {}
16035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeSoRegOperand(const MachineInstr *MI, int OpNum,
16135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
16235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner
16335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printCPSOptionOperand(const MachineInstr *MI, int OpNum,
16435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O) {}
16535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printMSRMaskOperand(const MachineInstr *MI, int OpNum,
16635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                             raw_ostream &O) {}
16735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printNegZeroOperand(const MachineInstr *MI, int OpNum,
16835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                             raw_ostream &O) {}
16935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printPredicateOperand(const MachineInstr *MI, int OpNum,
17035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
17135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printMandatoryPredicateOperand(const MachineInstr *MI, int OpNum,
17235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                        raw_ostream &O);
17335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printSBitModifierOperand(const MachineInstr *MI, int OpNum,
17435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                  raw_ostream &O);
17535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printPCLabel(const MachineInstr *MI, int OpNum,
17635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                      raw_ostream &O);
17735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printRegisterList(const MachineInstr *MI, int OpNum,
17835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                           raw_ostream &O);
179055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    void printCPInstOperand(const MachineInstr *MI, int OpNum,
18035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                            raw_ostream &O,
181a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                            const char *Modifier);
18235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printJTBlockOperand(const MachineInstr *MI, int OpNum,
18335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                             raw_ostream &O);
18435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printJT2BlockOperand(const MachineInstr *MI, int OpNum,
18535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                              raw_ostream &O);
18635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printTBAddrMode(const MachineInstr *MI, int OpNum,
18735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                         raw_ostream &O);
18835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printNoHashImmediate(const MachineInstr *MI, int OpNum,
18935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                              raw_ostream &O);
19035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printVFPf32ImmOperand(const MachineInstr *MI, int OpNum,
19135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
19235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printVFPf64ImmOperand(const MachineInstr *MI, int OpNum,
19335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
1941a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson    void printNEONModImmOperand(const MachineInstr *MI, int OpNum,
1951a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson                                raw_ostream &O);
19654c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson
197055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
198c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                 unsigned AsmVariant, const char *ExtraCode,
199c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                 raw_ostream &O);
200055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
201224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson                                       unsigned AsmVariant,
202c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                       const char *ExtraCode, raw_ostream &O);
2037bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
20435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen
205d95148f073c31924f275a34296da52a7cdefad91Chris Lattner    static const char *getRegisterName(unsigned RegNo);
20605af2616d0df19638e799d3e7afadea26d96a4baChris Lattner
207a786ceac5c888761d83d84d35eb16150be57cc6eChris Lattner    virtual void EmitInstruction(const MachineInstr *MI);
2087bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    bool runOnMachineFunction(MachineFunction &F);
209b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
210a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattner    virtual void EmitConstantPool() {} // we emit constant pools customly!
211953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner    virtual void EmitFunctionEntryLabel();
212812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson    void EmitStartOfAsmFile(Module &M);
2134a071d667d995b00e7853243ff9c7c1269324478Chris Lattner    void EmitEndOfAsmFile(Module &M);
214a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
21559135f49e1699daec9a43fc2d15715d55b910f54Devang Patel    MachineLocation getDebugValueLocation(const MachineInstr *MI) const {
21659135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      MachineLocation Location;
21759135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      assert (MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
21859135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      // Frame address.  Currently handles register +- offset only.
21959135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm())
22059135f49e1699daec9a43fc2d15715d55b910f54Devang Patel        Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
22159135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      else {
22259135f49e1699daec9a43fc2d15715d55b910f54Devang Patel        DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
22359135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      }
22459135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      return Location;
22559135f49e1699daec9a43fc2d15715d55b910f54Devang Patel    }
22659135f49e1699daec9a43fc2d15715d55b910f54Devang Patel
227917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    virtual unsigned getISAEncoding() {
228917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      // ARM/Darwin adds ISA to the DWARF info for each function.
229917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      if (!Subtarget->isTargetDarwin())
230917290043f87b8efa6ba540bec5963013c517912Jim Grosbach        return 0;
231917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      return Subtarget->isThumb() ?
232917290043f87b8efa6ba540bec5963013c517912Jim Grosbach        llvm::ARM::DW_ISA_ARM_thumb : llvm::ARM::DW_ISA_ARM_arm;
233917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    }
234917290043f87b8efa6ba540bec5963013c517912Jim Grosbach
2350890cf124f00da3dc943c1882f4221955e0281edChris Lattner    MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
2360890cf124f00da3dc943c1882f4221955e0281edChris Lattner                                          const MachineBasicBlock *MBB) const;
2370890cf124f00da3dc943c1882f4221955e0281edChris Lattner    MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const;
238bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner
239711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    /// EmitMachineConstantPoolValue - Print a machine constantpool value to
240711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    /// the .s file.
241a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
2429d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      SmallString<128> Str;
2439d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      raw_svector_ostream OS(Str);
2449d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      EmitMachineConstantPoolValue(MCPV, OS);
2459d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText(OS.str());
2469d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    }
247b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
2489d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV,
2499d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                                      raw_ostream &O) {
250ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      switch (TM.getTargetData()->getTypeAllocSize(MCPV->getType())) {
251ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      case 1: O << MAI->getData8bitsDirective(0); break;
252ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      case 2: O << MAI->getData16bitsDirective(0); break;
253ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      case 4: O << MAI->getData32bitsDirective(0); break;
254ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      default: assert(0 && "Unknown CPV size");
255ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      }
256a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
257711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng      ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
2583fb2b1ede30193b59a651328a946174196b20610Jim Grosbach
2593fb2b1ede30193b59a651328a946174196b20610Jim Grosbach      if (ACPV->isLSDA()) {
2609d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner        O << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
26128989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      } else if (ACPV->isBlockAddress()) {
2620752cda4de245978e14d806831abba4506272cd0Chris Lattner        O << *GetBlockAddressSymbol(ACPV->getBlockAddress());
26328989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      } else if (ACPV->isGlobalValue()) {
26446510a73e977273ec67747eb34cbdb43f815e451Dan Gohman        const GlobalValue *GV = ACPV->getGV();
265e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        bool isIndirect = Subtarget->isTargetDarwin() &&
26663476a80404125e5196b6c09113c1d4796da0604Evan Cheng          Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
267e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        if (!isIndirect)
268d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner          O << *Mang->getSymbol(GV);
269e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        else {
270e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng          // FIXME: Remove this when Darwin transition to @GOT like syntax.
2717a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner          MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
27210b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner          O << *Sym;
273b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
274b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner          MachineModuleInfoMachO &MMIMachO =
275b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner            MMI->getObjFileInfo<MachineModuleInfoMachO>();
276cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling          MachineModuleInfoImpl::StubValueTy &StubSym =
277b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner            GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(Sym) :
278b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner                                        MMIMachO.getGVStubEntry(Sym);
279cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling          if (StubSym.getPointer() == 0)
280cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling            StubSym = MachineModuleInfoImpl::
281d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner              StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
282e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        }
28328989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      } else {
28428989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson        assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
28510b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner        O << *GetExternalSymbolSymbol(ACPV->getSymbol());
28628989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      }
287e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
2880ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
28964f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio      if (ACPV->getPCAdjustment() != 0) {
29033adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner        O << "-(" << MAI->getPrivateGlobalPrefix() << "PC"
291e7e0d62efda2445b735052ca45bd74fb002e34c3Evan Cheng          << getFunctionNumber() << "_"  << ACPV->getLabelId()
29264f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio          << "+" << (unsigned)ACPV->getPCAdjustment();
29364f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio         if (ACPV->mustAddCurrentAddress())
29464f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio           O << "-.";
2958b3787586ed92df55131ad38c16646b7eba401a0Chris Lattner         O << ')';
29664f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio      }
297a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
2987bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  };
2997bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace
3007bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
3017bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMGenAsmWriter.inc"
3027bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
303953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattnervoid ARMAsmPrinter::EmitFunctionEntryLabel() {
304953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  if (AFI->isThumbFunction()) {
3059d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.EmitRawText(StringRef("\t.code\t16"));
3060752cda4de245978e14d806831abba4506272cd0Chris Lattner    if (!Subtarget->isTargetDarwin())
3079d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText(StringRef("\t.thumb_func"));
3080752cda4de245978e14d806831abba4506272cd0Chris Lattner    else {
3090752cda4de245978e14d806831abba4506272cd0Chris Lattner      // This needs to emit to a temporary string to get properly quoted
3100752cda4de245978e14d806831abba4506272cd0Chris Lattner      // MCSymbols when they have spaces in them.
3110752cda4de245978e14d806831abba4506272cd0Chris Lattner      SmallString<128> Tmp;
3120752cda4de245978e14d806831abba4506272cd0Chris Lattner      raw_svector_ostream OS(Tmp);
3130752cda4de245978e14d806831abba4506272cd0Chris Lattner      OS << "\t.thumb_func\t" << *CurrentFnSym;
3140752cda4de245978e14d806831abba4506272cd0Chris Lattner      OutStreamer.EmitRawText(OS.str());
3150752cda4de245978e14d806831abba4506272cd0Chris Lattner    }
316953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  }
317b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
318953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  OutStreamer.EmitLabel(CurrentFnSym);
319953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner}
320953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner
321a8e2989ece6dc46df59b0768184028257f913843Evan Cheng/// runOnMachineFunction - This uses the printInstruction()
3227bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction.
3237bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola///
3247bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
325a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  AFI = MF.getInfo<ARMFunctionInfo>();
3266d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng  MCP = MF.getConstantPool();
327a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
328d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner  return AsmPrinter::runOnMachineFunction(MF);
32932bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola}
33032bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola
331055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
33235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                 raw_ostream &O, const char *Modifier) {
333055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
3345cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov  unsigned TF = MO.getTargetFlags();
3355cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov
3362f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  switch (MO.getType()) {
3378bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner  default:
3388bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(0 && "<unknown operand type>");
3395bafff36c798608a189c517d37527e4a38863071Bob Wilson  case MachineOperand::MO_Register: {
3405bafff36c798608a189c517d37527e4a38863071Bob Wilson    unsigned Reg = MO.getReg();
3418bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(TargetRegisterInfo::isPhysicalRegister(Reg));
342de0ae8f83dd8eabc831b0631c20ffa3b53a774f2Bob Wilson    if (Modifier && strcmp(Modifier, "lane") == 0) {
343a4c3c8f28d9465dc7c42eb43c2377530f1821574Jim Grosbach      unsigned RegNum = getARMRegisterNumbering(Reg);
3449d1c1ada213c80135fbdda704175aae689daa6f9Chris Lattner      unsigned DReg =
345e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen        TM.getRegisterInfo()->getMatchingSuperReg(Reg,
346e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen          RegNum & 1 ? ARM::ssub_1 : ARM::ssub_0, &ARM::DPR_VFP2RegClass);
3478bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner      O << getRegisterName(DReg) << '[' << (RegNum & 1) << ']';
3488bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    } else {
349e8ea011cc766b37a957d5966655526096bf49feaAnton Korobeynikov      assert(!MO.getSubReg() && "Subregs should be eliminated!");
3508bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner      O << getRegisterName(Reg);
3518bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    }
3522f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
3535bafff36c798608a189c517d37527e4a38863071Bob Wilson  }
354a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_Immediate: {
3555adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng    int64_t Imm = MO.getImm();
356632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << '#';
3575cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
3585cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov        (TF & ARMII::MO_LO16))
3595cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
3605cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
3615cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov             (TF & ARMII::MO_HI16))
3625cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
363632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << Imm;
3642f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
365a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
3662f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_MachineBasicBlock:
3671b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner    O << *MO.getMBB()->getSymbol();
3682f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    return;
36984b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola  case MachineOperand::MO_GlobalAddress: {
370a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    bool isCallOp = Modifier && !strcmp(Modifier, "call");
37146510a73e977273ec67747eb34cbdb43f815e451Dan Gohman    const GlobalValue *GV = MO.getGlobal();
3725cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov
3735cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
3745cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov        (TF & ARMII::MO_LO16))
3755cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
3765cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
3775cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov             (TF & ARMII::MO_HI16))
3785cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
379d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner    O << *Mang->getSymbol(GV);
3807751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
3810c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner    printOffset(MO.getOffset(), O);
3827751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
3830ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio    if (isCallOp && Subtarget->isTargetELF() &&
3840ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio        TM.getRelocationModel() == Reloc::PIC_)
3850ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
3862f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
387a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
388a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_ExternalSymbol: {
389a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    bool isCallOp = Modifier && !strcmp(Modifier, "call");
39010b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner    O << *GetExternalSymbolSymbol(MO.getSymbolName());
391b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
3920ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio    if (isCallOp && Subtarget->isTargetELF() &&
3930ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio        TM.getRelocationModel() == Reloc::PIC_)
3940ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
3952f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
396a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
3972f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_ConstantPoolIndex:
3981b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetCPISymbol(MO.getIndex());
3992f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
400a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_JumpTableIndex:
4011b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetJTISymbol(MO.getIndex());
402a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    break;
4032f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  }
4047bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
4057bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
40635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnerstatic void printSOImm(raw_ostream &O, int64_t V, bool VerboseAsm,
40733adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner                       const MCAsmInfo *MAI) {
408e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng  // Break it up into two parts that make up a shifter immediate.
409e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng  V = ARM_AM::getSOImmVal(V);
410e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng  assert(V != -1 && "Not a valid so_imm value!");
411e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng
412c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  unsigned Imm = ARM_AM::getSOImmValImm(V);
413c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  unsigned Rot = ARM_AM::getSOImmValRot(V);
4147751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
415a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Print low-level immediate formation info, per
416a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // A5.1.3: "Data-processing operands - Immediate".
417a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Rot) {
418a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "#" << Imm << ", " << Rot;
419a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Pretty printed version.
42039382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng    if (VerboseAsm) {
42135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      O << "\t" << MAI->getCommentString() << ' ';
42239382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng      O << (int)ARM_AM::rotr32(Imm, Rot);
42339382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng    }
424a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
425a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "#" << Imm;
426a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
427a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
428a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
429c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
430c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// immediate in bits 0-7.
43135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum,
43235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O) {
433c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
434d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  assert(MO.isImm() && "Not a valid so_imm value!");
4353f53c8398d81065736a784469c9dd5afff85673fChris Lattner  printSOImm(O, MO.getImm(), isVerbose(), MAI);
436c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng}
437c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng
4389092213a5e50d4991f900d2df009d27bddfd9941Evan Cheng/// printSOImm2PartOperand - SOImm is broken into two pieces using a 'mov'
4399092213a5e50d4991f900d2df009d27bddfd9941Evan Cheng/// followed by an 'orr' to materialize.
44035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum,
44135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
442c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
443d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  assert(MO.isImm() && "Not a valid so_imm value!");
4449a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner  unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImm());
4459a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner  unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImm());
4463f53c8398d81065736a784469c9dd5afff85673fChris Lattner  printSOImm(O, V1, isVerbose(), MAI);
4475e148a37d3432f83ccc4dbebe08d4f1b4717034cEvan Cheng  O << "\n\torr";
44835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printPredicateOperand(MI, 2, O);
449162e30921da0ce1863672d4ca5fef541498fe6beEvan Cheng  O << "\t";
45035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, 0, O);
451c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  O << ", ";
45235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, 0, O);
453c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  O << ", ";
4543f53c8398d81065736a784469c9dd5afff85673fChris Lattner  printSOImm(O, V2, isVerbose(), MAI);
455c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng}
456c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng
457a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// so_reg is a 4-operand unit corresponding to register forms of the A5.1
458a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// "Addressing Mode 1 - Data-processing operands" forms.  This includes:
4599cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng//    REG 0   0           - e.g. R5
4609cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng//    REG REG 0,SH_OPC    - e.g. R5, ROR R3
461a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
46235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op,
46335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O) {
464a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
465a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
466a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
467a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
468762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << getRegisterName(MO1.getReg());
469a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
470a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Print the shift opc.
4711d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm());
4721d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
473a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (MO2.getReg()) {
4741d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson    O << ' ' << getRegisterName(MO2.getReg());
475a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
4761d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  } else if (ShOpc != ARM_AM::rrx) {
4771d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson    O << " #" << ARM_AM::getSORegOffset(MO3.getImm());
478a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
479a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
480a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
48135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op,
48235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
483a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
484a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
485a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
486a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
487d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
48835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, Op, O);
489a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
490a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
491a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
492762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
493a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
494a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!MO2.getReg()) {
4959e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0.
496a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << ", #"
4979e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen        << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
498a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        << ARM_AM::getAM2Offset(MO3.getImm());
499a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "]";
500a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
501a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
502a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
503a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << ", "
5049e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
505762ccea600158bb317dcccdff3303e942426cb71Chris Lattner    << getRegisterName(MO2.getReg());
506e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
507a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
508a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", "
5099a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
510a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << " #" << ShImm;
511a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
512a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
513a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
51435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op,
51535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O) {
516a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
517a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
518a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
519a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!MO1.getReg()) {
520bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng    unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
521bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng    O << "#"
5229e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen      << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
523bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng      << ImmOffs;
524a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
525a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
526a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
5279e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen  O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
528762ccea600158bb317dcccdff3303e942426cb71Chris Lattner    << getRegisterName(MO1.getReg());
529e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
530a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
531a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", "
5329a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm()))
533a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << " #" << ShImm;
534a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
535a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
53635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op,
53735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
538a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
539a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
540a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
541e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
5426f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
543762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
544a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
545a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (MO2.getReg()) {
546a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", "
547a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << (char)ARM_AM::getAM3Op(MO3.getImm())
548762ccea600158bb317dcccdff3303e942426cb71Chris Lattner      << getRegisterName(MO2.getReg())
549a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << "]";
550a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
551a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
552e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
553a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
554a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", #"
5559e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen      << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()))
556a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << ImmOffs;
557a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
558a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
559a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
56035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op,
56135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O){
562a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
563a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
564a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
565a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (MO1.getReg()) {
566a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << (char)ARM_AM::getAM3Op(MO2.getImm())
567762ccea600158bb317dcccdff3303e942426cb71Chris Lattner      << getRegisterName(MO1.getReg());
568a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
569a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
570a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
571a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
572a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "#"
5739e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()))
574a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    << ImmOffs;
575a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
576e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
577a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
57835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O,
579a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                          const char *Modifier) {
580a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
581a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
582a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Modifier && strcmp(Modifier, "submode") == 0) {
583ea7f22c31d0d12923eaab6840322431cc0222ae9Bob Wilson    O << ARM_AM::getAMSubModeStr(Mode);
584d77c7aba83bb290b9b62ede38b6ddbc9b790c6efEvan Cheng  } else if (Modifier && strcmp(Modifier, "wide") == 0) {
585d77c7aba83bb290b9b62ede38b6ddbc9b790c6efEvan Cheng    ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
586d77c7aba83bb290b9b62ede38b6ddbc9b790c6efEvan Cheng    if (Mode == ARM_AM::ia)
587d77c7aba83bb290b9b62ede38b6ddbc9b790c6efEvan Cheng      O << ".w";
588a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
58935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, Op, O);
590a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
591a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
592a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
593a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
59435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O,
595a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                          const char *Modifier) {
596a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
597a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
598a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
599d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
60035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, Op, O);
601a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
602a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
603e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
6046f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
605a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
606762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
607e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
608a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
609a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", #"
6109e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen      << ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2.getImm()))
611a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << ImmOffs*4;
612a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
613a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
614a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
615a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
61635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode6Operand(const MachineInstr *MI, int Op,
61735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
6188b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson  const MachineOperand &MO1 = MI->getOperand(Op);
6198b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson  const MachineOperand &MO2 = MI->getOperand(Op+1);
6208b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson
6218a5ec86a3d4d599984e52c0c5a3a6a436607cf3eJim Grosbach  O << "[" << getRegisterName(MO1.getReg());
622226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson  if (MO2.getImm()) {
623bce3dbd9be29a42f32eb888086050cd620f2133bAnton Korobeynikov    // FIXME: Both darwin as and GNU as violate ARM docs here.
624273ff31e134d48c8247e981d30e214e82568ff86Bob Wilson    O << ", :" << (MO2.getImm() << 3);
6258a5ec86a3d4d599984e52c0c5a3a6a436607cf3eJim Grosbach  }
6268a5ec86a3d4d599984e52c0c5a3a6a436607cf3eJim Grosbach  O << "]";
627226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson}
628a43e6bf69093b9870548e7d782ea148e2ddd6449Bob Wilson
62935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode6OffsetOperand(const MachineInstr *MI, int Op,
63035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O){
631226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson  const MachineOperand &MO = MI->getOperand(Op);
632226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson  if (MO.getReg() == 0)
633226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson    O << "!";
634226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson  else
635226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson    O << ", " << getRegisterName(MO.getReg());
6368b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson}
6378b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson
638a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
63935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O,
640a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                           const char *Modifier) {
641a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Modifier && strcmp(Modifier, "label") == 0) {
64235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printPCLabel(MI, Op+1, O);
643a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
644a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
645a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
646a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
6476f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
6489e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen  O << "[pc, " << getRegisterName(MO1.getReg()) << "]";
649a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
650a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
651a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
65235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printBitfieldInvMaskImmOperand(const MachineInstr *MI, int Op,
65335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                              raw_ostream &O) {
654f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng  const MachineOperand &MO = MI->getOperand(Op);
655f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng  uint32_t v = ~MO.getImm();
6569e03cbefc5b3b8772a18d9bd25593ce62137ac85Evan Cheng  int32_t lsb = CountTrailingZeros_32(v);
657b825aaa0289206a63f7e6ce7b5ca7c2d6a2c063eNick Lewycky  int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb;
658f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng  assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
659f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng  O << "#" << lsb << ", #" << width;
660f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng}
661f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng
6621adc40cac314b0a77b790b094bca146a3a868452Johnny Chenvoid
6631adc40cac314b0a77b790b094bca146a3a868452Johnny ChenARMAsmPrinter::printMemBOption(const MachineInstr *MI, int OpNum,
6641adc40cac314b0a77b790b094bca146a3a868452Johnny Chen                               raw_ostream &O) {
6651adc40cac314b0a77b790b094bca146a3a868452Johnny Chen  unsigned val = MI->getOperand(OpNum).getImm();
6661adc40cac314b0a77b790b094bca146a3a868452Johnny Chen  O << ARM_MB::MemBOptToString(val);
6671adc40cac314b0a77b790b094bca146a3a868452Johnny Chen}
6681adc40cac314b0a77b790b094bca146a3a868452Johnny Chen
66922f5dc79c05d69391b17e14ed912aa8e98a63027Bob Wilsonvoid ARMAsmPrinter::printShiftImmOperand(const MachineInstr *MI, int OpNum,
670eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson                                         raw_ostream &O) {
671eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  unsigned ShiftOp = MI->getOperand(OpNum).getImm();
672eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  ARM_AM::ShiftOpc Opc = ARM_AM::getSORegShOp(ShiftOp);
673eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  switch (Opc) {
674eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  case ARM_AM::no_shift:
675eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    return;
676eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  case ARM_AM::lsl:
677eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    O << ", lsl #";
678eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    break;
679eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  case ARM_AM::asr:
680eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    O << ", asr #";
681eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    break;
682eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  default:
68322f5dc79c05d69391b17e14ed912aa8e98a63027Bob Wilson    assert(0 && "unexpected shift opcode for shift immediate operand");
684eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  }
685eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  O << ARM_AM::getSORegOffset(ShiftOp);
686eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson}
687eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson
688055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===//
689055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
69035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printThumbS4ImmOperand(const MachineInstr *MI, int Op,
69135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
6922ef9c8a43d1030bf65cafedf4b4b3f04d30180ceEvan Cheng  O << "#" <<  MI->getOperand(Op).getImm() * 4;
6932ef9c8a43d1030bf65cafedf4b4b3f04d30180ceEvan Cheng}
6942ef9c8a43d1030bf65cafedf4b4b3f04d30180ceEvan Cheng
695f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Chengvoid
69635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbITMask(const MachineInstr *MI, int Op,
69735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                raw_ostream &O) {
698e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  // (3 - the number of trailing zeros) is the number of then / else.
699e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  unsigned Mask = MI->getOperand(Op).getImm();
7009e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen  unsigned CondBit0 = Mask >> 4 & 1;
701e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  unsigned NumTZ = CountTrailingZeros_32(Mask);
702e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  assert(NumTZ <= 3 && "Invalid IT mask!");
70306e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
7049e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    bool T = ((Mask >> Pos) & 1) == CondBit0;
705e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng    if (T)
706e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng      O << 't';
707e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng    else
708e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng      O << 'e';
709e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  }
710e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng}
711e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng
712e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Chengvoid
71335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op,
71435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
715a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
716a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
717762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
718762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << ", " << getRegisterName(MO2.getReg()) << "]";
719a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
720a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
721a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
722a8e2989ece6dc46df59b0768184028257f913843Evan ChengARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
72335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                            raw_ostream &O,
724a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                            unsigned Scale) {
725a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
726cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
727cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
728a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
729d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
73035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, Op, O);
731a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
732a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
733a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
734762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
735cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  if (MO3.getReg())
736762ccea600158bb317dcccdff3303e942426cb71Chris Lattner    O << ", " << getRegisterName(MO3.getReg());
7374b6bbe1e9c40fb58eccaf3671432661016663aabEvan Cheng  else if (unsigned ImmOffs = MO2.getImm())
7389e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << ImmOffs * Scale;
739a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
740a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
741a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
742a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
74335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op,
74435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
74535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printThumbAddrModeRI5Operand(MI, Op, O, 1);
746a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
747a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
74835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op,
74935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
75035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printThumbAddrModeRI5Operand(MI, Op, O, 2);
751a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
752a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
75335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op,
75435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
75535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printThumbAddrModeRI5Operand(MI, Op, O, 4);
756a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
757a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
75835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op,
75935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O) {
760a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
761a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
762762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
763a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ImmOffs = MO2.getImm())
7649e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << ImmOffs*4;
765a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
7667bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
7677bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
768055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===//
769055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
7709cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
7719cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng// register with shift forms.
7729cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng// REG 0   0           - e.g. R5
7739cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng// REG IMM, SH_OPC     - e.g. R5, LSL #3
77435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printT2SOOperand(const MachineInstr *MI, int OpNum,
77535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O) {
7769cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
7779cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
7789cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng
7799cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  unsigned Reg = MO1.getReg();
7809cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  assert(TargetRegisterInfo::isPhysicalRegister(Reg));
781762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << getRegisterName(Reg);
7829cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng
7839cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  // Print the shift opc.
7849cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  assert(MO2.isImm() && "Not a valid t2_so_reg value!");
7851d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO2.getImm());
7861d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
7871d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  if (ShOpc != ARM_AM::rrx)
7881d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson    O << " #" << ARM_AM::getSORegOffset(MO2.getImm());
7899cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng}
7909cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng
791055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printT2AddrModeImm12Operand(const MachineInstr *MI,
79235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                int OpNum,
79335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O) {
794055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
795055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
796055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
797762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
798055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
799055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  unsigned OffImm = MO2.getImm();
800055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  if (OffImm)  // Don't print +0.
8019e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << OffImm;
802055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  O << "]";
803055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng}
804055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
805055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printT2AddrModeImm8Operand(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  int32_t OffImm = (int32_t)MO2.getImm();
814055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  // Don't print +0.
815055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  if (OffImm < 0)
816055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    O << ", #-" << -OffImm;
817055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  else if (OffImm > 0)
8189e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << OffImm;
819055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  O << "]";
820055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng}
821055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
8225c874172ac8fd563867efc54022ac4c1571e1313Evan Chengvoid ARMAsmPrinter::printT2AddrModeImm8s4Operand(const MachineInstr *MI,
82335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                 int OpNum,
82435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                 raw_ostream &O) {
8255c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
8265c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
8275c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng
828762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
8295c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng
8305c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  int32_t OffImm = (int32_t)MO2.getImm() / 4;
8315c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  // Don't print +0.
8325c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  if (OffImm < 0)
833a64ce4591762b93030cd2a2ff202bbd5badfecddEvan Cheng    O << ", #-" << -OffImm * 4;
8345c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  else if (OffImm > 0)
8359e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << OffImm * 4;
8365c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  O << "]";
8375c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng}
8385c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng
839e88d5cee9d6b02bc786df806395a718464908064Evan Chengvoid ARMAsmPrinter::printT2AddrModeImm8OffsetOperand(const MachineInstr *MI,
84035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                     int OpNum,
84135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                     raw_ostream &O) {
842e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
843e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  int32_t OffImm = (int32_t)MO1.getImm();
844e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  // Don't print +0.
845e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  if (OffImm < 0)
846e88d5cee9d6b02bc786df806395a718464908064Evan Cheng    O << "#-" << -OffImm;
847e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  else if (OffImm > 0)
8489e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << "#" << OffImm;
8499e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen}
8509e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen
851055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printT2AddrModeSoRegOperand(const MachineInstr *MI,
85235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                int OpNum,
85335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O) {
854055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
855055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
856055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO3 = MI->getOperand(OpNum+2);
857055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
858762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
859055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
8603a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng  assert(MO2.getReg() && "Invalid so_reg load / store address!");
861762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << ", " << getRegisterName(MO2.getReg());
8629cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng
8633a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng  unsigned ShAmt = MO3.getImm();
8643a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng  if (ShAmt) {
8653a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng    assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
8663a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng    O << ", lsl #" << ShAmt;
867055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  }
868055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  O << "]";
869055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng}
870055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
871055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
872055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===//
873055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
87435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printPredicateOperand(const MachineInstr *MI, int OpNum,
87535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
876055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
87744bec52b1b7e9a3ac1efbae90db240b8c1ca2ad4Evan Cheng  if (CC != ARMCC::AL)
87844bec52b1b7e9a3ac1efbae90db240b8c1ca2ad4Evan Cheng    O << ARMCondCodeToString(CC);
8797bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
8807bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
8819d3acaa1a015c4499595eaff529686a517c14e15Johnny Chenvoid ARMAsmPrinter::printMandatoryPredicateOperand(const MachineInstr *MI,
88235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                   int OpNum,
88335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                   raw_ostream &O) {
8849d3acaa1a015c4499595eaff529686a517c14e15Johnny Chen  ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
8859d3acaa1a015c4499595eaff529686a517c14e15Johnny Chen  O << ARMCondCodeToString(CC);
8869d3acaa1a015c4499595eaff529686a517c14e15Johnny Chen}
8879d3acaa1a015c4499595eaff529686a517c14e15Johnny Chen
88835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printSBitModifierOperand(const MachineInstr *MI, int OpNum,
88935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                             raw_ostream &O){
890055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  unsigned Reg = MI->getOperand(OpNum).getReg();
891dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng  if (Reg) {
892dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng    assert(Reg == ARM::CPSR && "Expect ARM CPSR register!");
893dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng    O << 's';
894dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng  }
895dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng}
896dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng
89735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int OpNum,
89835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                 raw_ostream &O) {
899055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  int Id = (int)MI->getOperand(OpNum).getImm();
900e7e0d62efda2445b735052ca45bd74fb002e34c3Evan Cheng  O << MAI->getPrivateGlobalPrefix()
901e7e0d62efda2445b735052ca45bd74fb002e34c3Evan Cheng    << "PC" << getFunctionNumber() << "_" << Id;
902a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
903a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
90435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int OpNum,
90535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O) {
906a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "{";
907815baebe1c8dc02accf128ae10dff9a1742d3244Bob Wilson  for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
9084b322e58b77d16f103d88a3af3a4ebd2675245a0Evan Cheng    if (MI->getOperand(i).isImplicit())
9094b322e58b77d16f103d88a3af3a4ebd2675245a0Evan Cheng      continue;
910815baebe1c8dc02accf128ae10dff9a1742d3244Bob Wilson    if ((int)i != OpNum) O << ", ";
91135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, i, O);
912a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
913a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "}";
914a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
915a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
916055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNum,
91735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                       raw_ostream &O, const char *Modifier) {
918a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  assert(Modifier && "This operand only works with a modifier!");
919a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
920a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // data itself.
921a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!strcmp(Modifier, "label")) {
922055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    unsigned ID = MI->getOperand(OpNum).getImm();
9238e089a9e4d6b7aa2b3968c38644f926f60a7c670Chris Lattner    OutStreamer.EmitLabel(GetCPISymbol(ID));
924a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
925a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
926055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    unsigned CPI = MI->getOperand(OpNum).getIndex();
927a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
9286d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI];
929e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
930711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    if (MCPE.isMachineConstantPoolEntry()) {
931a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
932711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    } else {
933a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      EmitGlobalConstant(MCPE.Val.ConstVal);
934305b8a5f62c9d027f3d8a870fc12fc2abf69aeeaLauro Ramos Venancio    }
935a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
936a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
937a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
9380890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
9390890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
9400890cf124f00da3dc943c1882f4221955e0281edChris Lattner                            const MachineBasicBlock *MBB) const {
9410890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
9420890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
943bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2
9440890cf124f00da3dc943c1882f4221955e0281edChris Lattner    << "_set_" << MBB->getNumber();
9459b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
9460890cf124f00da3dc943c1882f4221955e0281edChris Lattner}
9470890cf124f00da3dc943c1882f4221955e0281edChris Lattner
9480890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
9490890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
9500890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
9510890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
952281e7767df71b3f727ade80a16ff0c4fe5a49dd9Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2;
9539b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
954bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner}
955bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner
95635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum,
95735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                        raw_ostream &O) {
95866ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  assert(!Subtarget->isThumb2() && "Thumb2 should use double-jump jumptables!");
95966ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng
960055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
961055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
962b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
9638aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner  unsigned JTI = MO1.getIndex();
9640890cf124f00da3dc943c1882f4221955e0281edChris Lattner  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
96503335350547b5d3521f9912d301bbb799d7eea31Chris Lattner  // Can't use EmitLabel until instprinter happens, label comes out in the wrong
96603335350547b5d3521f9912d301bbb799d7eea31Chris Lattner  // order.
967d4d188e5029801ef2a76ee756dcba49f313004f0Bob Wilson  O << "\n" << *JTISymbol << ":\n";
968a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
96933adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner  const char *JTEntryDirective = MAI->getData32bitsDirective();
970a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
9714542611bb9793e8376d7d5f33b4a1e2d11712894Dan Gohman  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
972a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
973a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
974cee63322eaccc2f1067bdf5eab506e440f867da1Chris Lattner  bool UseSet= MAI->hasSetDirective() && TM.getRelocationModel() == Reloc::PIC_;
975c324ecb7bc93a1f09db29851438ec5ee72b143ebEvan Cheng  SmallPtrSet<MachineBasicBlock*, 8> JTSets;
976a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
977a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    MachineBasicBlock *MBB = JTBBs[i];
97866ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng    bool isNew = JTSets.insert(MBB);
97966ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng
9800890cf124f00da3dc943c1882f4221955e0281edChris Lattner    if (UseSet && isNew) {
981cee63322eaccc2f1067bdf5eab506e440f867da1Chris Lattner      O << "\t.set\t"
9821f9b48ad87a5dab4a6c3805c369414c831e4451dJim Grosbach        << *GetARMSetPICJumpTableLabel2(JTI, MO2.getImm(), MBB) << ','
9831b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner        << *MBB->getSymbol() << '-' << *JTISymbol << '\n';
9840890cf124f00da3dc943c1882f4221955e0281edChris Lattner    }
985a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
986a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << JTEntryDirective << ' ';
987a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (UseSet)
9880890cf124f00da3dc943c1882f4221955e0281edChris Lattner      O << *GetARMSetPICJumpTableLabel2(JTI, MO2.getImm(), MBB);
9890890cf124f00da3dc943c1882f4221955e0281edChris Lattner    else if (TM.getRelocationModel() == Reloc::PIC_)
9901b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner      O << *MBB->getSymbol() << '-' << *JTISymbol;
9910890cf124f00da3dc943c1882f4221955e0281edChris Lattner    else
9921b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner      O << *MBB->getSymbol();
9930890cf124f00da3dc943c1882f4221955e0281edChris Lattner
994d85ac4d07966a56b3101598f29393f4532acc50fEvan Cheng    if (i != e-1)
995d85ac4d07966a56b3101598f29393f4532acc50fEvan Cheng      O << '\n';
996a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
997a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
998a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
99935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printJT2BlockOperand(const MachineInstr *MI, int OpNum,
100035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                         raw_ostream &O) {
100166ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
100266ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
100366ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  unsigned JTI = MO1.getIndex();
1004b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
10050890cf124f00da3dc943c1882f4221955e0281edChris Lattner  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
1006b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
100703335350547b5d3521f9912d301bbb799d7eea31Chris Lattner  // Can't use EmitLabel until instprinter happens, label comes out in the wrong
100803335350547b5d3521f9912d301bbb799d7eea31Chris Lattner  // order.
1009d4d188e5029801ef2a76ee756dcba49f313004f0Bob Wilson  O << "\n" << *JTISymbol << ":\n";
101066ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng
101166ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
101266ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
101366ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
10145657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  bool ByteOffset = false, HalfWordOffset = false;
10155657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  if (MI->getOpcode() == ARM::t2TBB)
10165657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    ByteOffset = true;
10175657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  else if (MI->getOpcode() == ARM::t2TBH)
10185657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    HalfWordOffset = true;
10195657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng
102066ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
102166ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng    MachineBasicBlock *MBB = JTBBs[i];
10225657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    if (ByteOffset)
102333adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner      O << MAI->getData8bitsDirective();
10245657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    else if (HalfWordOffset)
102533adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner      O << MAI->getData16bitsDirective();
1026b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
10270890cf124f00da3dc943c1882f4221955e0281edChris Lattner    if (ByteOffset || HalfWordOffset)
10281b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner      O << '(' << *MBB->getSymbol() << "-" << *JTISymbol << ")/2";
10290890cf124f00da3dc943c1882f4221955e0281edChris Lattner    else
10301b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner      O << "\tb.w " << *MBB->getSymbol();
10310890cf124f00da3dc943c1882f4221955e0281edChris Lattner
103266ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng    if (i != e-1)
103366ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng      O << '\n';
103466ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  }
103566ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng}
103666ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng
103735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printTBAddrMode(const MachineInstr *MI, int OpNum,
103835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                    raw_ostream &O) {
1039762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[pc, " << getRegisterName(MI->getOperand(OpNum).getReg());
10405657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  if (MI->getOpcode() == ARM::t2TBH)
10415657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    O << ", lsl #1";
10425657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  O << ']';
10435657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng}
10445657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng
104535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printNoHashImmediate(const MachineInstr *MI, int OpNum,
104635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                         raw_ostream &O) {
10478e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov  O << MI->getOperand(OpNum).getImm();
10488e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov}
1049a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
105035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printVFPf32ImmOperand(const MachineInstr *MI, int OpNum,
105135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
105239382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng  const ConstantFP *FP = MI->getOperand(OpNum).getFPImm();
105377b02beb1fa3a96efc05081889d1ae4ffecb44a7Jim Grosbach  O << '#' << FP->getValueAPF().convertToFloat();
10543f53c8398d81065736a784469c9dd5afff85673fChris Lattner  if (isVerbose()) {
105535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    O << "\t\t" << MAI->getCommentString() << ' ';
105639382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng    WriteAsOperand(O, FP, /*PrintType=*/false);
105739382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng  }
105839382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng}
105939382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng
106035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printVFPf64ImmOperand(const MachineInstr *MI, int OpNum,
106135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
106239382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng  const ConstantFP *FP = MI->getOperand(OpNum).getFPImm();
106377b02beb1fa3a96efc05081889d1ae4ffecb44a7Jim Grosbach  O << '#' << FP->getValueAPF().convertToDouble();
10643f53c8398d81065736a784469c9dd5afff85673fChris Lattner  if (isVerbose()) {
106535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    O << "\t\t" << MAI->getCommentString() << ' ';
106639382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng    WriteAsOperand(O, FP, /*PrintType=*/false);
106739382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng  }
106839382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng}
106939382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng
10701a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilsonvoid ARMAsmPrinter::printNEONModImmOperand(const MachineInstr *MI, int OpNum,
10711a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson                                           raw_ostream &O) {
10726dce00ced45b5bd1b7f34fe6f2d70c50fc090664Bob Wilson  unsigned EncodedImm = MI->getOperand(OpNum).getImm();
10736dce00ced45b5bd1b7f34fe6f2d70c50fc090664Bob Wilson  unsigned EltBits;
10746dce00ced45b5bd1b7f34fe6f2d70c50fc090664Bob Wilson  uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits);
10751a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson  O << "#0x" << utohexstr(Val);
10761a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson}
10771a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson
1078055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
1079c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    unsigned AsmVariant, const char *ExtraCode,
1080c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    raw_ostream &O) {
1081a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Does this asm operand have a single letter operand modifier?
1082a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (ExtraCode && ExtraCode[0]) {
1083a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ExtraCode[1] != 0) return true; // Unknown modifier.
10848e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov
1085a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    switch (ExtraCode[0]) {
1086a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    default: return true;  // Unknown modifier.
10879b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'a': // Print as a memory address.
10889b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      if (MI->getOperand(OpNum).isReg()) {
1089762ccea600158bb317dcccdff3303e942426cb71Chris Lattner        O << "[" << getRegisterName(MI->getOperand(OpNum).getReg()) << "]";
10909b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson        return false;
10919b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      }
10929b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      // Fallthrough
10939b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'c': // Don't print "#" before an immediate operand.
10944f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson      if (!MI->getOperand(OpNum).isImm())
10954f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson        return true;
109635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      printNoHashImmediate(MI, OpNum, O);
10978f3434647d3d39b49475239e3be1b8afb06415cfBob Wilson      return false;
1098e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng    case 'P': // Print a VFP double precision register.
1099d831cda3e74235704f163d5a18352584d537517aEvan Cheng    case 'q': // Print a NEON quad precision register.
110035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      printOperand(MI, OpNum, O);
110123a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng      return false;
1102a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'Q':
1103a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'R':
1104d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson    case 'H':
110512616727c71721f480f69026d88a58a067d89824Evan Cheng      report_fatal_error("llvm does not support 'Q', 'R', and 'H' modifiers!");
1106d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson      return true;
110784f60b7359e1aa90794bb19de2bbf4d25dc2f01dEvan Cheng    }
1108a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
1109e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
111035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, OpNum, O);
1111a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  return false;
1112a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
1113a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1114224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilsonbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
1115055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng                                          unsigned OpNum, unsigned AsmVariant,
1116c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          const char *ExtraCode,
1117c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          raw_ostream &O) {
1118224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  if (ExtraCode && ExtraCode[0])
1119224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson    return true; // Unknown modifier.
1120765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson
1121765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  const MachineOperand &MO = MI->getOperand(OpNum);
1122765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  assert(MO.isReg() && "unexpected inline asm memory operand");
1123765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  O << "[" << getRegisterName(MO.getReg()) << "]";
1124224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  return false;
1125224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson}
1126224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson
1127a786ceac5c888761d83d84d35eb16150be57cc6eChris Lattnervoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
112897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  if (EnableMCInst) {
112997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner    printInstructionThroughMCStreamer(MI);
11307ad07c46362500f7291a92742569e94fd3538dfdChris Lattner    return;
113197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  }
1132b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
11337ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  if (MI->getOpcode() == ARM::CONSTPOOL_ENTRY)
11347ad07c46362500f7291a92742569e94fd3538dfdChris Lattner    EmitAlignment(2);
1135b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
11367ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  SmallString<128> Str;
11377ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  raw_svector_ostream OS(Str);
11383f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen  if (MI->getOpcode() == ARM::DBG_VALUE) {
11393f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    unsigned NOps = MI->getNumOperands();
11403f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    assert(NOps==4);
11413f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
11423f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    // cast away const; DIetc do not take const operands for some reason.
11433f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
11443f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << V.getName();
11453f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << " <- ";
11463f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    // Frame address.  Currently handles register +- offset only.
11473f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
11483f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS);
11493f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << ']';
11503f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << "+";
11513f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    printOperand(MI, NOps-2, OS);
1152e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  } else if (MI->getOpcode() == ARM::MOVs) {
1153e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    // FIXME: Thumb variants?
1154e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    const MachineOperand &Dst = MI->getOperand(0);
1155e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    const MachineOperand &MO1 = MI->getOperand(1);
1156e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    const MachineOperand &MO2 = MI->getOperand(2);
1157e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    const MachineOperand &MO3 = MI->getOperand(3);
1158e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach
1159e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    OS << '\t' << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()));
1160e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    printSBitModifierOperand(MI, 6, OS);
1161e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    printPredicateOperand(MI, 4, OS);
1162e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach
1163e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    OS << '\t' << getRegisterName(Dst.getReg())
1164e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach       << ", " << getRegisterName(MO1.getReg());
1165e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach
1166e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    if (ARM_AM::getSORegShOp(MO3.getImm()) != ARM_AM::rrx) {
1167e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach      OS << ", ";
1168e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach
1169e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach      if (MO2.getReg()) {
1170e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach        OS << getRegisterName(MO2.getReg());
1171e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach        assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
1172e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach      } else {
1173e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach        OS << "#" << ARM_AM::getSORegOffset(MO3.getImm());
1174e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach      }
1175e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    }
1176e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  } else
1177e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  // A8.6.123 PUSH
1178e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  if ((MI->getOpcode() == ARM::STM_UPD || MI->getOpcode() == ARM::t2STM_UPD) &&
1179532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach      MI->getOperand(0).getReg() == ARM::SP &&
1180532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach      ARM_AM::getAM4SubMode(MI->getOperand(2).getImm()) == ARM_AM::db) {
1181532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    OS << '\t' << "push";
1182532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    printPredicateOperand(MI, 3, OS);
1183532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    OS << '\t';
1184532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    printRegisterList(MI, 5, OS);
1185e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  } else
1186e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  // A8.6.122 POP
1187e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  if ((MI->getOpcode() == ARM::LDM_UPD || MI->getOpcode() == ARM::t2LDM_UPD) &&
1188532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach      MI->getOperand(0).getReg() == ARM::SP &&
1189532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach      ARM_AM::getAM4SubMode(MI->getOperand(2).getImm()) == ARM_AM::ia) {
1190532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    OS << '\t' << "pop";
1191532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    printPredicateOperand(MI, 3, OS);
1192532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    OS << '\t';
1193532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    printRegisterList(MI, 5, OS);
1194e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  } else
1195e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  // A8.6.355 VPUSH
1196e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  if ((MI->getOpcode() == ARM::VSTMS_UPD || MI->getOpcode() ==ARM::VSTMD_UPD) &&
1197532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach      MI->getOperand(0).getReg() == ARM::SP &&
1198532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach      ARM_AM::getAM4SubMode(MI->getOperand(2).getImm()) == ARM_AM::db) {
1199532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    OS << '\t' << "vpush";
1200532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    printPredicateOperand(MI, 3, OS);
1201532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    OS << '\t';
1202532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    printRegisterList(MI, 5, OS);
1203e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  } else
1204e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  // A8.6.354 VPOP
1205e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  if ((MI->getOpcode() == ARM::VLDMS_UPD || MI->getOpcode() ==ARM::VLDMD_UPD) &&
1206532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach      MI->getOperand(0).getReg() == ARM::SP &&
1207532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach      ARM_AM::getAM4SubMode(MI->getOperand(2).getImm()) == ARM_AM::ia) {
1208532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    OS << '\t' << "vpop";
1209532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    printPredicateOperand(MI, 3, OS);
1210532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    OS << '\t';
1211532baa5d537e6cbfd0642f6f4f10ad9f8571fa85Jim Grosbach    printRegisterList(MI, 5, OS);
1212e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  } else
1213e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach    printInstruction(MI, OS);
12143f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen
1215e6be85e9ff6bd28c599421a120a8491257c13ebdJim Grosbach  // Output the instruction to the stream
12167ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  OutStreamer.EmitRawText(OS.str());
1217b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
12187ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  // Make sure the instruction that follows TBB is 2-byte aligned.
12197ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  // FIXME: Constant island pass should insert an "ALIGN" instruction instead.
12207ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  if (MI->getOpcode() == ARM::t2TBB)
12217ad07c46362500f7291a92742569e94fd3538dfdChris Lattner    EmitAlignment(1);
1222a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
1223a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1224812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
12250fb34683b9e33238288d2af1e090582464df8387Bob Wilson  if (Subtarget->isTargetDarwin()) {
12260fb34683b9e33238288d2af1e090582464df8387Bob Wilson    Reloc::Model RelocM = TM.getRelocationModel();
12270fb34683b9e33238288d2af1e090582464df8387Bob Wilson    if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
12280fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // Declare all the text sections up front (before the DWARF sections
12290fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // emitted by AsmPrinter::doInitialization) so the assembler will keep
12300fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // them together at the beginning of the object file.  This helps
12310fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // avoid out-of-range branches that are due a fundamental limitation of
12320fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // the way symbol offsets are encoded with the current Darwin ARM
12330fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // relocations.
1234b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach      const TargetLoweringObjectFileMachO &TLOFMacho =
12350d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman        static_cast<const TargetLoweringObjectFileMachO &>(
12360d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman          getObjFileLowering());
123729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextSection());
123829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
123929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection());
124029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      if (RelocM == Reloc::DynamicNoPIC) {
124129e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
124222772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__symbol_stub4",
124322772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
124422772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     12, SectionKind::getText());
124529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
124629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      } else {
124729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
124822772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__picsymbolstub4",
124922772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
125022772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     16, SectionKind::getText());
125129e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
125229e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      }
125363db594559dc8eac666204c7907bae664f5234daBob Wilson      const MCSection *StaticInitSect =
125463db594559dc8eac666204c7907bae664f5234daBob Wilson        OutContext.getMachOSection("__TEXT", "__StaticInit",
125563db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_REGULAR |
125663db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
125763db594559dc8eac666204c7907bae664f5234daBob Wilson                                   SectionKind::getText());
125863db594559dc8eac666204c7907bae664f5234daBob Wilson      OutStreamer.SwitchSection(StaticInitSect);
12590fb34683b9e33238288d2af1e090582464df8387Bob Wilson    }
12600fb34683b9e33238288d2af1e090582464df8387Bob Wilson  }
12610fb34683b9e33238288d2af1e090582464df8387Bob Wilson
1262e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach  // Use unified assembler syntax.
12639d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  OutStreamer.EmitRawText(StringRef("\t.syntax unified"));
1264d61eca533081580d56fabee38f86507d8019ca75Anton Korobeynikov
126588ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  // Emit ARM Build Attributes
126688ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  if (Subtarget->isTargetELF()) {
126788ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // CPU Type
1268d260c248abd57763aaeeadcab4155655a25d9e97Anton Korobeynikov    std::string CPUString = Subtarget->getCPUString();
1269d260c248abd57763aaeeadcab4155655a25d9e97Anton Korobeynikov    if (CPUString != "generic")
12709d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.cpu " + Twine(CPUString));
127188ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
127288ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // FIXME: Emit FPU type
127388ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    if (Subtarget->hasVFP2())
12749d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12759d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::VFP_arch) + ", 2");
127688ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
127788ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // Signal various FP modes.
12789d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    if (!UnsafeFPMath) {
12799d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12809d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_denormal) + ", 1");
12819d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12829d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_exceptions) + ", 1");
12839d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    }
1284b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
128560108e96bbc5432f4fe06ba313e64448e97a0e15Evan Cheng    if (NoInfsFPMath && NoNaNsFPMath)
12869d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12879d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 1");
128888ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    else
12899d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12909d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 3");
129188ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
129288ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // 8-bytes alignment stuff.
12939d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.EmitRawText("\t.eabi_attribute " +
12949d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                            Twine(ARMBuildAttrs::ABI_align8_needed) + ", 1");
12959d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.EmitRawText("\t.eabi_attribute " +
12969d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                            Twine(ARMBuildAttrs::ABI_align8_preserved) + ", 1");
129788ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
1298567d14f07cd62bfb9dd0edd90144a0a840450f7aAnton Korobeynikov    // Hard float.  Use both S and D registers and conform to AAPCS-VFP.
12999d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) {
13009d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
13019d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_HardFP_use) + ", 3");
13029d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
13039d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_VFP_args) + ", 1");
13049d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    }
130588ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // FIXME: Should we signal R9 usage?
130688ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  }
13077bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
13087bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
13090f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
13104a071d667d995b00e7853243ff9c7c1269324478Chris Lattnervoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
13115be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng  if (Subtarget->isTargetDarwin()) {
1312f61159b574155b056dbd5d6d44f47f753d424056Chris Lattner    // All darwin targets use mach-o.
13130d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman    const TargetLoweringObjectFileMachO &TLOFMacho =
13140d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman      static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
1315b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO &MMIMacho =
1316b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      MMI->getObjFileInfo<MachineModuleInfoMachO>();
1317e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
1318a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Output non-lazy-pointers for external and common global variables.
1319b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
1320cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling
1321b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    if (!Stubs.empty()) {
1322ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner      // Switch with ".non_lazy_symbol_pointer" directive.
13236c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
1324c076a9793936b140364671a5e39ee53bd266c6c3Chris Lattner      EmitAlignment(2);
1325b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1326becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
1327becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
1328becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .indirect_symbol _foo
132952a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
133052a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol);
1331cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
133252a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        if (MCSym.getInt())
1333cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // External to current translation unit.
1334cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
1335cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling        else
1336cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // Internal to current translation unit.
13375e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          //
13385e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          // When we place the LSDA into the TEXT section, the type info pointers
13395e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          // need to be indirect and pc-rel. We accomplish this by using NLPs.
13405e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          // However, sometimes the types are local to the file. So we need to
13415e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          // fill in the value for the NLP in those cases.
134252a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling          OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
134352a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling                                                        OutContext),
1344cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling                                4/*size*/, 0/*addrspace*/);
1345ae94e594164b193236002516970aeec4c4574768Evan Cheng      }
1346becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling
1347becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      Stubs.clear();
1348becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      OutStreamer.AddBlankLine();
1349a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
1350a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1351e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    Stubs = MMIMacho.GetHiddenGVStubList();
1352e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    if (!Stubs.empty()) {
13536c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
1354f3231de60bb64c3f6fc6770b3e6174f4f839a4f3Chris Lattner      EmitAlignment(2);
1355becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1356becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
1357becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
1358becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .long _foo
1359cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling        OutStreamer.EmitValue(MCSymbolRefExpr::
1360cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                              Create(Stubs[i].second.getPointer(),
1361cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                                     OutContext),
1362becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling                              4/*size*/, 0/*addrspace*/);
1363becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      }
1364cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
1365cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      Stubs.clear();
1366cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      OutStreamer.AddBlankLine();
1367ae94e594164b193236002516970aeec4c4574768Evan Cheng    }
1368ae94e594164b193236002516970aeec4c4574768Evan Cheng
1369a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Funny Darwin hack: This flag tells the linker that no global symbols
1370a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // contain code that falls through to other global symbols (e.g. the obvious
1371a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // implementation of multiple entry points).  If this doesn't occur, the
1372a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // linker can safely perform dead code stripping.  Since LLVM never
1373a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // generates code that does this, it is always safe to set.
1374a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner    OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
1375b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola  }
13767bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
13770bd89712c03c59ea43ce37763685e7f7c0bdd977Anton Korobeynikov
137897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===----------------------------------------------------------------------===//
137997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner
1380988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbachstatic MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber,
1381988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                             unsigned LabelId, MCContext &Ctx) {
1382988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach
1383988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach  MCSymbol *Label = Ctx.GetOrCreateSymbol(Twine(Prefix)
1384988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                       + "PC" + Twine(FunctionNumber) + "_" + Twine(LabelId));
1385988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach  return Label;
1386988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach}
1387988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach
1388882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbachvoid ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) {
1389882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  unsigned Opcode = MI->getOpcode();
1390882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1;
1391882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineOperand &MO1 = MI->getOperand(OpNum);
1392882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
1393882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  unsigned JTI = MO1.getIndex();
1394882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
1395882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  // Emit a label for the jump table.
1396882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
1397882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  OutStreamer.EmitLabel(JTISymbol);
1398882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
1399882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  // Emit each entry of the table.
1400882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1401882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1402882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1403882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  bool ByteOffset = false, HalfWordOffset = false;
1404882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  if (MI->getOpcode() == ARM::t2TBB)
1405882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    ByteOffset = true;
1406882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  else if (MI->getOpcode() == ARM::t2TBH)
1407882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    HalfWordOffset = true;
1408882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
1409882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
1410882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MachineBasicBlock *MBB = JTBBs[i];
1411882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // If this isn't a TBB or TBH, the entries are direct branch instructions.
1412882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    if (!ByteOffset && !HalfWordOffset) {
1413882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      MCInst BrInst;
1414882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      BrInst.setOpcode(ARM::t2B);
1415882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      BrInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create(
1416882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach            MBB->getSymbol(), OutContext)));
1417882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      OutStreamer.EmitInstruction(BrInst);
1418882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      continue;
1419882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    }
1420882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // Otherwise it's an offset from the dispatch instruction. Construct an
1421882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // MCExpr for the entry.
1422882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    assert(0 && "FIXME: TB[BH] jump table!!");
1423882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
1424882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach#if 0
1425882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    if (ByteOffset)
1426882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      O << MAI->getData8bitsDirective();
1427882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    else if (HalfWordOffset)
1428882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      O << MAI->getData16bitsDirective();
1429882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
1430882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    if (ByteOffset || HalfWordOffset)
1431882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      O << '(' << *MBB->getSymbol() << "-" << *JTISymbol << ")/2";
1432882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    else
1433882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      O << "\tb.w " << *MBB->getSymbol();
1434882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
1435882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    if (i != e-1)
1436882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach      O << '\n';
1437882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach#endif
1438882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  }
1439882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach}
1440882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
144197f06937449c593a248dbbb1365e6ae408fb9decChris Lattnervoid ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
144296bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner  ARMMCInstLower MCInstLowering(OutContext, *Mang, *this);
144397f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  switch (MI->getOpcode()) {
1444c6b8a9920787505468931e56696cef1245e25913Chris Lattner  case ARM::t2MOVi32imm:
1445c6b8a9920787505468931e56696cef1245e25913Chris Lattner    assert(0 && "Should be lowered by thumb2it pass");
14464d1522234192704f45dfd2527c2913fa60be616eChris Lattner  default: break;
1447fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach  case ARM::tPICADD: {
1448fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // This is a pseudo op for a label + instruction sequence, which looks like:
1449fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // LPC0:
1450fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    //     add r0, pc
1451fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // This adds the address of LPC0 to r0.
1452fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach
1453fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Emit the label.
1454988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1455988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
1456988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
1457fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach
1458fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Form and emit the add.
1459fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    MCInst AddInst;
1460fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.setOpcode(ARM::tADDhirr);
1461fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1462fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1463fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
1464fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    // Add predicate operands.
1465fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
1466fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(0));
1467fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    OutStreamer.EmitInstruction(AddInst);
1468fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach    return;
1469fbd1873041783f388de1c36c5d46c82a9ad46ef3Jim Grosbach  }
14704d1522234192704f45dfd2527c2913fa60be616eChris Lattner  case ARM::PICADD: { // FIXME: Remove asm string from td file.
14714d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This is a pseudo op for a label + instruction sequence, which looks like:
14724d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // LPC0:
14734d1522234192704f45dfd2527c2913fa60be616eChris Lattner    //     add r0, pc, r0
14744d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This adds the address of LPC0 to r0.
1475b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
14764d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // Emit the label.
1477988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1478988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
1479988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
1480b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1481f3f09527e6484143fcdef2ddfef0b2f016881e36Jim Grosbach    // Form and emit the add.
14824d1522234192704f45dfd2527c2913fa60be616eChris Lattner    MCInst AddInst;
14834d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.setOpcode(ARM::ADDrr);
14844d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
14854d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
14864d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
14875b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add predicate operands.
14885b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
14895b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
14905b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add 's' bit operand (always reg0 for this)
14915b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(0));
1492850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner    OutStreamer.EmitInstruction(AddInst);
14934d1522234192704f45dfd2527c2913fa60be616eChris Lattner    return;
1494b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach  }
1495a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTR:
1496a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTRB:
1497a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICSTRH:
1498a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDR:
1499a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRB:
1500a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRH:
1501a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRSB:
1502a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach  case ARM::PICLDRSH: {
1503b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // This is a pseudo op for a label + instruction sequence, which looks like:
1504b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // LPC0:
1505a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    //     OP r0, [pc, r0]
1506b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // The LCP0 label is referenced by a constant pool entry in order to get
1507b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // a PC-relative address at the ldr instruction.
1508b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1509b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Emit the label.
1510988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach    OutStreamer.EmitLabel(getPICLabel(MAI->getPrivateGlobalPrefix(),
1511988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          getFunctionNumber(), MI->getOperand(2).getImm(),
1512988ce097b7774ebc935ea539f3d88c2dcc3405b2Jim Grosbach                          OutContext));
1513b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1514b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Form and emit the load
1515a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    unsigned Opcode;
1516a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    switch (MI->getOpcode()) {
1517a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    default:
1518a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach      llvm_unreachable("Unexpected opcode!");
1519a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICSTR:   Opcode = ARM::STR; break;
1520a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICSTRB:  Opcode = ARM::STRB; break;
1521a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICSTRH:  Opcode = ARM::STRH; break;
1522a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDR:   Opcode = ARM::LDR; break;
1523a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRB:  Opcode = ARM::LDRB; break;
1524a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRH:  Opcode = ARM::LDRH; break;
1525a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRSB: Opcode = ARM::LDRSB; break;
1526a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    case ARM::PICLDRSH: Opcode = ARM::LDRSH; break;
1527a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    }
1528a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    MCInst LdStInst;
1529a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.setOpcode(Opcode);
1530a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1531a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(ARM::PC));
1532a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1533a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateImm(0));
1534b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Add predicate operands.
1535a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
1536a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    LdStInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
1537a28abbe24568d39414be7ccb7a1f659f40e487e2Jim Grosbach    OutStreamer.EmitInstruction(LdStInst);
1538b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1539b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    return;
15404d1522234192704f45dfd2527c2913fa60be616eChris Lattner  }
1541a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner  case ARM::CONSTPOOL_ENTRY: { // FIXME: Remove asm string from td file.
1542a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
1543a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// in the function.  The first operand is the ID# for this instruction, the
1544a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// second is the index into the MachineConstantPool that this is, the third
1545a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// is the size in bytes of this constant pool entry.
1546a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
1547a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned CPIdx   = (unsigned)MI->getOperand(1).getIndex();
1548a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
1549a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    EmitAlignment(2);
15501b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    OutStreamer.EmitLabel(GetCPISymbol(LabelId));
1551a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
1552a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
1553a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    if (MCPE.isMachineConstantPoolEntry())
1554a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
1555a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    else
1556a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitGlobalConstant(MCPE.Val.ConstVal);
1557b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1558a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    return;
1559a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner  }
1560017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner  case ARM::MOVi2pieces: { // FIXME: Remove asmstring from td file.
1561017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    // This is a hack that lowers as a two instruction sequence.
1562017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned DstReg = MI->getOperand(0).getReg();
1563017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
1564017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner
1565017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(ImmVal);
1566017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(ImmVal);
1567b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1568017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    {
1569017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      MCInst TmpInst;
1570017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.setOpcode(ARM::MOVi);
1571017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));
1572017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(SOImmValV1));
1573b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1574017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      // Predicate.
1575017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1576017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1577233917c07282564351439df8e7a9c83c9d6c459eChris Lattner
1578233917c07282564351439df8e7a9c83c9d6c459eChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out
1579850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
1580017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    }
1581017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner
1582017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    {
1583017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      MCInst TmpInst;
1584017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.setOpcode(ARM::ORRri);
1585017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // dstreg
1586017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // inreg
1587017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(SOImmValV2)); // so_imm
1588017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      // Predicate.
1589017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1590017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1591b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1592017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out
1593850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
1594017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    }
1595b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach    return;
1596017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner  }
1597161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner  case ARM::MOVi32imm: { // FIXME: Remove asmstring from td file.
1598161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    // This is a hack that lowers as a two instruction sequence.
1599161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    unsigned DstReg = MI->getOperand(0).getReg();
160018c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    const MachineOperand &MO = MI->getOperand(1);
160118c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    MCOperand V1, V2;
160218c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    if (MO.isImm()) {
160318c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
160418c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V1 = MCOperand::CreateImm(ImmVal & 65535);
160518c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V2 = MCOperand::CreateImm(ImmVal >> 16);
160618c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    } else if (MO.isGlobal()) {
1607c686e33d12f84e1e1f5c96eadef851d078bab043Jim Grosbach      MCSymbol *Symbol = MCInstLowering.GetGlobalAddressSymbol(MO.getGlobal());
160818c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      const MCSymbolRefExpr *SymRef1 =
16093472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        MCSymbolRefExpr::Create(Symbol,
16103472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands                                MCSymbolRefExpr::VK_ARM_LO16, OutContext);
161118c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      const MCSymbolRefExpr *SymRef2 =
16123472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        MCSymbolRefExpr::Create(Symbol,
16133472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands                                MCSymbolRefExpr::VK_ARM_HI16, OutContext);
161418c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V1 = MCOperand::CreateExpr(SymRef1);
161518c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V2 = MCOperand::CreateExpr(SymRef2);
161618c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    } else {
161718c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      MI->dump();
161818c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      llvm_unreachable("cannot handle this operand");
161918c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    }
162018c1021ec108722506125926087b1e5fcfb28046Rafael Espindola
1621161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    {
1622161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      MCInst TmpInst;
1623161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.setOpcode(ARM::MOVi16);
1624161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
162518c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      TmpInst.addOperand(V1); // lower16(imm)
1626b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1627161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      // Predicate.
1628161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1629161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1630b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1631850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
1632161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    }
1633b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1634161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    {
1635161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      MCInst TmpInst;
1636161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.setOpcode(ARM::MOVTi16);
1637161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
1638161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // srcreg
163918c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      TmpInst.addOperand(V2);   // upper16(imm)
1640b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1641161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      // Predicate.
1642161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1643161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1644b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1645850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
1646161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    }
1647b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1648161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    return;
1649161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner  }
1650882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::t2TBB:
1651882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::t2TBH:
1652882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::t2BR_JT: {
1653882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    // Lower and emit the instruction itself, then the jump table following it.
1654882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MCInst TmpInst;
1655882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    MCInstLowering.Lower(MI, TmpInst);
1656882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    OutStreamer.EmitInstruction(TmpInst);
1657882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach
1658882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    EmitJump2Table(MI);
1659882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    return;
1660882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  }
1661882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::tBR_JTr:
1662882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::BR_JTr:
1663882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::BR_JTm:
1664882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach  case ARM::BR_JTadd:
1665882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    abort();
1666882ef2b76a09cdc39d38756fca71cf6cf25ae590Jim Grosbach    break;
166797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  }
1668b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
166997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  MCInst TmpInst;
167097f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  MCInstLowering.Lower(MI, TmpInst);
1671850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner  OutStreamer.EmitInstruction(TmpInst);
167297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner}
16732685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
16742685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
16752685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Target Registry Stuff
16762685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
16772685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
16782685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarstatic MCInstPrinter *createARMMCInstPrinter(const Target &T,
16792685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar                                             unsigned SyntaxVariant,
1680d374087be5360a353a4239a155b1227057145f48Chris Lattner                                             const MCAsmInfo &MAI) {
16812685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  if (SyntaxVariant == 0)
168274d7e6c64e955f89e6d3d4023d36fd481da4cfc1Jim Grosbach    return new ARMInstPrinter(MAI);
16832685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  return 0;
16842685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
16852685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
16862685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Force static initialization.
16872685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarextern "C" void LLVMInitializeARMAsmPrinter() {
16882685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget);
16892685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget);
16902685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
16912685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter);
16922685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter);
16932685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
16942685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
1695