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