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