ARM "rrx" shift operands do not have an immediate. PR7790.
[oota-llvm.git] / lib / Target / ARM / ARMAsmPrinter.cpp
1 //===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains a printer that converts from our internal representation
11 // of machine-dependent LLVM code to GAS-format ARM assembly language.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #define DEBUG_TYPE "asm-printer"
16 #include "ARM.h"
17 #include "ARMBuildAttrs.h"
18 #include "ARMAddressingModes.h"
19 #include "ARMConstantPoolValue.h"
20 #include "AsmPrinter/ARMInstPrinter.h"
21 #include "ARMMachineFunctionInfo.h"
22 #include "ARMMCInstLower.h"
23 #include "ARMTargetMachine.h"
24 #include "llvm/Analysis/DebugInfo.h"
25 #include "llvm/Constants.h"
26 #include "llvm/Module.h"
27 #include "llvm/Type.h"
28 #include "llvm/Assembly/Writer.h"
29 #include "llvm/CodeGen/AsmPrinter.h"
30 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
31 #include "llvm/CodeGen/MachineFunctionPass.h"
32 #include "llvm/CodeGen/MachineJumpTableInfo.h"
33 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
34 #include "llvm/MC/MCAsmInfo.h"
35 #include "llvm/MC/MCContext.h"
36 #include "llvm/MC/MCExpr.h"
37 #include "llvm/MC/MCInst.h"
38 #include "llvm/MC/MCSectionMachO.h"
39 #include "llvm/MC/MCStreamer.h"
40 #include "llvm/MC/MCSymbol.h"
41 #include "llvm/Target/Mangler.h"
42 #include "llvm/Target/TargetData.h"
43 #include "llvm/Target/TargetMachine.h"
44 #include "llvm/Target/TargetOptions.h"
45 #include "llvm/Target/TargetRegistry.h"
46 #include "llvm/ADT/SmallPtrSet.h"
47 #include "llvm/ADT/SmallString.h"
48 #include "llvm/ADT/StringExtras.h"
49 #include "llvm/Support/CommandLine.h"
50 #include "llvm/Support/Debug.h"
51 #include "llvm/Support/ErrorHandling.h"
52 #include "llvm/Support/raw_ostream.h"
53 #include <cctype>
54 using namespace llvm;
55
56 static cl::opt<bool>
57 EnableMCInst("enable-arm-mcinst-printer", cl::Hidden,
58             cl::desc("enable experimental asmprinter gunk in the arm backend"));
59
60 namespace llvm {
61   namespace ARM {
62     enum DW_ISA {
63       DW_ISA_ARM_thumb = 1,
64       DW_ISA_ARM_arm = 2
65     };
66   }
67 }
68
69 namespace {
70   class ARMAsmPrinter : public AsmPrinter {
71
72     /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
73     /// make the right decision when printing asm code for different targets.
74     const ARMSubtarget *Subtarget;
75
76     /// AFI - Keep a pointer to ARMFunctionInfo for the current
77     /// MachineFunction.
78     ARMFunctionInfo *AFI;
79
80     /// MCP - Keep a pointer to constantpool entries of the current
81     /// MachineFunction.
82     const MachineConstantPool *MCP;
83
84   public:
85     explicit ARMAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
86       : AsmPrinter(TM, Streamer), AFI(NULL), MCP(NULL) {
87       Subtarget = &TM.getSubtarget<ARMSubtarget>();
88     }
89
90     virtual const char *getPassName() const {
91       return "ARM Assembly Printer";
92     }
93     
94     void printInstructionThroughMCStreamer(const MachineInstr *MI);
95     
96
97     void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O,
98                       const char *Modifier = 0);
99     void printSOImmOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
100     void printSOImm2PartOperand(const MachineInstr *MI, int OpNum,
101                                 raw_ostream &O);
102     void printSORegOperand(const MachineInstr *MI, int OpNum,
103                            raw_ostream &O);
104     void printAddrMode2Operand(const MachineInstr *MI, int OpNum,
105                                raw_ostream &O);
106     void printAddrMode2OffsetOperand(const MachineInstr *MI, int OpNum,
107                                      raw_ostream &O);
108     void printAddrMode3Operand(const MachineInstr *MI, int OpNum,
109                                raw_ostream &O);
110     void printAddrMode3OffsetOperand(const MachineInstr *MI, int OpNum,
111                                      raw_ostream &O);
112     void printAddrMode4Operand(const MachineInstr *MI, int OpNum,raw_ostream &O,
113                                const char *Modifier = 0);
114     void printAddrMode5Operand(const MachineInstr *MI, int OpNum,raw_ostream &O,
115                                const char *Modifier = 0);
116     void printAddrMode6Operand(const MachineInstr *MI, int OpNum,
117                                raw_ostream &O);
118     void printAddrMode6OffsetOperand(const MachineInstr *MI, int OpNum,
119                                      raw_ostream &O);
120     void printAddrModePCOperand(const MachineInstr *MI, int OpNum,
121                                 raw_ostream &O,
122                                 const char *Modifier = 0);
123     void printBitfieldInvMaskImmOperand (const MachineInstr *MI, int OpNum,
124                                          raw_ostream &O);
125
126     void printThumbS4ImmOperand(const MachineInstr *MI, int OpNum,
127                                 raw_ostream &O);
128     void printThumbITMask(const MachineInstr *MI, int OpNum, raw_ostream &O);
129     void printThumbAddrModeRROperand(const MachineInstr *MI, int OpNum,
130                                      raw_ostream &O);
131     void printThumbAddrModeRI5Operand(const MachineInstr *MI, int OpNum,
132                                       raw_ostream &O,
133                                       unsigned Scale);
134     void printThumbAddrModeS1Operand(const MachineInstr *MI, int OpNum,
135                                      raw_ostream &O);
136     void printThumbAddrModeS2Operand(const MachineInstr *MI, int OpNum,
137                                      raw_ostream &O);
138     void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNum,
139                                      raw_ostream &O);
140     void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNum,
141                                      raw_ostream &O);
142
143     void printT2SOOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
144     void printT2AddrModeImm12Operand(const MachineInstr *MI, int OpNum,
145                                      raw_ostream &O);
146     void printT2AddrModeImm8Operand(const MachineInstr *MI, int OpNum,
147                                     raw_ostream &O);
148     void printT2AddrModeImm8s4Operand(const MachineInstr *MI, int OpNum,
149                                       raw_ostream &O);
150     void printT2AddrModeImm8OffsetOperand(const MachineInstr *MI, int OpNum,
151                                           raw_ostream &O);
152     void printT2AddrModeImm8s4OffsetOperand(const MachineInstr *MI, int OpNum,
153                                             raw_ostream &O) {}
154     void printT2AddrModeSoRegOperand(const MachineInstr *MI, int OpNum,
155                                      raw_ostream &O);
156
157     void printCPSOptionOperand(const MachineInstr *MI, int OpNum,
158                                raw_ostream &O) {}
159     void printMSRMaskOperand(const MachineInstr *MI, int OpNum,
160                              raw_ostream &O) {}
161     void printNegZeroOperand(const MachineInstr *MI, int OpNum,
162                              raw_ostream &O) {}
163     void printPredicateOperand(const MachineInstr *MI, int OpNum,
164                                raw_ostream &O);
165     void printMandatoryPredicateOperand(const MachineInstr *MI, int OpNum,
166                                         raw_ostream &O);
167     void printSBitModifierOperand(const MachineInstr *MI, int OpNum,
168                                   raw_ostream &O);
169     void printPCLabel(const MachineInstr *MI, int OpNum,
170                       raw_ostream &O);
171     void printRegisterList(const MachineInstr *MI, int OpNum,
172                            raw_ostream &O);
173     void printCPInstOperand(const MachineInstr *MI, int OpNum,
174                             raw_ostream &O,
175                             const char *Modifier);
176     void printJTBlockOperand(const MachineInstr *MI, int OpNum,
177                              raw_ostream &O);
178     void printJT2BlockOperand(const MachineInstr *MI, int OpNum,
179                               raw_ostream &O);
180     void printTBAddrMode(const MachineInstr *MI, int OpNum,
181                          raw_ostream &O);
182     void printNoHashImmediate(const MachineInstr *MI, int OpNum,
183                               raw_ostream &O);
184     void printVFPf32ImmOperand(const MachineInstr *MI, int OpNum,
185                                raw_ostream &O);
186     void printVFPf64ImmOperand(const MachineInstr *MI, int OpNum,
187                                raw_ostream &O);
188     void printNEONModImmOperand(const MachineInstr *MI, int OpNum,
189                                 raw_ostream &O);
190
191     virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
192                                  unsigned AsmVariant, const char *ExtraCode,
193                                  raw_ostream &O);
194     virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
195                                        unsigned AsmVariant,
196                                        const char *ExtraCode, raw_ostream &O);
197
198     void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen
199     static const char *getRegisterName(unsigned RegNo);
200
201     virtual void EmitInstruction(const MachineInstr *MI);
202     bool runOnMachineFunction(MachineFunction &F);
203     
204     virtual void EmitConstantPool() {} // we emit constant pools customly!
205     virtual void EmitFunctionEntryLabel();
206     void EmitStartOfAsmFile(Module &M);
207     void EmitEndOfAsmFile(Module &M);
208
209     MachineLocation getDebugValueLocation(const MachineInstr *MI) const {
210       MachineLocation Location;
211       assert (MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
212       // Frame address.  Currently handles register +- offset only.
213       if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm())
214         Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
215       else {
216         DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
217       }
218       return Location;
219     }
220
221     virtual unsigned getISAEncoding() {
222       // ARM/Darwin adds ISA to the DWARF info for each function.
223       if (!Subtarget->isTargetDarwin())
224         return 0;
225       return Subtarget->isThumb() ?
226         llvm::ARM::DW_ISA_ARM_thumb : llvm::ARM::DW_ISA_ARM_arm;
227     }
228
229     MCSymbol *GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
230                                           const MachineBasicBlock *MBB) const;
231     MCSymbol *GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const;
232
233     /// EmitMachineConstantPoolValue - Print a machine constantpool value to
234     /// the .s file.
235     virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
236       SmallString<128> Str;
237       raw_svector_ostream OS(Str);
238       EmitMachineConstantPoolValue(MCPV, OS);
239       OutStreamer.EmitRawText(OS.str());
240     }
241     
242     void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV,
243                                       raw_ostream &O) {
244       switch (TM.getTargetData()->getTypeAllocSize(MCPV->getType())) {
245       case 1: O << MAI->getData8bitsDirective(0); break;
246       case 2: O << MAI->getData16bitsDirective(0); break;
247       case 4: O << MAI->getData32bitsDirective(0); break;
248       default: assert(0 && "Unknown CPV size");
249       }
250
251       ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
252
253       if (ACPV->isLSDA()) {
254         O << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber();
255       } else if (ACPV->isBlockAddress()) {
256         O << *GetBlockAddressSymbol(ACPV->getBlockAddress());
257       } else if (ACPV->isGlobalValue()) {
258         const GlobalValue *GV = ACPV->getGV();
259         bool isIndirect = Subtarget->isTargetDarwin() &&
260           Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
261         if (!isIndirect)
262           O << *Mang->getSymbol(GV);
263         else {
264           // FIXME: Remove this when Darwin transition to @GOT like syntax.
265           MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
266           O << *Sym;
267           
268           MachineModuleInfoMachO &MMIMachO =
269             MMI->getObjFileInfo<MachineModuleInfoMachO>();
270           MachineModuleInfoImpl::StubValueTy &StubSym =
271             GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(Sym) :
272                                         MMIMachO.getGVStubEntry(Sym);
273           if (StubSym.getPointer() == 0)
274             StubSym = MachineModuleInfoImpl::
275               StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
276         }
277       } else {
278         assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
279         O << *GetExternalSymbolSymbol(ACPV->getSymbol());
280       }
281
282       if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
283       if (ACPV->getPCAdjustment() != 0) {
284         O << "-(" << MAI->getPrivateGlobalPrefix() << "PC"
285           << getFunctionNumber() << "_"  << ACPV->getLabelId()
286           << "+" << (unsigned)ACPV->getPCAdjustment();
287          if (ACPV->mustAddCurrentAddress())
288            O << "-.";
289          O << ')';
290       }
291     }
292   };
293 } // end of anonymous namespace
294
295 #include "ARMGenAsmWriter.inc"
296
297 void ARMAsmPrinter::EmitFunctionEntryLabel() {
298   if (AFI->isThumbFunction()) {
299     OutStreamer.EmitRawText(StringRef("\t.code\t16"));
300     if (!Subtarget->isTargetDarwin())
301       OutStreamer.EmitRawText(StringRef("\t.thumb_func"));
302     else {
303       // This needs to emit to a temporary string to get properly quoted
304       // MCSymbols when they have spaces in them.
305       SmallString<128> Tmp;
306       raw_svector_ostream OS(Tmp);
307       OS << "\t.thumb_func\t" << *CurrentFnSym;
308       OutStreamer.EmitRawText(OS.str());
309     }
310   }
311   
312   OutStreamer.EmitLabel(CurrentFnSym);
313 }
314
315 /// runOnMachineFunction - This uses the printInstruction()
316 /// method to print assembly for each instruction.
317 ///
318 bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
319   AFI = MF.getInfo<ARMFunctionInfo>();
320   MCP = MF.getConstantPool();
321
322   return AsmPrinter::runOnMachineFunction(MF);
323 }
324
325 void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
326                                  raw_ostream &O, const char *Modifier) {
327   const MachineOperand &MO = MI->getOperand(OpNum);
328   unsigned TF = MO.getTargetFlags();
329
330   switch (MO.getType()) {
331   default:
332     assert(0 && "<unknown operand type>");
333   case MachineOperand::MO_Register: {
334     unsigned Reg = MO.getReg();
335     assert(TargetRegisterInfo::isPhysicalRegister(Reg));
336     if (Modifier && strcmp(Modifier, "dregpair") == 0) {
337       unsigned DRegLo = TM.getRegisterInfo()->getSubReg(Reg, ARM::dsub_0);
338       unsigned DRegHi = TM.getRegisterInfo()->getSubReg(Reg, ARM::dsub_1);
339       O << '{'
340         << getRegisterName(DRegLo) << ", " << getRegisterName(DRegHi)
341         << '}';
342     } else if (Modifier && strcmp(Modifier, "lane") == 0) {
343       unsigned RegNum = ARMRegisterInfo::getRegisterNumbering(Reg);
344       unsigned DReg =
345         TM.getRegisterInfo()->getMatchingSuperReg(Reg,
346           RegNum & 1 ? ARM::ssub_1 : ARM::ssub_0, &ARM::DPR_VFP2RegClass);
347       O << getRegisterName(DReg) << '[' << (RegNum & 1) << ']';
348     } else {
349       assert(!MO.getSubReg() && "Subregs should be eliminated!");
350       O << getRegisterName(Reg);
351     }
352     break;
353   }
354   case MachineOperand::MO_Immediate: {
355     int64_t Imm = MO.getImm();
356     O << '#';
357     if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
358         (TF & ARMII::MO_LO16))
359       O << ":lower16:";
360     else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
361              (TF & ARMII::MO_HI16))
362       O << ":upper16:";
363     O << Imm;
364     break;
365   }
366   case MachineOperand::MO_MachineBasicBlock:
367     O << *MO.getMBB()->getSymbol();
368     return;
369   case MachineOperand::MO_GlobalAddress: {
370     bool isCallOp = Modifier && !strcmp(Modifier, "call");
371     const GlobalValue *GV = MO.getGlobal();
372
373     if ((Modifier && strcmp(Modifier, "lo16") == 0) ||
374         (TF & ARMII::MO_LO16))
375       O << ":lower16:";
376     else if ((Modifier && strcmp(Modifier, "hi16") == 0) ||
377              (TF & ARMII::MO_HI16))
378       O << ":upper16:";
379     O << *Mang->getSymbol(GV);
380
381     printOffset(MO.getOffset(), O);
382
383     if (isCallOp && Subtarget->isTargetELF() &&
384         TM.getRelocationModel() == Reloc::PIC_)
385       O << "(PLT)";
386     break;
387   }
388   case MachineOperand::MO_ExternalSymbol: {
389     bool isCallOp = Modifier && !strcmp(Modifier, "call");
390     O << *GetExternalSymbolSymbol(MO.getSymbolName());
391     
392     if (isCallOp && Subtarget->isTargetELF() &&
393         TM.getRelocationModel() == Reloc::PIC_)
394       O << "(PLT)";
395     break;
396   }
397   case MachineOperand::MO_ConstantPoolIndex:
398     O << *GetCPISymbol(MO.getIndex());
399     break;
400   case MachineOperand::MO_JumpTableIndex:
401     O << *GetJTISymbol(MO.getIndex());
402     break;
403   }
404 }
405
406 static void printSOImm(raw_ostream &O, int64_t V, bool VerboseAsm,
407                        const MCAsmInfo *MAI) {
408   // Break it up into two parts that make up a shifter immediate.
409   V = ARM_AM::getSOImmVal(V);
410   assert(V != -1 && "Not a valid so_imm value!");
411
412   unsigned Imm = ARM_AM::getSOImmValImm(V);
413   unsigned Rot = ARM_AM::getSOImmValRot(V);
414
415   // Print low-level immediate formation info, per
416   // A5.1.3: "Data-processing operands - Immediate".
417   if (Rot) {
418     O << "#" << Imm << ", " << Rot;
419     // Pretty printed version.
420     if (VerboseAsm) {
421       O << "\t" << MAI->getCommentString() << ' ';
422       O << (int)ARM_AM::rotr32(Imm, Rot);
423     }
424   } else {
425     O << "#" << Imm;
426   }
427 }
428
429 /// printSOImmOperand - SOImm is 4-bit rotate amount in bits 8-11 with 8-bit
430 /// immediate in bits 0-7.
431 void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum,
432                                       raw_ostream &O) {
433   const MachineOperand &MO = MI->getOperand(OpNum);
434   assert(MO.isImm() && "Not a valid so_imm value!");
435   printSOImm(O, MO.getImm(), isVerbose(), MAI);
436 }
437
438 /// printSOImm2PartOperand - SOImm is broken into two pieces using a 'mov'
439 /// followed by an 'orr' to materialize.
440 void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum,
441                                            raw_ostream &O) {
442   const MachineOperand &MO = MI->getOperand(OpNum);
443   assert(MO.isImm() && "Not a valid so_imm value!");
444   unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImm());
445   unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImm());
446   printSOImm(O, V1, isVerbose(), MAI);
447   O << "\n\torr";
448   printPredicateOperand(MI, 2, O);
449   O << "\t";
450   printOperand(MI, 0, O);
451   O << ", ";
452   printOperand(MI, 0, O);
453   O << ", ";
454   printSOImm(O, V2, isVerbose(), MAI);
455 }
456
457 // so_reg is a 4-operand unit corresponding to register forms of the A5.1
458 // "Addressing Mode 1 - Data-processing operands" forms.  This includes:
459 //    REG 0   0           - e.g. R5
460 //    REG REG 0,SH_OPC    - e.g. R5, ROR R3
461 //    REG 0   IMM,SH_OPC  - e.g. R5, LSL #3
462 void ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op,
463                                       raw_ostream &O) {
464   const MachineOperand &MO1 = MI->getOperand(Op);
465   const MachineOperand &MO2 = MI->getOperand(Op+1);
466   const MachineOperand &MO3 = MI->getOperand(Op+2);
467
468   O << getRegisterName(MO1.getReg());
469
470   // Print the shift opc.
471   ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO3.getImm());
472   O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
473   if (MO2.getReg()) {
474     O << ' ' << getRegisterName(MO2.getReg());
475     assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
476   } else if (ShOpc != ARM_AM::rrx) {
477     O << " #" << ARM_AM::getSORegOffset(MO3.getImm());
478   }
479 }
480
481 void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op,
482                                           raw_ostream &O) {
483   const MachineOperand &MO1 = MI->getOperand(Op);
484   const MachineOperand &MO2 = MI->getOperand(Op+1);
485   const MachineOperand &MO3 = MI->getOperand(Op+2);
486
487   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
488     printOperand(MI, Op, O);
489     return;
490   }
491
492   O << "[" << getRegisterName(MO1.getReg());
493
494   if (!MO2.getReg()) {
495     if (ARM_AM::getAM2Offset(MO3.getImm())) // Don't print +0.
496       O << ", #"
497         << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
498         << ARM_AM::getAM2Offset(MO3.getImm());
499     O << "]";
500     return;
501   }
502
503   O << ", "
504     << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO3.getImm()))
505     << getRegisterName(MO2.getReg());
506
507   if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
508     O << ", "
509       << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
510       << " #" << ShImm;
511   O << "]";
512 }
513
514 void ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op,
515                                                 raw_ostream &O) {
516   const MachineOperand &MO1 = MI->getOperand(Op);
517   const MachineOperand &MO2 = MI->getOperand(Op+1);
518
519   if (!MO1.getReg()) {
520     unsigned ImmOffs = ARM_AM::getAM2Offset(MO2.getImm());
521     O << "#"
522       << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
523       << ImmOffs;
524     return;
525   }
526
527   O << ARM_AM::getAddrOpcStr(ARM_AM::getAM2Op(MO2.getImm()))
528     << getRegisterName(MO1.getReg());
529
530   if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
531     O << ", "
532       << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm()))
533       << " #" << ShImm;
534 }
535
536 void ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op,
537                                           raw_ostream &O) {
538   const MachineOperand &MO1 = MI->getOperand(Op);
539   const MachineOperand &MO2 = MI->getOperand(Op+1);
540   const MachineOperand &MO3 = MI->getOperand(Op+2);
541
542   assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
543   O << "[" << getRegisterName(MO1.getReg());
544
545   if (MO2.getReg()) {
546     O << ", "
547       << (char)ARM_AM::getAM3Op(MO3.getImm())
548       << getRegisterName(MO2.getReg())
549       << "]";
550     return;
551   }
552
553   if (unsigned ImmOffs = ARM_AM::getAM3Offset(MO3.getImm()))
554     O << ", #"
555       << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO3.getImm()))
556       << ImmOffs;
557   O << "]";
558 }
559
560 void ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op,
561                                                 raw_ostream &O){
562   const MachineOperand &MO1 = MI->getOperand(Op);
563   const MachineOperand &MO2 = MI->getOperand(Op+1);
564
565   if (MO1.getReg()) {
566     O << (char)ARM_AM::getAM3Op(MO2.getImm())
567       << getRegisterName(MO1.getReg());
568     return;
569   }
570
571   unsigned ImmOffs = ARM_AM::getAM3Offset(MO2.getImm());
572   O << "#"
573     << ARM_AM::getAddrOpcStr(ARM_AM::getAM3Op(MO2.getImm()))
574     << ImmOffs;
575 }
576
577 void ARMAsmPrinter::printAddrMode4Operand(const MachineInstr *MI, int Op,
578                                           raw_ostream &O,
579                                           const char *Modifier) {
580   const MachineOperand &MO2 = MI->getOperand(Op+1);
581   ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
582   if (Modifier && strcmp(Modifier, "submode") == 0) {
583     O << ARM_AM::getAMSubModeStr(Mode);
584   } else if (Modifier && strcmp(Modifier, "wide") == 0) {
585     ARM_AM::AMSubMode Mode = ARM_AM::getAM4SubMode(MO2.getImm());
586     if (Mode == ARM_AM::ia)
587       O << ".w";
588   } else {
589     printOperand(MI, Op, O);
590   }
591 }
592
593 void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
594                                           raw_ostream &O,
595                                           const char *Modifier) {
596   const MachineOperand &MO1 = MI->getOperand(Op);
597   const MachineOperand &MO2 = MI->getOperand(Op+1);
598
599   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
600     printOperand(MI, Op, O);
601     return;
602   }
603
604   assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
605
606   if (Modifier && strcmp(Modifier, "submode") == 0) {
607     ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MO2.getImm());
608     O << ARM_AM::getAMSubModeStr(Mode);
609     return;
610   } else if (Modifier && strcmp(Modifier, "base") == 0) {
611     // Used for FSTM{D|S} and LSTM{D|S} operations.
612     O << getRegisterName(MO1.getReg());
613     return;
614   }
615
616   O << "[" << getRegisterName(MO1.getReg());
617
618   if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
619     O << ", #"
620       << ARM_AM::getAddrOpcStr(ARM_AM::getAM5Op(MO2.getImm()))
621       << ImmOffs*4;
622   }
623   O << "]";
624 }
625
626 void ARMAsmPrinter::printAddrMode6Operand(const MachineInstr *MI, int Op,
627                                           raw_ostream &O) {
628   const MachineOperand &MO1 = MI->getOperand(Op);
629   const MachineOperand &MO2 = MI->getOperand(Op+1);
630
631   O << "[" << getRegisterName(MO1.getReg());
632   if (MO2.getImm()) {
633     // FIXME: Both darwin as and GNU as violate ARM docs here.
634     O << ", :" << (MO2.getImm() << 3);
635   }
636   O << "]";
637 }
638
639 void ARMAsmPrinter::printAddrMode6OffsetOperand(const MachineInstr *MI, int Op,
640                                                 raw_ostream &O){
641   const MachineOperand &MO = MI->getOperand(Op);
642   if (MO.getReg() == 0)
643     O << "!";
644   else
645     O << ", " << getRegisterName(MO.getReg());
646 }
647
648 void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
649                                            raw_ostream &O,
650                                            const char *Modifier) {
651   if (Modifier && strcmp(Modifier, "label") == 0) {
652     printPCLabel(MI, Op+1, O);
653     return;
654   }
655
656   const MachineOperand &MO1 = MI->getOperand(Op);
657   assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
658   O << "[pc, " << getRegisterName(MO1.getReg()) << "]";
659 }
660
661 void
662 ARMAsmPrinter::printBitfieldInvMaskImmOperand(const MachineInstr *MI, int Op,
663                                               raw_ostream &O) {
664   const MachineOperand &MO = MI->getOperand(Op);
665   uint32_t v = ~MO.getImm();
666   int32_t lsb = CountTrailingZeros_32(v);
667   int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb;
668   assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
669   O << "#" << lsb << ", #" << width;
670 }
671
672 //===--------------------------------------------------------------------===//
673
674 void ARMAsmPrinter::printThumbS4ImmOperand(const MachineInstr *MI, int Op,
675                                            raw_ostream &O) {
676   O << "#" <<  MI->getOperand(Op).getImm() * 4;
677 }
678
679 void
680 ARMAsmPrinter::printThumbITMask(const MachineInstr *MI, int Op,
681                                 raw_ostream &O) {
682   // (3 - the number of trailing zeros) is the number of then / else.
683   unsigned Mask = MI->getOperand(Op).getImm();
684   unsigned CondBit0 = Mask >> 4 & 1;
685   unsigned NumTZ = CountTrailingZeros_32(Mask);
686   assert(NumTZ <= 3 && "Invalid IT mask!");
687   for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
688     bool T = ((Mask >> Pos) & 1) == CondBit0;
689     if (T)
690       O << 't';
691     else
692       O << 'e';
693   }
694 }
695
696 void
697 ARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op,
698                                            raw_ostream &O) {
699   const MachineOperand &MO1 = MI->getOperand(Op);
700   const MachineOperand &MO2 = MI->getOperand(Op+1);
701   O << "[" << getRegisterName(MO1.getReg());
702   O << ", " << getRegisterName(MO2.getReg()) << "]";
703 }
704
705 void
706 ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
707                                             raw_ostream &O,
708                                             unsigned Scale) {
709   const MachineOperand &MO1 = MI->getOperand(Op);
710   const MachineOperand &MO2 = MI->getOperand(Op+1);
711   const MachineOperand &MO3 = MI->getOperand(Op+2);
712
713   if (!MO1.isReg()) {   // FIXME: This is for CP entries, but isn't right.
714     printOperand(MI, Op, O);
715     return;
716   }
717
718   O << "[" << getRegisterName(MO1.getReg());
719   if (MO3.getReg())
720     O << ", " << getRegisterName(MO3.getReg());
721   else if (unsigned ImmOffs = MO2.getImm())
722     O << ", #" << ImmOffs * Scale;
723   O << "]";
724 }
725
726 void
727 ARMAsmPrinter::printThumbAddrModeS1Operand(const MachineInstr *MI, int Op,
728                                            raw_ostream &O) {
729   printThumbAddrModeRI5Operand(MI, Op, O, 1);
730 }
731 void
732 ARMAsmPrinter::printThumbAddrModeS2Operand(const MachineInstr *MI, int Op,
733                                            raw_ostream &O) {
734   printThumbAddrModeRI5Operand(MI, Op, O, 2);
735 }
736 void
737 ARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op,
738                                            raw_ostream &O) {
739   printThumbAddrModeRI5Operand(MI, Op, O, 4);
740 }
741
742 void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op,
743                                                 raw_ostream &O) {
744   const MachineOperand &MO1 = MI->getOperand(Op);
745   const MachineOperand &MO2 = MI->getOperand(Op+1);
746   O << "[" << getRegisterName(MO1.getReg());
747   if (unsigned ImmOffs = MO2.getImm())
748     O << ", #" << ImmOffs*4;
749   O << "]";
750 }
751
752 //===--------------------------------------------------------------------===//
753
754 // Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
755 // register with shift forms.
756 // REG 0   0           - e.g. R5
757 // REG IMM, SH_OPC     - e.g. R5, LSL #3
758 void ARMAsmPrinter::printT2SOOperand(const MachineInstr *MI, int OpNum,
759                                      raw_ostream &O) {
760   const MachineOperand &MO1 = MI->getOperand(OpNum);
761   const MachineOperand &MO2 = MI->getOperand(OpNum+1);
762
763   unsigned Reg = MO1.getReg();
764   assert(TargetRegisterInfo::isPhysicalRegister(Reg));
765   O << getRegisterName(Reg);
766
767   // Print the shift opc.
768   assert(MO2.isImm() && "Not a valid t2_so_reg value!");
769   ARM_AM::ShiftOpc ShOpc = ARM_AM::getSORegShOp(MO2.getImm());
770   O << ", " << ARM_AM::getShiftOpcStr(ShOpc);
771   if (ShOpc != ARM_AM::rrx)
772     O << " #" << ARM_AM::getSORegOffset(MO2.getImm());
773 }
774
775 void ARMAsmPrinter::printT2AddrModeImm12Operand(const MachineInstr *MI,
776                                                 int OpNum,
777                                                 raw_ostream &O) {
778   const MachineOperand &MO1 = MI->getOperand(OpNum);
779   const MachineOperand &MO2 = MI->getOperand(OpNum+1);
780
781   O << "[" << getRegisterName(MO1.getReg());
782
783   unsigned OffImm = MO2.getImm();
784   if (OffImm)  // Don't print +0.
785     O << ", #" << OffImm;
786   O << "]";
787 }
788
789 void ARMAsmPrinter::printT2AddrModeImm8Operand(const MachineInstr *MI,
790                                                int OpNum,
791                                                raw_ostream &O) {
792   const MachineOperand &MO1 = MI->getOperand(OpNum);
793   const MachineOperand &MO2 = MI->getOperand(OpNum+1);
794
795   O << "[" << getRegisterName(MO1.getReg());
796
797   int32_t OffImm = (int32_t)MO2.getImm();
798   // Don't print +0.
799   if (OffImm < 0)
800     O << ", #-" << -OffImm;
801   else if (OffImm > 0)
802     O << ", #" << OffImm;
803   O << "]";
804 }
805
806 void ARMAsmPrinter::printT2AddrModeImm8s4Operand(const MachineInstr *MI,
807                                                  int OpNum,
808                                                  raw_ostream &O) {
809   const MachineOperand &MO1 = MI->getOperand(OpNum);
810   const MachineOperand &MO2 = MI->getOperand(OpNum+1);
811
812   O << "[" << getRegisterName(MO1.getReg());
813
814   int32_t OffImm = (int32_t)MO2.getImm() / 4;
815   // Don't print +0.
816   if (OffImm < 0)
817     O << ", #-" << -OffImm * 4;
818   else if (OffImm > 0)
819     O << ", #" << OffImm * 4;
820   O << "]";
821 }
822
823 void ARMAsmPrinter::printT2AddrModeImm8OffsetOperand(const MachineInstr *MI,
824                                                      int OpNum,
825                                                      raw_ostream &O) {
826   const MachineOperand &MO1 = MI->getOperand(OpNum);
827   int32_t OffImm = (int32_t)MO1.getImm();
828   // Don't print +0.
829   if (OffImm < 0)
830     O << "#-" << -OffImm;
831   else if (OffImm > 0)
832     O << "#" << OffImm;
833 }
834
835 void ARMAsmPrinter::printT2AddrModeSoRegOperand(const MachineInstr *MI,
836                                                 int OpNum,
837                                                 raw_ostream &O) {
838   const MachineOperand &MO1 = MI->getOperand(OpNum);
839   const MachineOperand &MO2 = MI->getOperand(OpNum+1);
840   const MachineOperand &MO3 = MI->getOperand(OpNum+2);
841
842   O << "[" << getRegisterName(MO1.getReg());
843
844   assert(MO2.getReg() && "Invalid so_reg load / store address!");
845   O << ", " << getRegisterName(MO2.getReg());
846
847   unsigned ShAmt = MO3.getImm();
848   if (ShAmt) {
849     assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
850     O << ", lsl #" << ShAmt;
851   }
852   O << "]";
853 }
854
855
856 //===--------------------------------------------------------------------===//
857
858 void ARMAsmPrinter::printPredicateOperand(const MachineInstr *MI, int OpNum,
859                                           raw_ostream &O) {
860   ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
861   if (CC != ARMCC::AL)
862     O << ARMCondCodeToString(CC);
863 }
864
865 void ARMAsmPrinter::printMandatoryPredicateOperand(const MachineInstr *MI,
866                                                    int OpNum,
867                                                    raw_ostream &O) {
868   ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(OpNum).getImm();
869   O << ARMCondCodeToString(CC);
870 }
871
872 void ARMAsmPrinter::printSBitModifierOperand(const MachineInstr *MI, int OpNum,
873                                              raw_ostream &O){
874   unsigned Reg = MI->getOperand(OpNum).getReg();
875   if (Reg) {
876     assert(Reg == ARM::CPSR && "Expect ARM CPSR register!");
877     O << 's';
878   }
879 }
880
881 void ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int OpNum,
882                                  raw_ostream &O) {
883   int Id = (int)MI->getOperand(OpNum).getImm();
884   O << MAI->getPrivateGlobalPrefix()
885     << "PC" << getFunctionNumber() << "_" << Id;
886 }
887
888 void ARMAsmPrinter::printRegisterList(const MachineInstr *MI, int OpNum,
889                                       raw_ostream &O) {
890   O << "{";
891   for (unsigned i = OpNum, e = MI->getNumOperands(); i != e; ++i) {
892     if (MI->getOperand(i).isImplicit())
893       continue;
894     if ((int)i != OpNum) O << ", ";
895     printOperand(MI, i, O);
896   }
897   O << "}";
898 }
899
900 void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNum,
901                                        raw_ostream &O, const char *Modifier) {
902   assert(Modifier && "This operand only works with a modifier!");
903   // There are two aspects to a CONSTANTPOOL_ENTRY operand, the label and the
904   // data itself.
905   if (!strcmp(Modifier, "label")) {
906     unsigned ID = MI->getOperand(OpNum).getImm();
907     OutStreamer.EmitLabel(GetCPISymbol(ID));
908   } else {
909     assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
910     unsigned CPI = MI->getOperand(OpNum).getIndex();
911
912     const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPI];
913
914     if (MCPE.isMachineConstantPoolEntry()) {
915       EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
916     } else {
917       EmitGlobalConstant(MCPE.Val.ConstVal);
918     }
919   }
920 }
921
922 MCSymbol *ARMAsmPrinter::
923 GetARMSetPICJumpTableLabel2(unsigned uid, unsigned uid2,
924                             const MachineBasicBlock *MBB) const {
925   SmallString<60> Name;
926   raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix()
927     << getFunctionNumber() << '_' << uid << '_' << uid2
928     << "_set_" << MBB->getNumber();
929   return OutContext.GetOrCreateSymbol(Name.str());
930 }
931
932 MCSymbol *ARMAsmPrinter::
933 GetARMJTIPICJumpTableLabel2(unsigned uid, unsigned uid2) const {
934   SmallString<60> Name;
935   raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "JTI"
936     << getFunctionNumber() << '_' << uid << '_' << uid2;
937   return OutContext.GetOrCreateSymbol(Name.str());
938 }
939
940 void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum,
941                                         raw_ostream &O) {
942   assert(!Subtarget->isThumb2() && "Thumb2 should use double-jump jumptables!");
943
944   const MachineOperand &MO1 = MI->getOperand(OpNum);
945   const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
946   
947   unsigned JTI = MO1.getIndex();
948   MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
949   // Can't use EmitLabel until instprinter happens, label comes out in the wrong
950   // order.
951   O << "\n" << *JTISymbol << ":\n";
952
953   const char *JTEntryDirective = MAI->getData32bitsDirective();
954
955   const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
956   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
957   const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
958   bool UseSet= MAI->hasSetDirective() && TM.getRelocationModel() == Reloc::PIC_;
959   SmallPtrSet<MachineBasicBlock*, 8> JTSets;
960   for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
961     MachineBasicBlock *MBB = JTBBs[i];
962     bool isNew = JTSets.insert(MBB);
963
964     if (UseSet && isNew) {
965       O << "\t.set\t"
966         << *GetARMSetPICJumpTableLabel2(JTI, MO2.getImm(), MBB) << ','
967         << *MBB->getSymbol() << '-' << *JTISymbol << '\n';
968     }
969
970     O << JTEntryDirective << ' ';
971     if (UseSet)
972       O << *GetARMSetPICJumpTableLabel2(JTI, MO2.getImm(), MBB);
973     else if (TM.getRelocationModel() == Reloc::PIC_)
974       O << *MBB->getSymbol() << '-' << *JTISymbol;
975     else
976       O << *MBB->getSymbol();
977
978     if (i != e-1)
979       O << '\n';
980   }
981 }
982
983 void ARMAsmPrinter::printJT2BlockOperand(const MachineInstr *MI, int OpNum,
984                                          raw_ostream &O) {
985   const MachineOperand &MO1 = MI->getOperand(OpNum);
986   const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
987   unsigned JTI = MO1.getIndex();
988   
989   MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
990   
991   // Can't use EmitLabel until instprinter happens, label comes out in the wrong
992   // order.
993   O << "\n" << *JTISymbol << ":\n";
994
995   const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
996   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
997   const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
998   bool ByteOffset = false, HalfWordOffset = false;
999   if (MI->getOpcode() == ARM::t2TBB)
1000     ByteOffset = true;
1001   else if (MI->getOpcode() == ARM::t2TBH)
1002     HalfWordOffset = true;
1003
1004   for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
1005     MachineBasicBlock *MBB = JTBBs[i];
1006     if (ByteOffset)
1007       O << MAI->getData8bitsDirective();
1008     else if (HalfWordOffset)
1009       O << MAI->getData16bitsDirective();
1010     
1011     if (ByteOffset || HalfWordOffset)
1012       O << '(' << *MBB->getSymbol() << "-" << *JTISymbol << ")/2";
1013     else
1014       O << "\tb.w " << *MBB->getSymbol();
1015
1016     if (i != e-1)
1017       O << '\n';
1018   }
1019 }
1020
1021 void ARMAsmPrinter::printTBAddrMode(const MachineInstr *MI, int OpNum,
1022                                     raw_ostream &O) {
1023   O << "[pc, " << getRegisterName(MI->getOperand(OpNum).getReg());
1024   if (MI->getOpcode() == ARM::t2TBH)
1025     O << ", lsl #1";
1026   O << ']';
1027 }
1028
1029 void ARMAsmPrinter::printNoHashImmediate(const MachineInstr *MI, int OpNum,
1030                                          raw_ostream &O) {
1031   O << MI->getOperand(OpNum).getImm();
1032 }
1033
1034 void ARMAsmPrinter::printVFPf32ImmOperand(const MachineInstr *MI, int OpNum,
1035                                           raw_ostream &O) {
1036   const ConstantFP *FP = MI->getOperand(OpNum).getFPImm();
1037   O << '#' << FP->getValueAPF().convertToFloat();
1038   if (isVerbose()) {
1039     O << "\t\t" << MAI->getCommentString() << ' ';
1040     WriteAsOperand(O, FP, /*PrintType=*/false);
1041   }
1042 }
1043
1044 void ARMAsmPrinter::printVFPf64ImmOperand(const MachineInstr *MI, int OpNum,
1045                                           raw_ostream &O) {
1046   const ConstantFP *FP = MI->getOperand(OpNum).getFPImm();
1047   O << '#' << FP->getValueAPF().convertToDouble();
1048   if (isVerbose()) {
1049     O << "\t\t" << MAI->getCommentString() << ' ';
1050     WriteAsOperand(O, FP, /*PrintType=*/false);
1051   }
1052 }
1053
1054 void ARMAsmPrinter::printNEONModImmOperand(const MachineInstr *MI, int OpNum,
1055                                            raw_ostream &O) {
1056   unsigned EncodedImm = MI->getOperand(OpNum).getImm();
1057   unsigned EltBits;
1058   uint64_t Val = ARM_AM::decodeNEONModImm(EncodedImm, EltBits);
1059   O << "#0x" << utohexstr(Val);
1060 }
1061
1062 bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
1063                                     unsigned AsmVariant, const char *ExtraCode,
1064                                     raw_ostream &O) {
1065   // Does this asm operand have a single letter operand modifier?
1066   if (ExtraCode && ExtraCode[0]) {
1067     if (ExtraCode[1] != 0) return true; // Unknown modifier.
1068
1069     switch (ExtraCode[0]) {
1070     default: return true;  // Unknown modifier.
1071     case 'a': // Print as a memory address.
1072       if (MI->getOperand(OpNum).isReg()) {
1073         O << "[" << getRegisterName(MI->getOperand(OpNum).getReg()) << "]";
1074         return false;
1075       }
1076       // Fallthrough
1077     case 'c': // Don't print "#" before an immediate operand.
1078       if (!MI->getOperand(OpNum).isImm())
1079         return true;
1080       printNoHashImmediate(MI, OpNum, O);
1081       return false;
1082     case 'P': // Print a VFP double precision register.
1083     case 'q': // Print a NEON quad precision register.
1084       printOperand(MI, OpNum, O);
1085       return false;
1086     case 'Q':
1087     case 'R':
1088     case 'H':
1089       report_fatal_error("llvm does not support 'Q', 'R', and 'H' modifiers!");
1090       return true;
1091     }
1092   }
1093
1094   printOperand(MI, OpNum, O);
1095   return false;
1096 }
1097
1098 bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
1099                                           unsigned OpNum, unsigned AsmVariant,
1100                                           const char *ExtraCode,
1101                                           raw_ostream &O) {
1102   if (ExtraCode && ExtraCode[0])
1103     return true; // Unknown modifier.
1104
1105   const MachineOperand &MO = MI->getOperand(OpNum);
1106   assert(MO.isReg() && "unexpected inline asm memory operand");
1107   O << "[" << getRegisterName(MO.getReg()) << "]";
1108   return false;
1109 }
1110
1111 void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
1112   if (EnableMCInst) {
1113     printInstructionThroughMCStreamer(MI);
1114     return;
1115   }
1116   
1117   if (MI->getOpcode() == ARM::CONSTPOOL_ENTRY)
1118     EmitAlignment(2);
1119   
1120   SmallString<128> Str;
1121   raw_svector_ostream OS(Str);
1122   if (MI->getOpcode() == ARM::DBG_VALUE) {
1123     unsigned NOps = MI->getNumOperands();
1124     assert(NOps==4);
1125     OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
1126     // cast away const; DIetc do not take const operands for some reason.
1127     DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata()));
1128     OS << V.getName();
1129     OS << " <- ";
1130     // Frame address.  Currently handles register +- offset only.
1131     assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
1132     OS << '['; printOperand(MI, 0, OS); OS << '+'; printOperand(MI, 1, OS);
1133     OS << ']';
1134     OS << "+";
1135     printOperand(MI, NOps-2, OS);
1136     OutStreamer.EmitRawText(OS.str());
1137     return;
1138   }
1139
1140   printInstruction(MI, OS);
1141   OutStreamer.EmitRawText(OS.str());
1142   
1143   // Make sure the instruction that follows TBB is 2-byte aligned.
1144   // FIXME: Constant island pass should insert an "ALIGN" instruction instead.
1145   if (MI->getOpcode() == ARM::t2TBB)
1146     EmitAlignment(1);
1147 }
1148
1149 void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
1150   if (Subtarget->isTargetDarwin()) {
1151     Reloc::Model RelocM = TM.getRelocationModel();
1152     if (RelocM == Reloc::PIC_ || RelocM == Reloc::DynamicNoPIC) {
1153       // Declare all the text sections up front (before the DWARF sections
1154       // emitted by AsmPrinter::doInitialization) so the assembler will keep
1155       // them together at the beginning of the object file.  This helps
1156       // avoid out-of-range branches that are due a fundamental limitation of
1157       // the way symbol offsets are encoded with the current Darwin ARM
1158       // relocations.
1159       const TargetLoweringObjectFileMachO &TLOFMacho = 
1160         static_cast<const TargetLoweringObjectFileMachO &>(
1161           getObjFileLowering());
1162       OutStreamer.SwitchSection(TLOFMacho.getTextSection());
1163       OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection());
1164       OutStreamer.SwitchSection(TLOFMacho.getConstTextCoalSection());
1165       if (RelocM == Reloc::DynamicNoPIC) {
1166         const MCSection *sect =
1167           OutContext.getMachOSection("__TEXT", "__symbol_stub4",
1168                                      MCSectionMachO::S_SYMBOL_STUBS,
1169                                      12, SectionKind::getText());
1170         OutStreamer.SwitchSection(sect);
1171       } else {
1172         const MCSection *sect =
1173           OutContext.getMachOSection("__TEXT", "__picsymbolstub4",
1174                                      MCSectionMachO::S_SYMBOL_STUBS,
1175                                      16, SectionKind::getText());
1176         OutStreamer.SwitchSection(sect);
1177       }
1178       const MCSection *StaticInitSect =
1179         OutContext.getMachOSection("__TEXT", "__StaticInit",
1180                                    MCSectionMachO::S_REGULAR |
1181                                    MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
1182                                    SectionKind::getText());
1183       OutStreamer.SwitchSection(StaticInitSect);
1184     }
1185   }
1186
1187   // Use unified assembler syntax.
1188   OutStreamer.EmitRawText(StringRef("\t.syntax unified"));
1189
1190   // Emit ARM Build Attributes
1191   if (Subtarget->isTargetELF()) {
1192     // CPU Type
1193     std::string CPUString = Subtarget->getCPUString();
1194     if (CPUString != "generic")
1195       OutStreamer.EmitRawText("\t.cpu " + Twine(CPUString));
1196
1197     // FIXME: Emit FPU type
1198     if (Subtarget->hasVFP2())
1199       OutStreamer.EmitRawText("\t.eabi_attribute " +
1200                               Twine(ARMBuildAttrs::VFP_arch) + ", 2");
1201
1202     // Signal various FP modes.
1203     if (!UnsafeFPMath) {
1204       OutStreamer.EmitRawText("\t.eabi_attribute " +
1205                               Twine(ARMBuildAttrs::ABI_FP_denormal) + ", 1");
1206       OutStreamer.EmitRawText("\t.eabi_attribute " +
1207                               Twine(ARMBuildAttrs::ABI_FP_exceptions) + ", 1");
1208     }
1209     
1210     if (NoInfsFPMath && NoNaNsFPMath)
1211       OutStreamer.EmitRawText("\t.eabi_attribute " +
1212                               Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 1");
1213     else
1214       OutStreamer.EmitRawText("\t.eabi_attribute " +
1215                               Twine(ARMBuildAttrs::ABI_FP_number_model)+ ", 3");
1216
1217     // 8-bytes alignment stuff.
1218     OutStreamer.EmitRawText("\t.eabi_attribute " +
1219                             Twine(ARMBuildAttrs::ABI_align8_needed) + ", 1");
1220     OutStreamer.EmitRawText("\t.eabi_attribute " +
1221                             Twine(ARMBuildAttrs::ABI_align8_preserved) + ", 1");
1222
1223     // Hard float.  Use both S and D registers and conform to AAPCS-VFP.
1224     if (Subtarget->isAAPCS_ABI() && FloatABIType == FloatABI::Hard) {
1225       OutStreamer.EmitRawText("\t.eabi_attribute " +
1226                               Twine(ARMBuildAttrs::ABI_HardFP_use) + ", 3");
1227       OutStreamer.EmitRawText("\t.eabi_attribute " +
1228                               Twine(ARMBuildAttrs::ABI_VFP_args) + ", 1");
1229     }
1230     // FIXME: Should we signal R9 usage?
1231   }
1232 }
1233
1234
1235 void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) {
1236   if (Subtarget->isTargetDarwin()) {
1237     // All darwin targets use mach-o.
1238     const TargetLoweringObjectFileMachO &TLOFMacho =
1239       static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
1240     MachineModuleInfoMachO &MMIMacho =
1241       MMI->getObjFileInfo<MachineModuleInfoMachO>();
1242
1243     // Output non-lazy-pointers for external and common global variables.
1244     MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
1245
1246     if (!Stubs.empty()) {
1247       // Switch with ".non_lazy_symbol_pointer" directive.
1248       OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
1249       EmitAlignment(2);
1250       for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1251         // L_foo$stub:
1252         OutStreamer.EmitLabel(Stubs[i].first);
1253         //   .indirect_symbol _foo
1254         MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
1255         OutStreamer.EmitSymbolAttribute(MCSym.getPointer(),MCSA_IndirectSymbol);
1256
1257         if (MCSym.getInt())
1258           // External to current translation unit.
1259           OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
1260         else
1261           // Internal to current translation unit.
1262           //
1263           // When we place the LSDA into the TEXT section, the type info pointers
1264           // need to be indirect and pc-rel. We accomplish this by using NLPs.
1265           // However, sometimes the types are local to the file. So we need to
1266           // fill in the value for the NLP in those cases.
1267           OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(),
1268                                                         OutContext),
1269                                 4/*size*/, 0/*addrspace*/);
1270       }
1271
1272       Stubs.clear();
1273       OutStreamer.AddBlankLine();
1274     }
1275
1276     Stubs = MMIMacho.GetHiddenGVStubList();
1277     if (!Stubs.empty()) {
1278       OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
1279       EmitAlignment(2);
1280       for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1281         // L_foo$stub:
1282         OutStreamer.EmitLabel(Stubs[i].first);
1283         //   .long _foo
1284         OutStreamer.EmitValue(MCSymbolRefExpr::
1285                               Create(Stubs[i].second.getPointer(),
1286                                      OutContext),
1287                               4/*size*/, 0/*addrspace*/);
1288       }
1289
1290       Stubs.clear();
1291       OutStreamer.AddBlankLine();
1292     }
1293
1294     // Funny Darwin hack: This flag tells the linker that no global symbols
1295     // contain code that falls through to other global symbols (e.g. the obvious
1296     // implementation of multiple entry points).  If this doesn't occur, the
1297     // linker can safely perform dead code stripping.  Since LLVM never
1298     // generates code that does this, it is always safe to set.
1299     OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
1300   }
1301 }
1302
1303 //===----------------------------------------------------------------------===//
1304
1305 void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
1306   ARMMCInstLower MCInstLowering(OutContext, *Mang, *this);
1307   switch (MI->getOpcode()) {
1308   case ARM::t2MOVi32imm:
1309     assert(0 && "Should be lowered by thumb2it pass");
1310   default: break;
1311   case ARM::PICADD: { // FIXME: Remove asm string from td file.
1312     // This is a pseudo op for a label + instruction sequence, which looks like:
1313     // LPC0:
1314     //     add r0, pc, r0
1315     // This adds the address of LPC0 to r0.
1316     
1317     // Emit the label.
1318     // FIXME: MOVE TO SHARED PLACE.
1319     unsigned Id = (unsigned)MI->getOperand(2).getImm();
1320     const char *Prefix = MAI->getPrivateGlobalPrefix();
1321     MCSymbol *Label =OutContext.GetOrCreateSymbol(Twine(Prefix)
1322                          + "PC" + Twine(getFunctionNumber()) + "_" + Twine(Id));
1323     OutStreamer.EmitLabel(Label);
1324     
1325     
1326     // Form and emit tha dd.
1327     MCInst AddInst;
1328     AddInst.setOpcode(ARM::ADDrr);
1329     AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
1330     AddInst.addOperand(MCOperand::CreateReg(ARM::PC));
1331     AddInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
1332     OutStreamer.EmitInstruction(AddInst);
1333     return;
1334   }
1335   case ARM::CONSTPOOL_ENTRY: { // FIXME: Remove asm string from td file.
1336     /// CONSTPOOL_ENTRY - This instruction represents a floating constant pool
1337     /// in the function.  The first operand is the ID# for this instruction, the
1338     /// second is the index into the MachineConstantPool that this is, the third
1339     /// is the size in bytes of this constant pool entry.
1340     unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
1341     unsigned CPIdx   = (unsigned)MI->getOperand(1).getIndex();
1342
1343     EmitAlignment(2);
1344     OutStreamer.EmitLabel(GetCPISymbol(LabelId));
1345
1346     const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
1347     if (MCPE.isMachineConstantPoolEntry())
1348       EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
1349     else
1350       EmitGlobalConstant(MCPE.Val.ConstVal);
1351     
1352     return;
1353   }
1354   case ARM::MOVi2pieces: { // FIXME: Remove asmstring from td file.
1355     // This is a hack that lowers as a two instruction sequence.
1356     unsigned DstReg = MI->getOperand(0).getReg();
1357     unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
1358
1359     unsigned SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(ImmVal);
1360     unsigned SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(ImmVal);
1361     
1362     {
1363       MCInst TmpInst;
1364       TmpInst.setOpcode(ARM::MOVi);
1365       TmpInst.addOperand(MCOperand::CreateReg(DstReg));
1366       TmpInst.addOperand(MCOperand::CreateImm(SOImmValV1));
1367       
1368       // Predicate.
1369       TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1370       TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1371
1372       TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out
1373       OutStreamer.EmitInstruction(TmpInst);
1374     }
1375
1376     {
1377       MCInst TmpInst;
1378       TmpInst.setOpcode(ARM::ORRri);
1379       TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // dstreg
1380       TmpInst.addOperand(MCOperand::CreateReg(DstReg));     // inreg
1381       TmpInst.addOperand(MCOperand::CreateImm(SOImmValV2)); // so_imm
1382       // Predicate.
1383       TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1384       TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1385       
1386       TmpInst.addOperand(MCOperand::CreateReg(0));          // cc_out
1387       OutStreamer.EmitInstruction(TmpInst);
1388     }
1389     return; 
1390   }
1391   case ARM::MOVi32imm: { // FIXME: Remove asmstring from td file.
1392     // This is a hack that lowers as a two instruction sequence.
1393     unsigned DstReg = MI->getOperand(0).getReg();
1394     const MachineOperand &MO = MI->getOperand(1);
1395     MCOperand V1, V2;
1396     if (MO.isImm()) {
1397       unsigned ImmVal = (unsigned)MI->getOperand(1).getImm();
1398       V1 = MCOperand::CreateImm(ImmVal & 65535);
1399       V2 = MCOperand::CreateImm(ImmVal >> 16);
1400     } else if (MO.isGlobal()) {
1401       MCSymbol *Symbol = MCInstLowering.GetGlobalAddressSymbol(MO);
1402       const MCSymbolRefExpr *SymRef1 =
1403         MCSymbolRefExpr::Create(Symbol,
1404                                 MCSymbolRefExpr::VK_ARM_LO16, OutContext);
1405       const MCSymbolRefExpr *SymRef2 =
1406         MCSymbolRefExpr::Create(Symbol,
1407                                 MCSymbolRefExpr::VK_ARM_HI16, OutContext);
1408       V1 = MCOperand::CreateExpr(SymRef1);
1409       V2 = MCOperand::CreateExpr(SymRef2);
1410     } else {
1411       MI->dump();
1412       llvm_unreachable("cannot handle this operand");
1413     }
1414
1415     {
1416       MCInst TmpInst;
1417       TmpInst.setOpcode(ARM::MOVi16);
1418       TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
1419       TmpInst.addOperand(V1); // lower16(imm)
1420       
1421       // Predicate.
1422       TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1423       TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1424       
1425       OutStreamer.EmitInstruction(TmpInst);
1426     }
1427     
1428     {
1429       MCInst TmpInst;
1430       TmpInst.setOpcode(ARM::MOVTi16);
1431       TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // dstreg
1432       TmpInst.addOperand(MCOperand::CreateReg(DstReg));         // srcreg
1433       TmpInst.addOperand(V2);   // upper16(imm)
1434       
1435       // Predicate.
1436       TmpInst.addOperand(MCOperand::CreateImm(MI->getOperand(2).getImm()));
1437       TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(3).getReg()));
1438       
1439       OutStreamer.EmitInstruction(TmpInst);
1440     }
1441     
1442     return;
1443   }
1444   }
1445       
1446   MCInst TmpInst;
1447   MCInstLowering.Lower(MI, TmpInst);
1448   OutStreamer.EmitInstruction(TmpInst);
1449 }
1450
1451 //===----------------------------------------------------------------------===//
1452 // Target Registry Stuff
1453 //===----------------------------------------------------------------------===//
1454
1455 static MCInstPrinter *createARMMCInstPrinter(const Target &T,
1456                                              unsigned SyntaxVariant,
1457                                              const MCAsmInfo &MAI) {
1458   if (SyntaxVariant == 0)
1459     return new ARMInstPrinter(MAI, false);
1460   return 0;
1461 }
1462
1463 // Force static initialization.
1464 extern "C" void LLVMInitializeARMAsmPrinter() {
1465   RegisterAsmPrinter<ARMAsmPrinter> X(TheARMTarget);
1466   RegisterAsmPrinter<ARMAsmPrinter> Y(TheThumbTarget);
1467
1468   TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter);
1469   TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter);
1470 }
1471