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