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