ARMAsmPrinter.cpp revision b74ca9d63104c94b800f2763a654d19f3eb30304
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
9497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner    void printInstructionThroughMCStreamer(const MachineInstr *MI);
95b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
967bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
9735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
98a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                      const char *Modifier = 0);
9935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printSOImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
10035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printSOImm2PartOperand(const MachineInstr *MI, int OpNum,
10135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                raw_ostream &O);
10235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printSORegOperand(const MachineInstr *MI, int OpNum,
10335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                           raw_ostream &O);
10435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode2Operand(const MachineInstr *MI, int OpNum,
10535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
10635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNum,
10735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
10835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode3Operand(const MachineInstr *MI, int OpNum,
10935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
11035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode3OffsetOperand(const MachineInstr *MI, int OpNum,
11135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
11235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode4Operand(const MachineInstr *MI, int OpNum,raw_ostream &O,
113a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                               const char *Modifier = 0);
11435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode5Operand(const MachineInstr *MI, int OpNum,raw_ostream &O,
115a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                               const char *Modifier = 0);
11635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode6Operand(const MachineInstr *MI, int OpNum,
11735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
11835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printAddrMode6OffsetOperand(const MachineInstr *MI, int OpNum,
11935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
120055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    void printAddrModePCOperand(const MachineInstr *MI, int OpNum,
12135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                raw_ostream &O,
122a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                const char *Modifier = 0);
123eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    void printBitfieldInvMaskImmOperand(const MachineInstr *MI, int OpNum,
124eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson                                        raw_ostream &O);
1251adc40cac314b0a77b790b094bca146a3a868452Johnny Chen    void printMemBOption(const MachineInstr *MI, int OpNum,
1261adc40cac314b0a77b790b094bca146a3a868452Johnny Chen                         raw_ostream &O);
12722f5dc79c05d69391b17e14ed912aa8e98a63027Bob Wilson    void printShiftImmOperand(const MachineInstr *MI, int OpNum,
128eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson                              raw_ostream &O);
12935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner
13035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbS4ImmOperand(const MachineInstr *MI, int OpNum,
13135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                raw_ostream &O);
13235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbITMask(const MachineInstr *MI, int OpNum, raw_ostream &O);
13335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNum,
13435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
135055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNum,
13635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O,
137a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                      unsigned Scale);
13835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeS1Operand(const MachineInstr *MI, int OpNum,
13935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
14035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNum,
14135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
14235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNum,
14335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
14435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNum,
14535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
14635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner
14735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2SOOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
14835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm12Operand(const MachineInstr *MI, int OpNum,
14935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
15035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm8Operand(const MachineInstr *MI, int OpNum,
15135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                    raw_ostream &O);
15235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm8s4Operand(const MachineInstr *MI, int OpNum,
15335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O);
15435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm8OffsetOperand(const MachineInstr *MI, int OpNum,
15535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O);
15635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeImm8s4OffsetOperand(const MachineInstr *MI, int OpNum,
15735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                            raw_ostream &O) {}
15835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printT2AddrModeSoRegOperand(const MachineInstr *MI, int OpNum,
15935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O);
16035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner
16135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printCPSOptionOperand(const MachineInstr *MI, int OpNum,
16235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O) {}
16335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printMSRMaskOperand(const MachineInstr *MI, int OpNum,
16435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                             raw_ostream &O) {}
16535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printNegZeroOperand(const MachineInstr *MI, int OpNum,
16635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                             raw_ostream &O) {}
16735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printPredicateOperand(const MachineInstr *MI, int OpNum,
16835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
16935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printMandatoryPredicateOperand(const MachineInstr *MI, int OpNum,
17035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                        raw_ostream &O);
17135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printSBitModifierOperand(const MachineInstr *MI, int OpNum,
17235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                  raw_ostream &O);
17335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printPCLabel(const MachineInstr *MI, int OpNum,
17435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                      raw_ostream &O);
17535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printRegisterList(const MachineInstr *MI, int OpNum,
17635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                           raw_ostream &O);
177055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    void printCPInstOperand(const MachineInstr *MI, int OpNum,
17835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                            raw_ostream &O,
179a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                            const char *Modifier);
18035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printJTBlockOperand(const MachineInstr *MI, int OpNum,
18135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                             raw_ostream &O);
18235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printJT2BlockOperand(const MachineInstr *MI, int OpNum,
18335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                              raw_ostream &O);
18435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printTBAddrMode(const MachineInstr *MI, int OpNum,
18535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                         raw_ostream &O);
18635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printNoHashImmediate(const MachineInstr *MI, int OpNum,
18735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                              raw_ostream &O);
18835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printVFPf32ImmOperand(const MachineInstr *MI, int OpNum,
18935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
19035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printVFPf64ImmOperand(const MachineInstr *MI, int OpNum,
19135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                               raw_ostream &O);
1921a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson    void printNEONModImmOperand(const MachineInstr *MI, int OpNum,
1931a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson                                raw_ostream &O);
19454c78ef2fed32e82e6aea8cbeb89156814eaf27cBob Wilson
195055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
196c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                 unsigned AsmVariant, const char *ExtraCode,
197c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                 raw_ostream &O);
198055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
199224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson                                       unsigned AsmVariant,
200c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                       const char *ExtraCode, raw_ostream &O);
2017bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
20235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen
203d95148f073c31924f275a34296da52a7cdefad91Chris Lattner    static const char *getRegisterName(unsigned RegNo);
20405af2616d0df19638e799d3e7afadea26d96a4baChris Lattner
205a786ceac5c888761d83d84d35eb16150be57cc6eChris Lattner    virtual void EmitInstruction(const MachineInstr *MI);
2067bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola    bool runOnMachineFunction(MachineFunction &F);
207b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
208a2406190ca28dc5901dfe747849c8eda9c29d7eeChris Lattner    virtual void EmitConstantPool() {} // we emit constant pools customly!
209953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner    virtual void EmitFunctionEntryLabel();
210812209a58c5520c604bc9279aa069e5ae066e860Bob Wilson    void EmitStartOfAsmFile(Module &M);
2114a071d667d995b00e7853243ff9c7c1269324478Chris Lattner    void EmitEndOfAsmFile(Module &M);
212a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
21359135f49e1699daec9a43fc2d15715d55b910f54Devang Patel    MachineLocation getDebugValueLocation(const MachineInstr *MI) const {
21459135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      MachineLocation Location;
21559135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      assert (MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
21659135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      // Frame address.  Currently handles register +- offset only.
21759135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm())
21859135f49e1699daec9a43fc2d15715d55b910f54Devang Patel        Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
21959135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      else {
22059135f49e1699daec9a43fc2d15715d55b910f54Devang Patel        DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
22159135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      }
22259135f49e1699daec9a43fc2d15715d55b910f54Devang Patel      return Location;
22359135f49e1699daec9a43fc2d15715d55b910f54Devang Patel    }
22459135f49e1699daec9a43fc2d15715d55b910f54Devang Patel
225917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    virtual unsigned getISAEncoding() {
226917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      // ARM/Darwin adds ISA to the DWARF info for each function.
227917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      if (!Subtarget->isTargetDarwin())
228917290043f87b8efa6ba540bec5963013c517912Jim Grosbach        return 0;
229917290043f87b8efa6ba540bec5963013c517912Jim Grosbach      return Subtarget->isThumb() ?
230917290043f87b8efa6ba540bec5963013c517912Jim Grosbach        llvm::ARM::DW_ISA_ARM_thumb : llvm::ARM::DW_ISA_ARM_arm;
231917290043f87b8efa6ba540bec5963013c517912Jim Grosbach    }
232917290043f87b8efa6ba540bec5963013c517912Jim Grosbach
2330890cf124f00da3dc943c1882f4221955e0281edChris Lattner    MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
2340890cf124f00da3dc943c1882f4221955e0281edChris Lattner                                          const MachineBasicBlock *MBB) const;
2350890cf124f00da3dc943c1882f4221955e0281edChris Lattner    MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const;
236bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner
237711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    /// EmitMachineConstantPoolValue - Print a machine constantpool value to
238711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    /// the .s file.
239a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
2409d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      SmallString<128> Str;
2419d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      raw_svector_ostream OS(Str);
2429d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      EmitMachineConstantPoolValue(MCPV, OS);
2439d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText(OS.str());
2449d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    }
245b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
2469d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV,
2479d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                                      raw_ostream &O) {
248ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      switch (TM.getTargetData()->getTypeAllocSize(MCPV->getType())) {
249ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      case 1: O << MAI->getData8bitsDirective(0); break;
250ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      case 2: O << MAI->getData16bitsDirective(0); break;
251ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      case 4: O << MAI->getData32bitsDirective(0); break;
252ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      default: assert(0 && "Unknown CPV size");
253ea3cb40fab5dc84caa0c6c6bcb650261b4b6e724Chris Lattner      }
254a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
255711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng      ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
2563fb2b1ede30193b59a651328a946174196b20610Jim Grosbach
2573fb2b1ede30193b59a651328a946174196b20610Jim Grosbach      if (ACPV->isLSDA()) {
2589d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner        O << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
25928989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      } else if (ACPV->isBlockAddress()) {
2600752cda4de245978e14d806831abba4506272cd0Chris Lattner        O << *GetBlockAddressSymbol(ACPV->getBlockAddress());
26128989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      } else if (ACPV->isGlobalValue()) {
26246510a73e977273ec67747eb34cbdb43f815e451Dan Gohman        const GlobalValue *GV = ACPV->getGV();
263e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        bool isIndirect = Subtarget->isTargetDarwin() &&
26463476a80404125e5196b6c09113c1d4796da0604Evan Cheng          Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
265e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        if (!isIndirect)
266d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner          O << *Mang->getSymbol(GV);
267e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        else {
268e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng          // FIXME: Remove this when Darwin transition to @GOT like syntax.
2697a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner          MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
27010b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner          O << *Sym;
271b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
272b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner          MachineModuleInfoMachO &MMIMachO =
273b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner            MMI->getObjFileInfo<MachineModuleInfoMachO>();
274cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling          MachineModuleInfoImpl::StubValueTy &StubSym =
275b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner            GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(Sym) :
276b8f64a72d83b26ca29612081f3906272368a3692Chris Lattner                                        MMIMachO.getGVStubEntry(Sym);
277cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling          if (StubSym.getPointer() == 0)
278cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling            StubSym = MachineModuleInfoImpl::
279d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner              StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
280e4e4ed3b56f63e9343e01bf0b2ecd7c1f45d296cEvan Cheng        }
28128989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      } else {
28228989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson        assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
28310b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner        O << *GetExternalSymbolSymbol(ACPV->getSymbol());
28428989a8ddc665dce4dde368e8c000a5769871b63Bob Wilson      }
285e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
2860ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
28764f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio      if (ACPV->getPCAdjustment() != 0) {
28833adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner        O << "-(" << MAI->getPrivateGlobalPrefix() << "PC"
289e7e0d62efda2445b735052ca45bd74fb002e34c3Evan Cheng          << getFunctionNumber() << "_"  << ACPV->getLabelId()
29064f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio          << "+" << (unsigned)ACPV->getPCAdjustment();
29164f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio         if (ACPV->mustAddCurrentAddress())
29264f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio           O << "-.";
2938b3787586ed92df55131ad38c16646b7eba401a0Chris Lattner         O << ')';
29464f4fa5e0eb505eec3a72041bec6b3a7f7739dedLauro Ramos Venancio      }
295a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
2967bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola  };
2977bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola} // end of anonymous namespace
2987bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
2997bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola#include "ARMGenAsmWriter.inc"
3007bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
301953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattnervoid ARMAsmPrinter::EmitFunctionEntryLabel() {
302953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  if (AFI->isThumbFunction()) {
3039d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.EmitRawText(StringRef("\t.code\t16"));
3040752cda4de245978e14d806831abba4506272cd0Chris Lattner    if (!Subtarget->isTargetDarwin())
3059d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText(StringRef("\t.thumb_func"));
3060752cda4de245978e14d806831abba4506272cd0Chris Lattner    else {
3070752cda4de245978e14d806831abba4506272cd0Chris Lattner      // This needs to emit to a temporary string to get properly quoted
3080752cda4de245978e14d806831abba4506272cd0Chris Lattner      // MCSymbols when they have spaces in them.
3090752cda4de245978e14d806831abba4506272cd0Chris Lattner      SmallString<128> Tmp;
3100752cda4de245978e14d806831abba4506272cd0Chris Lattner      raw_svector_ostream OS(Tmp);
3110752cda4de245978e14d806831abba4506272cd0Chris Lattner      OS << "\t.thumb_func\t" << *CurrentFnSym;
3120752cda4de245978e14d806831abba4506272cd0Chris Lattner      OutStreamer.EmitRawText(OS.str());
3130752cda4de245978e14d806831abba4506272cd0Chris Lattner    }
314953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  }
315b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
316953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner  OutStreamer.EmitLabel(CurrentFnSym);
317953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner}
318953ebb769ada06d22f8ae4963651530b9cb84830Chris Lattner
319a8e2989ece6dc46df59b0768184028257f913843Evan Cheng/// runOnMachineFunction - This uses the printInstruction()
3207bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola/// method to print assembly for each instruction.
3217bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola///
3227bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindolabool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
323a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  AFI = MF.getInfo<ARMFunctionInfo>();
3246d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng  MCP = MF.getConstantPool();
325a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
326d49fe1b6bc4615684c2ec71140a21e9c4cd69ce3Chris Lattner  return AsmPrinter::runOnMachineFunction(MF);
32732bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola}
32832bd5f4f6a374f9ab0fcbd2cf6a8561019a6fd56Rafael Espindola
329055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
33035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                 raw_ostream &O, const char *Modifier) {
331055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
3325cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov  unsigned TF = MO.getTargetFlags();
3335cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov
3342f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  switch (MO.getType()) {
3358bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner  default:
3368bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(0 && "<unknown operand type>");
3375bafff36c798608a189c517d37527e4a38863071Bob Wilson  case MachineOperand::MO_Register: {
3385bafff36c798608a189c517d37527e4a38863071Bob Wilson    unsigned Reg = MO.getReg();
3398bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    assert(TargetRegisterInfo::isPhysicalRegister(Reg));
340de0ae8f83dd8eabc831b0631c20ffa3b53a774f2Bob Wilson    if (Modifier && strcmp(Modifier, "lane") == 0) {
341a4c3c8f28d9465dc7c42eb43c2377530f1821574Jim Grosbach      unsigned RegNum = getARMRegisterNumbering(Reg);
3429d1c1ada213c80135fbdda704175aae689daa6f9Chris Lattner      unsigned DReg =
343e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen        TM.getRegisterInfo()->getMatchingSuperReg(Reg,
344e00fa64c16f40230d76417be8f09166b7c84c52dJakob Stoklund Olesen          RegNum & 1 ? ARM::ssub_1 : ARM::ssub_0, &ARM::DPR_VFP2RegClass);
3458bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner      O << getRegisterName(DReg) << '[' << (RegNum & 1) << ']';
3468bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    } else {
347e8ea011cc766b37a957d5966655526096bf49feaAnton Korobeynikov      assert(!MO.getSubReg() && "Subregs should be eliminated!");
3488bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner      O << getRegisterName(Reg);
3498bc86cba60fbb35fbfb52cc32b9e451e6b903a27Chris Lattner    }
3502f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
3515bafff36c798608a189c517d37527e4a38863071Bob Wilson  }
352a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_Immediate: {
3535adb66a646e2ec32265263739f5b01c3f50c176aEvan Cheng    int64_t Imm = MO.getImm();
354632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << '#';
3555cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
3565cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov        (TF & ARMII::MO_LO16))
3575cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
3585cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
3595cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov             (TF & ARMII::MO_HI16))
3605cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
361632606c724ebcfa6a9da71c443151e7a65829c99Anton Korobeynikov    O << Imm;
3622f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
363a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
3642f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_MachineBasicBlock:
3651b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner    O << *MO.getMBB()->getSymbol();
3662f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    return;
36784b19be6ab9544f72eafb11048a1121f5ea77c95Rafael Espindola  case MachineOperand::MO_GlobalAddress: {
368a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    bool isCallOp = Modifier && !strcmp(Modifier, "call");
36946510a73e977273ec67747eb34cbdb43f815e451Dan Gohman    const GlobalValue *GV = MO.getGlobal();
3705cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov
3715cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
3725cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov        (TF & ARMII::MO_LO16))
3735cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":lower16:";
3745cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov    else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
3755cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov             (TF & ARMII::MO_HI16))
3765cdc3a949af0cef7f2163f8a7acbf3049c226321Anton Korobeynikov      O << ":upper16:";
377d62f1b4168d4327c119642d28c26c836ae6717abChris Lattner    O << *Mang->getSymbol(GV);
3787751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
3790c08d092049c025c9ccf7143e39f39dc4e30d6b4Chris Lattner    printOffset(MO.getOffset(), O);
3807751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
3810ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio    if (isCallOp && Subtarget->isTargetELF() &&
3820ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio        TM.getRelocationModel() == Reloc::PIC_)
3830ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
3842f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
385a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
386a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_ExternalSymbol: {
387a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    bool isCallOp = Modifier && !strcmp(Modifier, "call");
38810b318bcb39218d2ed525e4862c854bc8d1baf63Chris Lattner    O << *GetExternalSymbolSymbol(MO.getSymbolName());
389b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
3900ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio    if (isCallOp && Subtarget->isTargetELF() &&
3910ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio        TM.getRelocationModel() == Reloc::PIC_)
3920ae4a3357a556261f25b1584a2d9914637c69e65Lauro Ramos Venancio      O << "(PLT)";
3932f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
394a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
3952f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  case MachineOperand::MO_ConstantPoolIndex:
3961b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetCPISymbol(MO.getIndex());
3972f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola    break;
398a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  case MachineOperand::MO_JumpTableIndex:
3991b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    O << *GetJTISymbol(MO.getIndex());
400a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    break;
4012f99b6bd9601ae8d4fd248f9bb701283795c38a8Rafael Espindola  }
4027bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
4037bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
40435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnerstatic void printSOImm(raw_ostream &O, int64_t V, bool VerboseAsm,
40533adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner                       const MCAsmInfo *MAI) {
406e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng  // Break it up into two parts that make up a shifter immediate.
407e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng  V = ARM_AM::getSOImmVal(V);
408e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng  assert(V != -1 && "Not a valid so_imm value!");
409e7cbe4118b7ddf05032ff8772a98c51e1637bb5cEvan Cheng
410c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  unsigned Imm = ARM_AM::getSOImmValImm(V);
411c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  unsigned Rot = ARM_AM::getSOImmValRot(V);
4127751ad92daeea5a3502fbc266ae814baec5c03e6Anton Korobeynikov
413a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Print low-level immediate formation info, per
414a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // A5.1.3: "Data-processing operands - Immediate".
415a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Rot) {
416a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "#" << Imm << ", " << Rot;
417a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Pretty printed version.
41839382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng    if (VerboseAsm) {
41935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      O << "\t" << MAI->getCommentString() << ' ';
42039382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng      O << (int)ARM_AM::rotr32(Imm, Rot);
42139382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng    }
422a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
423a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "#" << Imm;
424a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
425a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
426a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
427c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
428c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng/// immediate in bits 0-7.
42935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum,
43035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O) {
431c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
432d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  assert(MO.isImm() && "Not a valid so_imm value!");
4333f53c8398d81065736a784469c9dd5afff85673fChris Lattner  printSOImm(O, MO.getImm(), isVerbose(), MAI);
434c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng}
435c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng
4369092213a5e50d4991f900d2df009d27bddfd9941Evan Cheng/// printSOImm2PartOperand - SOImm is broken into two pieces using a 'mov'
4379092213a5e50d4991f900d2df009d27bddfd9941Evan Cheng/// followed by an 'orr' to materialize.
43835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum,
43935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
440c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  const MachineOperand &MO = MI->getOperand(OpNum);
441d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  assert(MO.isImm() && "Not a valid so_imm value!");
4429a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner  unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImm());
4439a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner  unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImm());
4443f53c8398d81065736a784469c9dd5afff85673fChris Lattner  printSOImm(O, V1, isVerbose(), MAI);
4455e148a37d3432f83ccc4dbebe08d4f1b4717034cEvan Cheng  O << "\n\torr";
44635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printPredicateOperand(MI, 2, O);
447162e30921da0ce1863672d4ca5fef541498fe6beEvan Cheng  O << "\t";
44835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, 0, O);
449c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  O << ", ";
45035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, 0, O);
451c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng  O << ", ";
4523f53c8398d81065736a784469c9dd5afff85673fChris Lattner  printSOImm(O, V2, isVerbose(), MAI);
453c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng}
454c70d1849b7b85b06adf7dce856b3b19028fff8f7Evan Cheng
455a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// so_reg is a 4-operand unit corresponding to register forms of the A5.1
456a8e2989ece6dc46df59b0768184028257f913843Evan Cheng// "Addressing Mode 1 - Data-processing operands" forms.  This includes:
4579cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng//    REG 0   0           - e.g. R5
4589cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng//    REG REG 0,SH_OPC    - e.g. R5, ROR R3
459a8e2989ece6dc46df59b0768184028257f913843Evan Cheng//    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
46035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op,
46135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O) {
462a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
463a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
464a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
465a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
466762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << getRegisterName(MO1.getReg());
467a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
468a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Print the shift opc.
4691d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm());
4701d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
471a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (MO2.getReg()) {
4721d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson    O << ' ' << getRegisterName(MO2.getReg());
473a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
4741d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  } else if (ShOpc != ARM_AM::rrx) {
4751d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson    O << " #" << ARM_AM::getSORegOffset(MO3.getImm());
476a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
477a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
478a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
47935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op,
48035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
481a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
482a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
483a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
484a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
485d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
48635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, Op, O);
487a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
488a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
489a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
490762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
491a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
492a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!MO2.getReg()) {
4939e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0.
494a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      O << ", #"
4959e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen        << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
496a8e2989ece6dc46df59b0768184028257f913843Evan Cheng        << ARM_AM::getAM2Offset(MO3.getImm());
497a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << "]";
498a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
499a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
500a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
501a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << ", "
5029e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
503762ccea600158bb317dcccdff3303e942426cb71Chris Lattner    << getRegisterName(MO2.getReg());
504e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
505a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
506a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", "
5079a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
508a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << " #" << ShImm;
509a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
510a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
511a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
51235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op,
51335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O) {
514a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
515a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
516a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
517a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!MO1.getReg()) {
518bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng    unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
519bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng    O << "#"
5209e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen      << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
521bdc9869dbfa40579236405db73897a9fd19d1ed0Evan Cheng      << ImmOffs;
522a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
523a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
524a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
5259e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen  O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
526762ccea600158bb317dcccdff3303e942426cb71Chris Lattner    << getRegisterName(MO1.getReg());
527e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
528a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
529a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", "
5309a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm()))
531a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << " #" << ShImm;
532a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
533a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
53435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op,
53535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
536a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
537a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
538a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
539e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
5406f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
541762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
542a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
543a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (MO2.getReg()) {
544a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", "
545a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << (char)ARM_AM::getAM3Op(MO3.getImm())
546762ccea600158bb317dcccdff3303e942426cb71Chris Lattner      << getRegisterName(MO2.getReg())
547a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << "]";
548a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
549a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
550e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
551a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
552a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", #"
5539e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen      << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()))
554a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << ImmOffs;
555a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
556a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
557a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
55835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op,
55935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O){
560a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
561a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
562a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
563a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (MO1.getReg()) {
564a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << (char)ARM_AM::getAM3Op(MO2.getImm())
565762ccea600158bb317dcccdff3303e942426cb71Chris Lattner      << getRegisterName(MO1.getReg());
566a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
567a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
568a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
569a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
570a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "#"
5719e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()))
572a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    << ImmOffs;
573a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
574e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
575a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
57635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O,
577a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                          const char *Modifier) {
578a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
579a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
580a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Modifier && strcmp(Modifier, "submode") == 0) {
581ea7f22c31d0d12923eaab6840322431cc0222ae9Bob Wilson    O << ARM_AM::getAMSubModeStr(Mode);
582d77c7aba83bb290b9b62ede38b6ddbc9b790c6efEvan Cheng  } else if (Modifier && strcmp(Modifier, "wide") == 0) {
583d77c7aba83bb290b9b62ede38b6ddbc9b790c6efEvan Cheng    ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
584d77c7aba83bb290b9b62ede38b6ddbc9b790c6efEvan Cheng    if (Mode == ARM_AM::ia)
585d77c7aba83bb290b9b62ede38b6ddbc9b790c6efEvan Cheng      O << ".w";
586a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
58735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, Op, O);
588a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
589a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
590a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
591a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
59235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O,
593a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                          const char *Modifier) {
594a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
595a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
596a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
597d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
59835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, Op, O);
599a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
600a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
601e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
6026f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
603a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
604762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
605e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
606a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
607a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << ", #"
6089e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen      << ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2.getImm()))
609a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      << ImmOffs*4;
610a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
611a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
612a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
613a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
61435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode6Operand(const MachineInstr *MI, int Op,
61535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
6168b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson  const MachineOperand &MO1 = MI->getOperand(Op);
6178b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson  const MachineOperand &MO2 = MI->getOperand(Op+1);
6188b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson
6198a5ec86a3d4d599984e52c0c5a3a6a436607cf3eJim Grosbach  O << "[" << getRegisterName(MO1.getReg());
620226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson  if (MO2.getImm()) {
621bce3dbd9be29a42f32eb888086050cd620f2133bAnton Korobeynikov    // FIXME: Both darwin as and GNU as violate ARM docs here.
622273ff31e134d48c8247e981d30e214e82568ff86Bob Wilson    O << ", :" << (MO2.getImm() << 3);
6238a5ec86a3d4d599984e52c0c5a3a6a436607cf3eJim Grosbach  }
6248a5ec86a3d4d599984e52c0c5a3a6a436607cf3eJim Grosbach  O << "]";
625226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson}
626a43e6bf69093b9870548e7d782ea148e2ddd6449Bob Wilson
62735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printAddrMode6OffsetOperand(const MachineInstr *MI, int Op,
62835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O){
629226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson  const MachineOperand &MO = MI->getOperand(Op);
630226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson  if (MO.getReg() == 0)
631226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson    O << "!";
632226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson  else
633226036ee731a2041f37f28f958d2b6a50373f4f4Bob Wilson    O << ", " << getRegisterName(MO.getReg());
6348b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson}
6358b024a5eb5b64b482f7d92aad7a3f0e6cac93f12Bob Wilson
636a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
63735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O,
638a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                           const char *Modifier) {
639a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (Modifier && strcmp(Modifier, "label") == 0) {
64035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printPCLabel(MI, Op+1, O);
641a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
642a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
643a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
644a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
6456f0d024a534af18d9e60b3ea757376cd8a3a980eDan Gohman  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
6469e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen  O << "[pc, " << getRegisterName(MO1.getReg()) << "]";
647a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
648a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
649a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
65035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printBitfieldInvMaskImmOperand(const MachineInstr *MI, int Op,
65135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                              raw_ostream &O) {
652f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng  const MachineOperand &MO = MI->getOperand(Op);
653f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng  uint32_t v = ~MO.getImm();
6549e03cbefc5b3b8772a18d9bd25593ce62137ac85Evan Cheng  int32_t lsb = CountTrailingZeros_32(v);
655b825aaa0289206a63f7e6ce7b5ca7c2d6a2c063eNick Lewycky  int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb;
656f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng  assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
657f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng  O << "#" << lsb << ", #" << width;
658f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng}
659f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Cheng
6601adc40cac314b0a77b790b094bca146a3a868452Johnny Chenvoid
6611adc40cac314b0a77b790b094bca146a3a868452Johnny ChenARMAsmPrinter::printMemBOption(const MachineInstr *MI, int OpNum,
6621adc40cac314b0a77b790b094bca146a3a868452Johnny Chen                               raw_ostream &O) {
6631adc40cac314b0a77b790b094bca146a3a868452Johnny Chen  unsigned val = MI->getOperand(OpNum).getImm();
6641adc40cac314b0a77b790b094bca146a3a868452Johnny Chen  O << ARM_MB::MemBOptToString(val);
6651adc40cac314b0a77b790b094bca146a3a868452Johnny Chen}
6661adc40cac314b0a77b790b094bca146a3a868452Johnny Chen
66722f5dc79c05d69391b17e14ed912aa8e98a63027Bob Wilsonvoid ARMAsmPrinter::printShiftImmOperand(const MachineInstr *MI, int OpNum,
668eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson                                         raw_ostream &O) {
669eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  unsigned ShiftOp = MI->getOperand(OpNum).getImm();
670eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  ARM_AM::ShiftOpc Opc = ARM_AM::getSORegShOp(ShiftOp);
671eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  switch (Opc) {
672eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  case ARM_AM::no_shift:
673eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    return;
674eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  case ARM_AM::lsl:
675eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    O << ", lsl #";
676eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    break;
677eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  case ARM_AM::asr:
678eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    O << ", asr #";
679eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson    break;
680eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  default:
68122f5dc79c05d69391b17e14ed912aa8e98a63027Bob Wilson    assert(0 && "unexpected shift opcode for shift immediate operand");
682eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  }
683eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson  O << ARM_AM::getSORegOffset(ShiftOp);
684eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson}
685eaf1c98a7c38444d41d1c6dc2074736eec7d452fBob Wilson
686055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===//
687055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
68835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printThumbS4ImmOperand(const MachineInstr *MI, int Op,
68935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
6902ef9c8a43d1030bf65cafedf4b4b3f04d30180ceEvan Cheng  O << "#" <<  MI->getOperand(Op).getImm() * 4;
6912ef9c8a43d1030bf65cafedf4b4b3f04d30180ceEvan Cheng}
6922ef9c8a43d1030bf65cafedf4b4b3f04d30180ceEvan Cheng
693f49810c7e60807c43a68ab02c936a4ee77a4d2cfEvan Chengvoid
69435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbITMask(const MachineInstr *MI, int Op,
69535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                raw_ostream &O) {
696e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  // (3 - the number of trailing zeros) is the number of then / else.
697e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  unsigned Mask = MI->getOperand(Op).getImm();
6989e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen  unsigned CondBit0 = Mask >> 4 & 1;
699e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  unsigned NumTZ = CountTrailingZeros_32(Mask);
700e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  assert(NumTZ <= 3 && "Invalid IT mask!");
70106e16587ebc81e43b42157fa3afcfd806b59b296Evan Cheng  for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
7029e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    bool T = ((Mask >> Pos) & 1) == CondBit0;
703e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng    if (T)
704e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng      O << 't';
705e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng    else
706e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng      O << 'e';
707e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng  }
708e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng}
709e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Cheng
710e5564748b7d35df5c06fd243d04ea1eb305d3bc3Evan Chengvoid
71135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op,
71235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
713a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
714a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
715762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
716762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << ", " << getRegisterName(MO2.getReg()) << "]";
717a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
718a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
719a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
720a8e2989ece6dc46df59b0768184028257f913843Evan ChengARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
72135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                            raw_ostream &O,
722a8e2989ece6dc46df59b0768184028257f913843Evan Cheng                                            unsigned Scale) {
723a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
724cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
725cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  const MachineOperand &MO3 = MI->getOperand(Op+2);
726a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
727d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman  if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
72835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, Op, O);
729a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    return;
730a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
731a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
732762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
733cea117d2de0bfe422641e2ada4fef160e099a6b4Evan Cheng  if (MO3.getReg())
734762ccea600158bb317dcccdff3303e942426cb71Chris Lattner    O << ", " << getRegisterName(MO3.getReg());
7354b6bbe1e9c40fb58eccaf3671432661016663aabEvan Cheng  else if (unsigned ImmOffs = MO2.getImm())
7369e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << ImmOffs * Scale;
737a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
738a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
739a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
740a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
74135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op,
74235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
74335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printThumbAddrModeRI5Operand(MI, Op, O, 1);
744a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
745a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
74635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op,
74735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
74835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printThumbAddrModeRI5Operand(MI, Op, O, 2);
749a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
750a8e2989ece6dc46df59b0768184028257f913843Evan Chengvoid
75135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op,
75235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                           raw_ostream &O) {
75335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printThumbAddrModeRI5Operand(MI, Op, O, 4);
754a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
755a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
75635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op,
75735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O) {
758a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO1 = MI->getOperand(Op);
759a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const MachineOperand &MO2 = MI->getOperand(Op+1);
760762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
761a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (unsigned ImmOffs = MO2.getImm())
7629e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << ImmOffs*4;
763a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "]";
7647bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
7657bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
766055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===//
767055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
7689cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
7699cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng// register with shift forms.
7709cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng// REG 0   0           - e.g. R5
7719cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng// REG IMM, SH_OPC     - e.g. R5, LSL #3
77235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printT2SOOperand(const MachineInstr *MI, int OpNum,
77335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                     raw_ostream &O) {
7749cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
7759cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
7769cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng
7779cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  unsigned Reg = MO1.getReg();
7789cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  assert(TargetRegisterInfo::isPhysicalRegister(Reg));
779762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << getRegisterName(Reg);
7809cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng
7819cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  // Print the shift opc.
7829cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng  assert(MO2.isImm() && "Not a valid t2_so_reg value!");
7831d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO2.getImm());
7841d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
7851d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson  if (ShOpc != ARM_AM::rrx)
7861d9125a6ff192f1346d2b08bbf6ecc9c9e44103dBob Wilson    O << " #" << ARM_AM::getSORegOffset(MO2.getImm());
7879cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng}
7889cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng
789055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printT2AddrModeImm12Operand(const MachineInstr *MI,
79035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                int OpNum,
79135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O) {
792055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
793055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
794055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
795762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
796055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
797055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  unsigned OffImm = MO2.getImm();
798055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  if (OffImm)  // Don't print +0.
7999e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << OffImm;
800055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  O << "]";
801055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng}
802055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
803055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printT2AddrModeImm8Operand(const MachineInstr *MI,
80435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                               int OpNum,
80535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                               raw_ostream &O) {
806055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
807055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
808055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
809762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
810055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
811055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  int32_t OffImm = (int32_t)MO2.getImm();
812055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  // Don't print +0.
813055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  if (OffImm < 0)
814055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    O << ", #-" << -OffImm;
815055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  else if (OffImm > 0)
8169e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << OffImm;
817055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  O << "]";
818055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng}
819055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
8205c874172ac8fd563867efc54022ac4c1571e1313Evan Chengvoid ARMAsmPrinter::printT2AddrModeImm8s4Operand(const MachineInstr *MI,
82135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                 int OpNum,
82235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                 raw_ostream &O) {
8235c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
8245c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
8255c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng
826762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
8275c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng
8285c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  int32_t OffImm = (int32_t)MO2.getImm() / 4;
8295c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  // Don't print +0.
8305c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  if (OffImm < 0)
831a64ce4591762b93030cd2a2ff202bbd5badfecddEvan Cheng    O << ", #-" << -OffImm * 4;
8325c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  else if (OffImm > 0)
8339e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << ", #" << OffImm * 4;
8345c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng  O << "]";
8355c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng}
8365c874172ac8fd563867efc54022ac4c1571e1313Evan Cheng
837e88d5cee9d6b02bc786df806395a718464908064Evan Chengvoid ARMAsmPrinter::printT2AddrModeImm8OffsetOperand(const MachineInstr *MI,
83835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                     int OpNum,
83935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                     raw_ostream &O) {
840e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
841e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  int32_t OffImm = (int32_t)MO1.getImm();
842e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  // Don't print +0.
843e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  if (OffImm < 0)
844e88d5cee9d6b02bc786df806395a718464908064Evan Cheng    O << "#-" << -OffImm;
845e88d5cee9d6b02bc786df806395a718464908064Evan Cheng  else if (OffImm > 0)
8469e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen    O << "#" << OffImm;
8479e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen}
8489e08876a2ae329feb7a76dbfe33666cb58033c00Johnny Chen
849055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printT2AddrModeSoRegOperand(const MachineInstr *MI,
85035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                int OpNum,
85135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                raw_ostream &O) {
852055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
853055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1);
854055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO3 = MI->getOperand(OpNum+2);
855055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
856762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[" << getRegisterName(MO1.getReg());
857055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
8583a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng  assert(MO2.getReg() && "Invalid so_reg load / store address!");
859762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << ", " << getRegisterName(MO2.getReg());
8609cb9e6778c7d458eee7f3e25d304697ad10d8d46Evan Cheng
8613a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng  unsigned ShAmt = MO3.getImm();
8623a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng  if (ShAmt) {
8633a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng    assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
8643a21425dbe09c7ac85e6b156f82184dd6132435aEvan Cheng    O << ", lsl #" << ShAmt;
865055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  }
866055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  O << "]";
867055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng}
868055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
869055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
870055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng//===--------------------------------------------------------------------===//
871055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng
87235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printPredicateOperand(const MachineInstr *MI, int OpNum,
87335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
874055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
87544bec52b1b7e9a3ac1efbae90db240b8c1ca2ad4Evan Cheng  if (CC != ARMCC::AL)
87644bec52b1b7e9a3ac1efbae90db240b8c1ca2ad4Evan Cheng    O << ARMCondCodeToString(CC);
8777bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
8787bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
8799d3acaa1a015c4499595eaff529686a517c14e15Johnny Chenvoid ARMAsmPrinter::printMandatoryPredicateOperand(const MachineInstr *MI,
88035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                   int OpNum,
88135c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                                   raw_ostream &O) {
8829d3acaa1a015c4499595eaff529686a517c14e15Johnny Chen  ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
8839d3acaa1a015c4499595eaff529686a517c14e15Johnny Chen  O << ARMCondCodeToString(CC);
8849d3acaa1a015c4499595eaff529686a517c14e15Johnny Chen}
8859d3acaa1a015c4499595eaff529686a517c14e15Johnny Chen
88635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printSBitModifierOperand(const MachineInstr *MI, int OpNum,
88735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                             raw_ostream &O){
888055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  unsigned Reg = MI->getOperand(OpNum).getReg();
889dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng  if (Reg) {
890dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng    assert(Reg == ARM::CPSR && "Expect ARM CPSR register!");
891dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng    O << 's';
892dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng  }
893dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng}
894dfb2ebac29f92a533218bd576734913a89d1299dEvan Cheng
89535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int OpNum,
89635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                 raw_ostream &O) {
897055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  int Id = (int)MI->getOperand(OpNum).getImm();
898e7e0d62efda2445b735052ca45bd74fb002e34c3Evan Cheng  O << MAI->getPrivateGlobalPrefix()
899e7e0d62efda2445b735052ca45bd74fb002e34c3Evan Cheng    << "PC" << getFunctionNumber() << "_" << Id;
900a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
901a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
90235c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int OpNum,
90335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                      raw_ostream &O) {
904a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "{";
905815baebe1c8dc02accf128ae10dff9a1742d3244Bob Wilson  for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
9064b322e58b77d16f103d88a3af3a4ebd2675245a0Evan Cheng    if (MI->getOperand(i).isImplicit())
9074b322e58b77d16f103d88a3af3a4ebd2675245a0Evan Cheng      continue;
908815baebe1c8dc02accf128ae10dff9a1742d3244Bob Wilson    if ((int)i != OpNum) O << ", ";
90935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    printOperand(MI, i, O);
910a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
911a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  O << "}";
912a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
913a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
914055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengvoid ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNum,
91535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                       raw_ostream &O, const char *Modifier) {
916a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  assert(Modifier && "This operand only works with a modifier!");
917a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
918a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // data itself.
919a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (!strcmp(Modifier, "label")) {
920055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    unsigned ID = MI->getOperand(OpNum).getImm();
9218e089a9e4d6b7aa2b3968c38644f926f60a7c670Chris Lattner    OutStreamer.EmitLabel(GetCPISymbol(ID));
922a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  } else {
923a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
924055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng    unsigned CPI = MI->getOperand(OpNum).getIndex();
925a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
9266d63a728586d56eb3e881905beb9db27f520f5d3Evan Cheng    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI];
927e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
928711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    if (MCPE.isMachineConstantPoolEntry()) {
929a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
930711b6dce246c87b5d830966bed823d0e7aa15300Evan Cheng    } else {
931a8e2989ece6dc46df59b0768184028257f913843Evan Cheng      EmitGlobalConstant(MCPE.Val.ConstVal);
932305b8a5f62c9d027f3d8a870fc12fc2abf69aeeaLauro Ramos Venancio    }
933a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
934a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
935a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
9360890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
9370890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
9380890cf124f00da3dc943c1882f4221955e0281edChris Lattner                            const MachineBasicBlock *MBB) const {
9390890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
9400890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
941bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2
9420890cf124f00da3dc943c1882f4221955e0281edChris Lattner    << "_set_" << MBB->getNumber();
9439b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
9440890cf124f00da3dc943c1882f4221955e0281edChris Lattner}
9450890cf124f00da3dc943c1882f4221955e0281edChris Lattner
9460890cf124f00da3dc943c1882f4221955e0281edChris LattnerMCSymbol *ARMAsmPrinter::
9470890cf124f00da3dc943c1882f4221955e0281edChris LattnerGetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
9480890cf124f00da3dc943c1882f4221955e0281edChris Lattner  SmallString<60> Name;
9490890cf124f00da3dc943c1882f4221955e0281edChris Lattner  raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
950281e7767df71b3f727ade80a16ff0c4fe5a49dd9Chris Lattner    << getFunctionNumber() << '_' << uid << '_' << uid2;
9519b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner  return OutContext.GetOrCreateSymbol(Name.str());
952bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner}
953bfcb09688c7db15a9f9415d717a5a31c499a2208Chris Lattner
95435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum,
95535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                        raw_ostream &O) {
95666ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  assert(!Subtarget->isThumb2() && "Thumb2 should use double-jump jumptables!");
95766ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng
958055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
959055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
960b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
9618aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner  unsigned JTI = MO1.getIndex();
9620890cf124f00da3dc943c1882f4221955e0281edChris Lattner  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
96303335350547b5d3521f9912d301bbb799d7eea31Chris Lattner  // Can't use EmitLabel until instprinter happens, label comes out in the wrong
96403335350547b5d3521f9912d301bbb799d7eea31Chris Lattner  // order.
965d4d188e5029801ef2a76ee756dcba49f313004f0Bob Wilson  O << "\n" << *JTISymbol << ":\n";
966a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
96733adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner  const char *JTEntryDirective = MAI->getData32bitsDirective();
968a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
9694542611bb9793e8376d7d5f33b4a1e2d11712894Dan Gohman  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
970a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
971a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
972cee63322eaccc2f1067bdf5eab506e440f867da1Chris Lattner  bool UseSet= MAI->hasSetDirective() && TM.getRelocationModel() == Reloc::PIC_;
973c324ecb7bc93a1f09db29851438ec5ee72b143ebEvan Cheng  SmallPtrSet<MachineBasicBlock*, 8> JTSets;
974a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
975a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    MachineBasicBlock *MBB = JTBBs[i];
97666ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng    bool isNew = JTSets.insert(MBB);
97766ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng
9780890cf124f00da3dc943c1882f4221955e0281edChris Lattner    if (UseSet && isNew) {
979cee63322eaccc2f1067bdf5eab506e440f867da1Chris Lattner      O << "\t.set\t"
9801f9b48ad87a5dab4a6c3805c369414c831e4451dJim Grosbach        << *GetARMSetPICJumpTableLabel2(JTI, MO2.getImm(), MBB) << ','
9811b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner        << *MBB->getSymbol() << '-' << *JTISymbol << '\n';
9820890cf124f00da3dc943c1882f4221955e0281edChris Lattner    }
983a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
984a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    O << JTEntryDirective << ' ';
985a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (UseSet)
9860890cf124f00da3dc943c1882f4221955e0281edChris Lattner      O << *GetARMSetPICJumpTableLabel2(JTI, MO2.getImm(), MBB);
9870890cf124f00da3dc943c1882f4221955e0281edChris Lattner    else if (TM.getRelocationModel() == Reloc::PIC_)
9881b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner      O << *MBB->getSymbol() << '-' << *JTISymbol;
9890890cf124f00da3dc943c1882f4221955e0281edChris Lattner    else
9901b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner      O << *MBB->getSymbol();
9910890cf124f00da3dc943c1882f4221955e0281edChris Lattner
992d85ac4d07966a56b3101598f29393f4532acc50fEvan Cheng    if (i != e-1)
993d85ac4d07966a56b3101598f29393f4532acc50fEvan Cheng      O << '\n';
994a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
995a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
996a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
99735c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printJT2BlockOperand(const MachineInstr *MI, int OpNum,
99835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                         raw_ostream &O) {
99966ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const MachineOperand &MO1 = MI->getOperand(OpNum);
100066ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
100166ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  unsigned JTI = MO1.getIndex();
1002b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
10030890cf124f00da3dc943c1882f4221955e0281edChris Lattner  MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
1004b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
100503335350547b5d3521f9912d301bbb799d7eea31Chris Lattner  // Can't use EmitLabel until instprinter happens, label comes out in the wrong
100603335350547b5d3521f9912d301bbb799d7eea31Chris Lattner  // order.
1007d4d188e5029801ef2a76ee756dcba49f313004f0Bob Wilson  O << "\n" << *JTISymbol << ":\n";
100866ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng
100966ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
101066ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
101166ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
10125657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  bool ByteOffset = false, HalfWordOffset = false;
10135657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  if (MI->getOpcode() == ARM::t2TBB)
10145657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    ByteOffset = true;
10155657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  else if (MI->getOpcode() == ARM::t2TBH)
10165657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    HalfWordOffset = true;
10175657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng
101866ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
101966ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng    MachineBasicBlock *MBB = JTBBs[i];
10205657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    if (ByteOffset)
102133adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner      O << MAI->getData8bitsDirective();
10225657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    else if (HalfWordOffset)
102333adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattner      O << MAI->getData16bitsDirective();
1024b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
10250890cf124f00da3dc943c1882f4221955e0281edChris Lattner    if (ByteOffset || HalfWordOffset)
10261b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner      O << '(' << *MBB->getSymbol() << "-" << *JTISymbol << ")/2";
10270890cf124f00da3dc943c1882f4221955e0281edChris Lattner    else
10281b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner      O << "\tb.w " << *MBB->getSymbol();
10290890cf124f00da3dc943c1882f4221955e0281edChris Lattner
103066ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng    if (i != e-1)
103166ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng      O << '\n';
103266ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng  }
103366ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng}
103466ac53165e17b7c76b8c69e57bde623d44ec492eEvan Cheng
103535c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printTBAddrMode(const MachineInstr *MI, int OpNum,
103635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                    raw_ostream &O) {
1037762ccea600158bb317dcccdff3303e942426cb71Chris Lattner  O << "[pc, " << getRegisterName(MI->getOperand(OpNum).getReg());
10385657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  if (MI->getOpcode() == ARM::t2TBH)
10395657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng    O << ", lsl #1";
10405657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng  O << ']';
10415657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng}
10425657c01949dca6c012ac60d242d1a8d2ffdf5603Evan Cheng
104335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printNoHashImmediate(const MachineInstr *MI, int OpNum,
104435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                         raw_ostream &O) {
10458e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov  O << MI->getOperand(OpNum).getImm();
10468e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov}
1047a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
104835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printVFPf32ImmOperand(const MachineInstr *MI, int OpNum,
104935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
105039382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng  const ConstantFP *FP = MI->getOperand(OpNum).getFPImm();
105177b02beb1fa3a96efc05081889d1ae4ffecb44a7Jim Grosbach  O << '#' << FP->getValueAPF().convertToFloat();
10523f53c8398d81065736a784469c9dd5afff85673fChris Lattner  if (isVerbose()) {
105335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    O << "\t\t" << MAI->getCommentString() << ' ';
105439382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng    WriteAsOperand(O, FP, /*PrintType=*/false);
105539382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng  }
105639382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng}
105739382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng
105835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid ARMAsmPrinter::printVFPf64ImmOperand(const MachineInstr *MI, int OpNum,
105935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner                                          raw_ostream &O) {
106039382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng  const ConstantFP *FP = MI->getOperand(OpNum).getFPImm();
106177b02beb1fa3a96efc05081889d1ae4ffecb44a7Jim Grosbach  O << '#' << FP->getValueAPF().convertToDouble();
10623f53c8398d81065736a784469c9dd5afff85673fChris Lattner  if (isVerbose()) {
106335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner    O << "\t\t" << MAI->getCommentString() << ' ';
106439382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng    WriteAsOperand(O, FP, /*PrintType=*/false);
106539382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng  }
106639382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng}
106739382427f1095f089d73a7dd3d9a371dea75b781Evan Cheng
10681a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilsonvoid ARMAsmPrinter::printNEONModImmOperand(const MachineInstr *MI, int OpNum,
10691a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson                                           raw_ostream &O) {
10706dce00ced45b5bd1b7f34fe6f2d70c50fc090664Bob Wilson  unsigned EncodedImm = MI->getOperand(OpNum).getImm();
10716dce00ced45b5bd1b7f34fe6f2d70c50fc090664Bob Wilson  unsigned EltBits;
10726dce00ced45b5bd1b7f34fe6f2d70c50fc090664Bob Wilson  uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits);
10731a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson  O << "#0x" << utohexstr(Val);
10741a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson}
10751a913ed17875d1a0fb490e1266b74c057c76a94bBob Wilson
1076055b0310f862b91f33699037ce67d3ab8137c20cEvan Chengbool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
1077c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    unsigned AsmVariant, const char *ExtraCode,
1078c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                    raw_ostream &O) {
1079a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  // Does this asm operand have a single letter operand modifier?
1080a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  if (ExtraCode && ExtraCode[0]) {
1081a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    if (ExtraCode[1] != 0) return true; // Unknown modifier.
10828e9ece75db5045ec057efbbdba6550fa0d85e695Anton Korobeynikov
1083a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    switch (ExtraCode[0]) {
1084a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    default: return true;  // Unknown modifier.
10859b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'a': // Print as a memory address.
10869b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      if (MI->getOperand(OpNum).isReg()) {
1087762ccea600158bb317dcccdff3303e942426cb71Chris Lattner        O << "[" << getRegisterName(MI->getOperand(OpNum).getReg()) << "]";
10889b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson        return false;
10899b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      }
10909b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson      // Fallthrough
10919b4b00ad436daeac6f97f77e9b5a3cc67ada150cBob Wilson    case 'c': // Don't print "#" before an immediate operand.
10924f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson      if (!MI->getOperand(OpNum).isImm())
10934f38b383d5089c49489a9a56d8efd0eb76048b3fBob Wilson        return true;
109435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      printNoHashImmediate(MI, OpNum, O);
10958f3434647d3d39b49475239e3be1b8afb06415cfBob Wilson      return false;
1096e21e39666e8a41ffd4971d8bb023b70b59297267Evan Cheng    case 'P': // Print a VFP double precision register.
1097d831cda3e74235704f163d5a18352584d537517aEvan Cheng    case 'q': // Print a NEON quad precision register.
109835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner      printOperand(MI, OpNum, O);
109923a95704949b99ca07afe45c6946d0fa26baf9f3Evan Cheng      return false;
1100a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'Q':
1101a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    case 'R':
1102d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson    case 'H':
110312616727c71721f480f69026d88a58a067d89824Evan Cheng      report_fatal_error("llvm does not support 'Q', 'R', and 'H' modifiers!");
1104d984eb6073d5445f08fb0cea67a668b1b5e888e0Bob Wilson      return true;
110584f60b7359e1aa90794bb19de2bbf4d25dc2f01dEvan Cheng    }
1106a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  }
1107e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
110835c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner  printOperand(MI, OpNum, O);
1109a8e2989ece6dc46df59b0768184028257f913843Evan Cheng  return false;
1110a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
1111a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1112224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilsonbool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
1113055b0310f862b91f33699037ce67d3ab8137c20cEvan Cheng                                          unsigned OpNum, unsigned AsmVariant,
1114c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          const char *ExtraCode,
1115c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner                                          raw_ostream &O) {
1116224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  if (ExtraCode && ExtraCode[0])
1117224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson    return true; // Unknown modifier.
1118765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson
1119765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  const MachineOperand &MO = MI->getOperand(OpNum);
1120765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  assert(MO.isReg() && "unexpected inline asm memory operand");
1121765cc0b9d59bf63dfcb02e3d126ea1c63e16f86fBob Wilson  O << "[" << getRegisterName(MO.getReg()) << "]";
1122224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson  return false;
1123224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson}
1124224c244f56025c10e70e4204daceadfb3cdd2c06Bob Wilson
1125a786ceac5c888761d83d84d35eb16150be57cc6eChris Lattnervoid ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
112697f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  if (EnableMCInst) {
112797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner    printInstructionThroughMCStreamer(MI);
11287ad07c46362500f7291a92742569e94fd3538dfdChris Lattner    return;
112997f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  }
1130b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
11317ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  if (MI->getOpcode() == ARM::CONSTPOOL_ENTRY)
11327ad07c46362500f7291a92742569e94fd3538dfdChris Lattner    EmitAlignment(2);
1133b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
11347ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  SmallString<128> Str;
11357ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  raw_svector_ostream OS(Str);
11363f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen  if (MI->getOpcode() == ARM::DBG_VALUE) {
11373f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    unsigned NOps = MI->getNumOperands();
11383f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    assert(NOps==4);
11393f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
11403f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    // cast away const; DIetc do not take const operands for some reason.
11413f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
11423f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << V.getName();
11433f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << " <- ";
11443f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    // Frame address.  Currently handles register +- offset only.
11453f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
11463f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS);
11473f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << ']';
11483f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OS << "+";
11493f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    printOperand(MI, NOps-2, OS);
11503f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    OutStreamer.EmitRawText(OS.str());
11513f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen    return;
11523f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen  }
11533f282aa94b80f4a93ff3cbc37cf3cd4a851c8432Dale Johannesen
11547ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  printInstruction(MI, OS);
11557ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  OutStreamer.EmitRawText(OS.str());
1156b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
11577ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  // Make sure the instruction that follows TBB is 2-byte aligned.
11587ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  // FIXME: Constant island pass should insert an "ALIGN" instruction instead.
11597ad07c46362500f7291a92742569e94fd3538dfdChris Lattner  if (MI->getOpcode() == ARM::t2TBB)
11607ad07c46362500f7291a92742569e94fd3538dfdChris Lattner    EmitAlignment(1);
1161a8e2989ece6dc46df59b0768184028257f913843Evan Cheng}
1162a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1163812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
11640fb34683b9e33238288d2af1e090582464df8387Bob Wilson  if (Subtarget->isTargetDarwin()) {
11650fb34683b9e33238288d2af1e090582464df8387Bob Wilson    Reloc::Model RelocM = TM.getRelocationModel();
11660fb34683b9e33238288d2af1e090582464df8387Bob Wilson    if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
11670fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // Declare all the text sections up front (before the DWARF sections
11680fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // emitted by AsmPrinter::doInitialization) so the assembler will keep
11690fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // them together at the beginning of the object file.  This helps
11700fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // avoid out-of-range branches that are due a fundamental limitation of
11710fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // the way symbol offsets are encoded with the current Darwin ARM
11720fb34683b9e33238288d2af1e090582464df8387Bob Wilson      // relocations.
1173b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach      const TargetLoweringObjectFileMachO &TLOFMacho =
11740d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman        static_cast<const TargetLoweringObjectFileMachO &>(
11750d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman          getObjFileLowering());
117629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextSection());
117729e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
117829e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection());
117929e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      if (RelocM == Reloc::DynamicNoPIC) {
118029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
118122772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__symbol_stub4",
118222772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
118322772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     12, SectionKind::getText());
118429e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
118529e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      } else {
118629e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        const MCSection *sect =
118722772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner          OutContext.getMachOSection("__TEXT", "__picsymbolstub4",
118822772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     MCSectionMachO::S_SYMBOL_STUBS,
118922772214de79aa1c5ca38c4fb1da137d8fb30a05Chris Lattner                                     16, SectionKind::getText());
119029e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson        OutStreamer.SwitchSection(sect);
119129e066965fb84b3aad2840815c6d0602dafb0b17Bob Wilson      }
119263db594559dc8eac666204c7907bae664f5234daBob Wilson      const MCSection *StaticInitSect =
119363db594559dc8eac666204c7907bae664f5234daBob Wilson        OutContext.getMachOSection("__TEXT", "__StaticInit",
119463db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_REGULAR |
119563db594559dc8eac666204c7907bae664f5234daBob Wilson                                   MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
119663db594559dc8eac666204c7907bae664f5234daBob Wilson                                   SectionKind::getText());
119763db594559dc8eac666204c7907bae664f5234daBob Wilson      OutStreamer.SwitchSection(StaticInitSect);
11980fb34683b9e33238288d2af1e090582464df8387Bob Wilson    }
11990fb34683b9e33238288d2af1e090582464df8387Bob Wilson  }
12000fb34683b9e33238288d2af1e090582464df8387Bob Wilson
1201e5165490b7ba24bb2f3043399e0d60e7f3bcf8a5Jim Grosbach  // Use unified assembler syntax.
12029d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner  OutStreamer.EmitRawText(StringRef("\t.syntax unified"));
1203d61eca533081580d56fabee38f86507d8019ca75Anton Korobeynikov
120488ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  // Emit ARM Build Attributes
120588ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  if (Subtarget->isTargetELF()) {
120688ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // CPU Type
1207d260c248abd57763aaeeadcab4155655a25d9e97Anton Korobeynikov    std::string CPUString = Subtarget->getCPUString();
1208d260c248abd57763aaeeadcab4155655a25d9e97Anton Korobeynikov    if (CPUString != "generic")
12099d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.cpu " + Twine(CPUString));
121088ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
121188ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // FIXME: Emit FPU type
121288ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    if (Subtarget->hasVFP2())
12139d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12149d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::VFP_arch) + ", 2");
121588ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
121688ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // Signal various FP modes.
12179d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    if (!UnsafeFPMath) {
12189d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12199d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_denormal) + ", 1");
12209d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12219d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_exceptions) + ", 1");
12229d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    }
1223b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
122460108e96bbc5432f4fe06ba313e64448e97a0e15Evan Cheng    if (NoInfsFPMath && NoNaNsFPMath)
12259d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12269d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 1");
122788ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    else
12289d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12299d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 3");
123088ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
123188ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // 8-bytes alignment stuff.
12329d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.EmitRawText("\t.eabi_attribute " +
12339d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                            Twine(ARMBuildAttrs::ABI_align8_needed) + ", 1");
12349d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    OutStreamer.EmitRawText("\t.eabi_attribute " +
12359d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                            Twine(ARMBuildAttrs::ABI_align8_preserved) + ", 1");
123688ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov
1237567d14f07cd62bfb9dd0edd90144a0a840450f7aAnton Korobeynikov    // Hard float.  Use both S and D registers and conform to AAPCS-VFP.
12389d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) {
12399d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12409d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_HardFP_use) + ", 3");
12419d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner      OutStreamer.EmitRawText("\t.eabi_attribute " +
12429d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner                              Twine(ARMBuildAttrs::ABI_VFP_args) + ", 1");
12439d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner    }
124488ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov    // FIXME: Should we signal R9 usage?
124588ce667003a33e008d9ecc6811584681787e8150Anton Korobeynikov  }
12467bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
12477bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola
12480f3cc657387d44cd7c56e4ddea896a50ab9106b8Anton Korobeynikov
12494a071d667d995b00e7853243ff9c7c1269324478Chris Lattnervoid ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
12505be54b00bdbe1abd02dde46ca2c4b0e5aaf7b537Evan Cheng  if (Subtarget->isTargetDarwin()) {
1251f61159b574155b056dbd5d6d44f47f753d424056Chris Lattner    // All darwin targets use mach-o.
12520d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman    const TargetLoweringObjectFileMachO &TLOFMacho =
12530d805c33d134d88169e3dc4a3272cff9a5713ce7Dan Gohman      static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
1254b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO &MMIMacho =
1255b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      MMI->getObjFileInfo<MachineModuleInfoMachO>();
1256e9952213086c865eb678bd3f4c9c7d849f0249d2Jim Grosbach
1257a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Output non-lazy-pointers for external and common global variables.
1258b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
1259cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling
1260b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner    if (!Stubs.empty()) {
1261ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner      // Switch with ".non_lazy_symbol_pointer" directive.
12626c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
1263c076a9793936b140364671a5e39ee53bd266c6c3Chris Lattner      EmitAlignment(2);
1264b0f294c14b4e7098e5170ecfd528bcc9682ce0c7Chris Lattner      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1265becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
1266becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
1267becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .indirect_symbol _foo
126852a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
126952a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol);
1270cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
127152a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling        if (MCSym.getInt())
1272cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // External to current translation unit.
1273cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
1274cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling        else
1275cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling          // Internal to current translation unit.
12765e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          //
12775e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          // When we place the LSDA into the TEXT section, the type info pointers
12785e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          // need to be indirect and pc-rel. We accomplish this by using NLPs.
12795e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          // However, sometimes the types are local to the file. So we need to
12805e1b55d67288874f8669621b9176814ce449f8f5Bill Wendling          // fill in the value for the NLP in those cases.
128152a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling          OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
128252a50e5d0e6ac08d86706dbdd8f4a5dbb44da4cbBill Wendling                                                        OutContext),
1283cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling                                4/*size*/, 0/*addrspace*/);
1284ae94e594164b193236002516970aeec4c4574768Evan Cheng      }
1285becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling
1286becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      Stubs.clear();
1287becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      OutStreamer.AddBlankLine();
1288a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    }
1289a8e2989ece6dc46df59b0768184028257f913843Evan Cheng
1290e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    Stubs = MMIMacho.GetHiddenGVStubList();
1291e4d9ea83c0d4bcc535bd978e1afa599eb3ebb893Chris Lattner    if (!Stubs.empty()) {
12926c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner      OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
1293f3231de60bb64c3f6fc6770b3e6174f4f839a4f3Chris Lattner      EmitAlignment(2);
1294becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1295becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        // L_foo$stub:
1296becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        OutStreamer.EmitLabel(Stubs[i].first);
1297becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling        //   .long _foo
1298cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling        OutStreamer.EmitValue(MCSymbolRefExpr::
1299cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                              Create(Stubs[i].second.getPointer(),
1300cebae36f57456fe6b0e13726acd1e0250654f02dBill Wendling                                     OutContext),
1301becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling                              4/*size*/, 0/*addrspace*/);
1302becd83e3f4eb996f8e43189ce482267b3b8351a8Bill Wendling      }
1303cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling
1304cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      Stubs.clear();
1305cf6f28d84af09b38e96307007cd93760a7ca42d7Bill Wendling      OutStreamer.AddBlankLine();
1306ae94e594164b193236002516970aeec4c4574768Evan Cheng    }
1307ae94e594164b193236002516970aeec4c4574768Evan Cheng
1308a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // Funny Darwin hack: This flag tells the linker that no global symbols
1309a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // contain code that falls through to other global symbols (e.g. the obvious
1310a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // implementation of multiple entry points).  If this doesn't occur, the
1311a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // linker can safely perform dead code stripping.  Since LLVM never
1312a8e2989ece6dc46df59b0768184028257f913843Evan Cheng    // generates code that does this, it is always safe to set.
1313a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner    OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
1314b01c4bbb4573e0007444e218b683840e4519e0c8Rafael Espindola  }
13157bc59bc3952ad7842b1e079753deb32217a768a3Rafael Espindola}
13160bd89712c03c59ea43ce37763685e7f7c0bdd977Anton Korobeynikov
131797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner//===----------------------------------------------------------------------===//
131897f06937449c593a248dbbb1365e6ae408fb9decChris Lattner
131997f06937449c593a248dbbb1365e6ae408fb9decChris Lattnervoid ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
132096bc2173bb4909be0058e4eb2171f37a66e361ddChris Lattner  ARMMCInstLower MCInstLowering(OutContext, *Mang, *this);
132197f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  switch (MI->getOpcode()) {
1322c6b8a9920787505468931e56696cef1245e25913Chris Lattner  case ARM::t2MOVi32imm:
1323c6b8a9920787505468931e56696cef1245e25913Chris Lattner    assert(0 && "Should be lowered by thumb2it pass");
13244d1522234192704f45dfd2527c2913fa60be616eChris Lattner  default: break;
13254d1522234192704f45dfd2527c2913fa60be616eChris Lattner  case ARM::PICADD: { // FIXME: Remove asm string from td file.
13264d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This is a pseudo op for a label + instruction sequence, which looks like:
13274d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // LPC0:
13284d1522234192704f45dfd2527c2913fa60be616eChris Lattner    //     add r0, pc, r0
13294d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // This adds the address of LPC0 to r0.
1330b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
13314d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // Emit the label.
13324d1522234192704f45dfd2527c2913fa60be616eChris Lattner    // FIXME: MOVE TO SHARED PLACE.
1333a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned Id = (unsigned)MI->getOperand(2).getImm();
13347c5b021793e8c8184c655040ea5e169b55c55063Chris Lattner    const char *Prefix = MAI->getPrivateGlobalPrefix();
13359b97a73dedf736e14b04a3d1a153f10d25b2507bChris Lattner    MCSymbol *Label =OutContext.GetOrCreateSymbol(Twine(Prefix)
1336e7e0d62efda2445b735052ca45bd74fb002e34c3Evan Cheng                         + "PC" + Twine(getFunctionNumber()) + "_" + Twine(Id));
13377c5b021793e8c8184c655040ea5e169b55c55063Chris Lattner    OutStreamer.EmitLabel(Label);
1338b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1339b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1340f3f09527e6484143fcdef2ddfef0b2f016881e36Jim Grosbach    // Form and emit the add.
13414d1522234192704f45dfd2527c2913fa60be616eChris Lattner    MCInst AddInst;
13424d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.setOpcode(ARM::ADDrr);
13434d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
13444d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
13454d1522234192704f45dfd2527c2913fa60be616eChris Lattner    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
13465b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add predicate operands.
13475b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
13485b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
13495b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    // Add 's' bit operand (always reg0 for this)
13505b46d62c4459dbfd56bb6ac650a271cd02365092Jim Grosbach    AddInst.addOperand(MCOperand::CreateReg(0));
1351850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner    OutStreamer.EmitInstruction(AddInst);
13524d1522234192704f45dfd2527c2913fa60be616eChris Lattner    return;
1353b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach  }
1354b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach  case ARM::PICLDR: {
1355b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // This is a pseudo op for a label + instruction sequence, which looks like:
1356b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // LPC0:
1357b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    //     ldr r0, [pc, r0]
1358b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // The LCP0 label is referenced by a constant pool entry in order to get
1359b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // a PC-relative address at the ldr instruction.
1360b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1361b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Emit the label.
1362b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // FIXME: MOVE TO SHARED PLACE.
1363b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    unsigned Id = (unsigned)MI->getOperand(2).getImm();
1364b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    const char *Prefix = MAI->getPrivateGlobalPrefix();
1365b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    MCSymbol *Label =OutContext.GetOrCreateSymbol(Twine(Prefix)
1366b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach                         + "PC" + Twine(getFunctionNumber()) + "_" + Twine(Id));
1367b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    OutStreamer.EmitLabel(Label);
1368b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1369b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Form and emit the load
1370b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    MCInst LdrInst;
1371b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    LdrInst.setOpcode(ARM::LDR);
1372b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    LdrInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1373b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    LdrInst.addOperand(MCOperand::CreateReg(ARM::PC));
1374b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    LdrInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1375b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    LdrInst.addOperand(MCOperand::CreateImm(0));
1376b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    // Add predicate operands.
1377b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    LdrInst.addOperand(MCOperand::CreateImm(MI->getOperand(3).getImm()));
1378b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    LdrInst.addOperand(MCOperand::CreateReg(MI->getOperand(4).getReg()));
1379b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    OutStreamer.EmitInstruction(LdrInst);
1380b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach
1381b74ca9d63104c94b800f2763a654d19f3eb30304Jim Grosbach    return;
13824d1522234192704f45dfd2527c2913fa60be616eChris Lattner  }
1383a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner  case ARM::CONSTPOOL_ENTRY: { // FIXME: Remove asm string from td file.
1384a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
1385a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// in the function.  The first operand is the ID# for this instruction, the
1386a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// second is the index into the MachineConstantPool that this is, the third
1387a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    /// is the size in bytes of this constant pool entry.
1388a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
1389a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    unsigned CPIdx   = (unsigned)MI->getOperand(1).getIndex();
1390a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
1391a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    EmitAlignment(2);
13921b46f433e02155daba8ed3b1269c86ce63c9713bChris Lattner    OutStreamer.EmitLabel(GetCPISymbol(LabelId));
1393a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner
1394a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
1395a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    if (MCPE.isMachineConstantPoolEntry())
1396a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
1397a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    else
1398a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner      EmitGlobalConstant(MCPE.Val.ConstVal);
1399b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1400a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner    return;
1401a70e644820db9c58f201bd27ed3c28f81261a0d9Chris Lattner  }
1402017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner  case ARM::MOVi2pieces: { // FIXME: Remove asmstring from td file.
1403017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    // This is a hack that lowers as a two instruction sequence.
1404017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned DstReg = MI->getOperand(0).getReg();
1405017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
1406017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner
1407017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(ImmVal);
1408017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    unsigned SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(ImmVal);
1409b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1410017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    {
1411017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      MCInst TmpInst;
1412017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.setOpcode(ARM::MOVi);
1413017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));
1414017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(SOImmValV1));
1415b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1416017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      // Predicate.
1417017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1418017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1419233917c07282564351439df8e7a9c83c9d6c459eChris Lattner
1420233917c07282564351439df8e7a9c83c9d6c459eChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out
1421850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
1422017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    }
1423017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner
1424017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    {
1425017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      MCInst TmpInst;
1426017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.setOpcode(ARM::ORRri);
1427017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // dstreg
1428017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // inreg
1429017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(SOImmValV2)); // so_imm
1430017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      // Predicate.
1431017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1432017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1433b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1434017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner      TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out
1435850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
1436017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner    }
1437b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach    return;
1438017d9478d52e56fd20db29eb40e0665cce9f094cChris Lattner  }
1439161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner  case ARM::MOVi32imm: { // FIXME: Remove asmstring from td file.
1440161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    // This is a hack that lowers as a two instruction sequence.
1441161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    unsigned DstReg = MI->getOperand(0).getReg();
144218c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    const MachineOperand &MO = MI->getOperand(1);
144318c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    MCOperand V1, V2;
144418c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    if (MO.isImm()) {
144518c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
144618c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V1 = MCOperand::CreateImm(ImmVal & 65535);
144718c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V2 = MCOperand::CreateImm(ImmVal >> 16);
144818c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    } else if (MO.isGlobal()) {
144918c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      MCSymbol *Symbol = MCInstLowering.GetGlobalAddressSymbol(MO);
145018c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      const MCSymbolRefExpr *SymRef1 =
14513472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        MCSymbolRefExpr::Create(Symbol,
14523472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands                                MCSymbolRefExpr::VK_ARM_LO16, OutContext);
145318c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      const MCSymbolRefExpr *SymRef2 =
14543472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands        MCSymbolRefExpr::Create(Symbol,
14553472766f9eb7d66f234c390ce1b3a8b76f0ee9ceDuncan Sands                                MCSymbolRefExpr::VK_ARM_HI16, OutContext);
145618c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V1 = MCOperand::CreateExpr(SymRef1);
145718c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      V2 = MCOperand::CreateExpr(SymRef2);
145818c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    } else {
145918c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      MI->dump();
146018c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      llvm_unreachable("cannot handle this operand");
146118c1021ec108722506125926087b1e5fcfb28046Rafael Espindola    }
146218c1021ec108722506125926087b1e5fcfb28046Rafael Espindola
1463161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    {
1464161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      MCInst TmpInst;
1465161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.setOpcode(ARM::MOVi16);
1466161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
146718c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      TmpInst.addOperand(V1); // lower16(imm)
1468b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1469161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      // Predicate.
1470161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1471161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1472b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1473850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
1474161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    }
1475b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1476161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    {
1477161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      MCInst TmpInst;
1478161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.setOpcode(ARM::MOVTi16);
1479161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
1480161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // srcreg
148118c1021ec108722506125926087b1e5fcfb28046Rafael Espindola      TmpInst.addOperand(V2);   // upper16(imm)
1482b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1483161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      // Predicate.
1484161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1485161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner      TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1486b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1487850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner      OutStreamer.EmitInstruction(TmpInst);
1488161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    }
1489b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
1490161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner    return;
1491161dcbf79955ed11b6760fda59f1e203380d27c8Chris Lattner  }
149297f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  }
1493b0739b78332275906cd5ace2ae0d65a29135667bJim Grosbach
149497f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  MCInst TmpInst;
149597f06937449c593a248dbbb1365e6ae408fb9decChris Lattner  MCInstLowering.Lower(MI, TmpInst);
1496850d2e2a1b58ea30abed10ca955259d60d07d97aChris Lattner  OutStreamer.EmitInstruction(TmpInst);
149797f06937449c593a248dbbb1365e6ae408fb9decChris Lattner}
14982685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
14992685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
15002685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Target Registry Stuff
15012685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar//===----------------------------------------------------------------------===//
15022685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
15032685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarstatic MCInstPrinter *createARMMCInstPrinter(const Target &T,
15042685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar                                             unsigned SyntaxVariant,
1505d374087be5360a353a4239a155b1227057145f48Chris Lattner                                             const MCAsmInfo &MAI) {
15062685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  if (SyntaxVariant == 0)
1507d374087be5360a353a4239a155b1227057145f48Chris Lattner    return new ARMInstPrinter(MAI, false);
15082685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  return 0;
15092685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
15102685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
15112685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar// Force static initialization.
15122685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbarextern "C" void LLVMInitializeARMAsmPrinter() {
15132685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget);
15142685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget);
15152685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
15162685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter);
15172685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar  TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter);
15182685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar}
15192685a29a8d4ced7791bb671e28f9fe51c74eb3bbDaniel Dunbar
1520