Move DebugInfo checks into EmitComments and remove them from
[oota-llvm.git] / lib / Target / CellSPU / AsmPrinter / SPUAsmPrinter.cpp
1 //===-- SPUAsmPrinter.cpp - Print machine instrs to Cell SPU assembly -------=//
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 Cell SPU assembly language. This printer
12 // is the output mechanism used by `llc'.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #define DEBUG_TYPE "asmprinter"
17 #include "SPU.h"
18 #include "SPUTargetMachine.h"
19 #include "llvm/Constants.h"
20 #include "llvm/DerivedTypes.h"
21 #include "llvm/Module.h"
22 #include "llvm/Assembly/Writer.h"
23 #include "llvm/CodeGen/AsmPrinter.h"
24 #include "llvm/CodeGen/DwarfWriter.h"
25 #include "llvm/CodeGen/MachineModuleInfo.h"
26 #include "llvm/CodeGen/MachineFunctionPass.h"
27 #include "llvm/CodeGen/MachineInstr.h"
28 #include "llvm/MC/MCStreamer.h"
29 #include "llvm/MC/MCAsmInfo.h"
30 #include "llvm/MC/MCSymbol.h"
31 #include "llvm/Target/TargetLoweringObjectFile.h"
32 #include "llvm/Target/TargetInstrInfo.h"
33 #include "llvm/Target/TargetOptions.h"
34 #include "llvm/Target/TargetRegisterInfo.h"
35 #include "llvm/Target/TargetRegistry.h"
36 #include "llvm/ADT/Statistic.h"
37 #include "llvm/ADT/StringExtras.h"
38 #include "llvm/Support/CommandLine.h"
39 #include "llvm/Support/Debug.h"
40 #include "llvm/Support/ErrorHandling.h"
41 #include "llvm/Support/FormattedStream.h"
42 #include "llvm/Support/Mangler.h"
43 #include "llvm/Support/MathExtras.h"
44 #include <set>
45 using namespace llvm;
46
47 namespace {
48   STATISTIC(EmittedInsts, "Number of machine instrs printed");
49
50   const std::string bss_section(".bss");
51
52   class SPUAsmPrinter : public AsmPrinter {
53     std::set<std::string> FnStubs, GVStubs;
54   public:
55     explicit SPUAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
56                            const MCAsmInfo *T, bool V) :
57       AsmPrinter(O, TM, T, V) {}
58
59     virtual const char *getPassName() const {
60       return "STI CBEA SPU Assembly Printer";
61     }
62
63     SPUTargetMachine &getTM() {
64       return static_cast<SPUTargetMachine&>(TM);
65     }
66
67     /// printInstruction - This method is automatically generated by tablegen
68     /// from the instruction set description.
69     void printInstruction(const MachineInstr *MI);
70     static const char *getRegisterName(unsigned RegNo);
71
72
73     void printMachineInstruction(const MachineInstr *MI);
74     void printOp(const MachineOperand &MO);
75
76     /// printRegister - Print register according to target requirements.
77     ///
78     void printRegister(const MachineOperand &MO, bool R0AsZero) {
79       unsigned RegNo = MO.getReg();
80       assert(TargetRegisterInfo::isPhysicalRegister(RegNo) &&
81              "Not physreg??");
82       O << getRegisterName(RegNo);
83     }
84
85     void printOperand(const MachineInstr *MI, unsigned OpNo) {
86       const MachineOperand &MO = MI->getOperand(OpNo);
87       if (MO.isReg()) {
88         O << getRegisterName(MO.getReg());
89       } else if (MO.isImm()) {
90         O << MO.getImm();
91       } else {
92         printOp(MO);
93       }
94     }
95
96     bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
97                          unsigned AsmVariant, const char *ExtraCode);
98     bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
99                                unsigned AsmVariant, const char *ExtraCode);
100
101
102     void
103     printS7ImmOperand(const MachineInstr *MI, unsigned OpNo)
104     {
105       int value = MI->getOperand(OpNo).getImm();
106       value = (value << (32 - 7)) >> (32 - 7);
107
108       assert((value >= -(1 << 8) && value <= (1 << 7) - 1)
109              && "Invalid s7 argument");
110       O << value;
111     }
112
113     void
114     printU7ImmOperand(const MachineInstr *MI, unsigned OpNo)
115     {
116       unsigned int value = MI->getOperand(OpNo).getImm();
117       assert(value < (1 << 8) && "Invalid u7 argument");
118       O << value;
119     }
120
121     void
122     printShufAddr(const MachineInstr *MI, unsigned OpNo)
123     {
124       char value = MI->getOperand(OpNo).getImm();
125       O << (int) value;
126       O << "(";
127       printOperand(MI, OpNo+1);
128       O << ")";
129     }
130
131     void
132     printS16ImmOperand(const MachineInstr *MI, unsigned OpNo)
133     {
134       O << (short) MI->getOperand(OpNo).getImm();
135     }
136
137     void
138     printU16ImmOperand(const MachineInstr *MI, unsigned OpNo)
139     {
140       O << (unsigned short)MI->getOperand(OpNo).getImm();
141     }
142
143     void
144     printU32ImmOperand(const MachineInstr *MI, unsigned OpNo)
145     {
146       O << (unsigned)MI->getOperand(OpNo).getImm();
147     }
148
149     void
150     printMemRegReg(const MachineInstr *MI, unsigned OpNo) {
151       // When used as the base register, r0 reads constant zero rather than
152       // the value contained in the register.  For this reason, the darwin
153       // assembler requires that we print r0 as 0 (no r) when used as the base.
154       const MachineOperand &MO = MI->getOperand(OpNo);
155       O << getRegisterName(MO.getReg()) << ", ";
156       printOperand(MI, OpNo+1);
157     }
158
159     void
160     printU18ImmOperand(const MachineInstr *MI, unsigned OpNo)
161     {
162       unsigned int value = MI->getOperand(OpNo).getImm();
163       assert(value <= (1 << 19) - 1 && "Invalid u18 argument");
164       O << value;
165     }
166
167     void
168     printS10ImmOperand(const MachineInstr *MI, unsigned OpNo)
169     {
170       short value = (short) (((int) MI->getOperand(OpNo).getImm() << 16)
171                              >> 16);
172       assert((value >= -(1 << 9) && value <= (1 << 9) - 1)
173              && "Invalid s10 argument");
174       O << value;
175     }
176
177     void
178     printU10ImmOperand(const MachineInstr *MI, unsigned OpNo)
179     {
180       short value = (short) (((int) MI->getOperand(OpNo).getImm() << 16)
181                              >> 16);
182       assert((value <= (1 << 10) - 1) && "Invalid u10 argument");
183       O << value;
184     }
185
186     void
187     printDFormAddr(const MachineInstr *MI, unsigned OpNo)
188     {
189       assert(MI->getOperand(OpNo).isImm() &&
190              "printDFormAddr first operand is not immediate");
191       int64_t value = int64_t(MI->getOperand(OpNo).getImm());
192       int16_t value16 = int16_t(value);
193       assert((value16 >= -(1 << (9+4)) && value16 <= (1 << (9+4)) - 1)
194              && "Invalid dform s10 offset argument");
195       O << (value16 & ~0xf) << "(";
196       printOperand(MI, OpNo+1);
197       O << ")";
198     }
199
200     void
201     printAddr256K(const MachineInstr *MI, unsigned OpNo)
202     {
203       /* Note: operand 1 is an offset or symbol name. */
204       if (MI->getOperand(OpNo).isImm()) {
205         printS16ImmOperand(MI, OpNo);
206       } else {
207         printOp(MI->getOperand(OpNo));
208         if (MI->getOperand(OpNo+1).isImm()) {
209           int displ = int(MI->getOperand(OpNo+1).getImm());
210           if (displ > 0)
211             O << "+" << displ;
212           else if (displ < 0)
213             O << displ;
214         }
215       }
216     }
217
218     void printCallOperand(const MachineInstr *MI, unsigned OpNo) {
219       printOp(MI->getOperand(OpNo));
220     }
221
222     void printPCRelativeOperand(const MachineInstr *MI, unsigned OpNo) {
223       // Used to generate a ".-<target>", but it turns out that the assembler
224       // really wants the target.
225       //
226       // N.B.: This operand is used for call targets. Branch hints are another
227       // animal entirely.
228       printOp(MI->getOperand(OpNo));
229     }
230
231     void printHBROperand(const MachineInstr *MI, unsigned OpNo) {
232       // HBR operands are generated in front of branches, hence, the
233       // program counter plus the target.
234       O << ".+";
235       printOp(MI->getOperand(OpNo));
236     }
237
238     void printSymbolHi(const MachineInstr *MI, unsigned OpNo) {
239       if (MI->getOperand(OpNo).isImm()) {
240         printS16ImmOperand(MI, OpNo);
241       } else {
242         printOp(MI->getOperand(OpNo));
243         O << "@h";
244       }
245     }
246
247     void printSymbolLo(const MachineInstr *MI, unsigned OpNo) {
248       if (MI->getOperand(OpNo).isImm()) {
249         printS16ImmOperand(MI, OpNo);
250       } else {
251         printOp(MI->getOperand(OpNo));
252         O << "@l";
253       }
254     }
255
256     /// Print local store address
257     void printSymbolLSA(const MachineInstr *MI, unsigned OpNo) {
258       printOp(MI->getOperand(OpNo));
259     }
260
261     void printROTHNeg7Imm(const MachineInstr *MI, unsigned OpNo) {
262       if (MI->getOperand(OpNo).isImm()) {
263         int value = (int) MI->getOperand(OpNo).getImm();
264         assert((value >= 0 && value < 16)
265                && "Invalid negated immediate rotate 7-bit argument");
266         O << -value;
267       } else {
268         llvm_unreachable("Invalid/non-immediate rotate amount in printRotateNeg7Imm");
269       }
270     }
271
272     void printROTNeg7Imm(const MachineInstr *MI, unsigned OpNo) {
273       if (MI->getOperand(OpNo).isImm()) {
274         int value = (int) MI->getOperand(OpNo).getImm();
275         assert((value >= 0 && value <= 32)
276                && "Invalid negated immediate rotate 7-bit argument");
277         O << -value;
278       } else {
279         llvm_unreachable("Invalid/non-immediate rotate amount in printRotateNeg7Imm");
280       }
281     }
282
283     virtual bool runOnMachineFunction(MachineFunction &F) = 0;
284   };
285
286   /// LinuxAsmPrinter - SPU assembly printer, customized for Linux
287   class LinuxAsmPrinter : public SPUAsmPrinter {
288   public:
289     explicit LinuxAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
290                              const MCAsmInfo *T, bool V)
291       : SPUAsmPrinter(O, TM, T, V) {}
292
293     virtual const char *getPassName() const {
294       return "STI CBEA SPU Assembly Printer";
295     }
296
297     bool runOnMachineFunction(MachineFunction &F);
298
299     void getAnalysisUsage(AnalysisUsage &AU) const {
300       AU.setPreservesAll();
301       AU.addRequired<MachineModuleInfo>();
302       AU.addRequired<DwarfWriter>();
303       SPUAsmPrinter::getAnalysisUsage(AU);
304     }
305
306     //! Emit a global variable according to its section and type
307     void PrintGlobalVariable(const GlobalVariable* GVar);
308   };
309 } // end of anonymous namespace
310
311 // Include the auto-generated portion of the assembly writer
312 #include "SPUGenAsmWriter.inc"
313
314 void SPUAsmPrinter::printOp(const MachineOperand &MO) {
315   switch (MO.getType()) {
316   case MachineOperand::MO_Immediate:
317     llvm_report_error("printOp() does not handle immediate values");
318     return;
319
320   case MachineOperand::MO_MachineBasicBlock:
321     GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
322     return;
323   case MachineOperand::MO_JumpTableIndex:
324     O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
325       << '_' << MO.getIndex();
326     return;
327   case MachineOperand::MO_ConstantPoolIndex:
328     O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
329       << '_' << MO.getIndex();
330     return;
331   case MachineOperand::MO_ExternalSymbol:
332     // Computing the address of an external symbol, not calling it.
333     if (TM.getRelocationModel() != Reloc::Static) {
334       std::string Name(MAI->getGlobalPrefix()); Name += MO.getSymbolName();
335       GVStubs.insert(Name);
336       O << "L" << Name << "$non_lazy_ptr";
337       return;
338     }
339     O << MAI->getGlobalPrefix() << MO.getSymbolName();
340     return;
341   case MachineOperand::MO_GlobalAddress: {
342     // Computing the address of a global symbol, not calling it.
343     GlobalValue *GV = MO.getGlobal();
344     std::string Name = Mang->getMangledName(GV);
345
346     // External or weakly linked global variables need non-lazily-resolved
347     // stubs
348     if (TM.getRelocationModel() != Reloc::Static) {
349       if (((GV->isDeclaration() || GV->hasWeakLinkage() ||
350             GV->hasLinkOnceLinkage() || GV->hasCommonLinkage()))) {
351         GVStubs.insert(Name);
352         O << "L" << Name << "$non_lazy_ptr";
353         return;
354       }
355     }
356     O << Name;
357     return;
358   }
359
360   default:
361     O << "<unknown operand type: " << MO.getType() << ">";
362     return;
363   }
364 }
365
366 /// PrintAsmOperand - Print out an operand for an inline asm expression.
367 ///
368 bool SPUAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
369                                     unsigned AsmVariant,
370                                     const char *ExtraCode) {
371   // Does this asm operand have a single letter operand modifier?
372   if (ExtraCode && ExtraCode[0]) {
373     if (ExtraCode[1] != 0) return true; // Unknown modifier.
374
375     switch (ExtraCode[0]) {
376     default: return true;  // Unknown modifier.
377     case 'L': // Write second word of DImode reference.
378       // Verify that this operand has two consecutive registers.
379       if (!MI->getOperand(OpNo).isReg() ||
380           OpNo+1 == MI->getNumOperands() ||
381           !MI->getOperand(OpNo+1).isReg())
382         return true;
383       ++OpNo;   // Return the high-part.
384       break;
385     }
386   }
387
388   printOperand(MI, OpNo);
389   return false;
390 }
391
392 bool SPUAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
393                                           unsigned OpNo,
394                                           unsigned AsmVariant,
395                                           const char *ExtraCode) {
396   if (ExtraCode && ExtraCode[0])
397     return true; // Unknown modifier.
398   printMemRegReg(MI, OpNo);
399   return false;
400 }
401
402 /// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax
403 /// to the current output stream.
404 ///
405 void SPUAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
406   ++EmittedInsts;
407   processDebugLoc(MI, true);
408   printInstruction(MI);
409   if (VerboseAsm)
410     EmitComments(*MI);
411   processDebugLoc(MI, false);
412   O << '\n';
413 }
414
415 /// runOnMachineFunction - This uses the printMachineInstruction()
416 /// method to print assembly for each instruction.
417 ///
418 bool LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
419   this->MF = &MF;
420
421   SetupMachineFunction(MF);
422   O << "\n\n";
423
424   // Print out constants referenced by the function
425   EmitConstantPool(MF.getConstantPool());
426
427   // Print out labels for the function.
428   const Function *F = MF.getFunction();
429
430   OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
431   EmitAlignment(MF.getAlignment(), F);
432
433   switch (F->getLinkage()) {
434   default: llvm_unreachable("Unknown linkage type!");
435   case Function::PrivateLinkage:
436   case Function::LinkerPrivateLinkage:
437   case Function::InternalLinkage:  // Symbols default to internal.
438     break;
439   case Function::ExternalLinkage:
440     O << "\t.global\t" << CurrentFnName << "\n"
441       << "\t.type\t" << CurrentFnName << ", @function\n";
442     break;
443   case Function::WeakAnyLinkage:
444   case Function::WeakODRLinkage:
445   case Function::LinkOnceAnyLinkage:
446   case Function::LinkOnceODRLinkage:
447     O << "\t.global\t" << CurrentFnName << "\n";
448     O << "\t.weak_definition\t" << CurrentFnName << "\n";
449     break;
450   }
451   O << CurrentFnName << ":\n";
452
453   // Emit pre-function debug information.
454   DW->BeginFunction(&MF);
455
456   // Print out code for the function.
457   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
458        I != E; ++I) {
459     // Print a label for the basic block.
460     if (I != MF.begin()) {
461       EmitBasicBlockStart(I);
462     }
463     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
464          II != E; ++II) {
465       // Print the assembly for the instruction.
466       printMachineInstruction(II);
467     }
468   }
469
470   O << "\t.size\t" << CurrentFnName << ",.-" << CurrentFnName << "\n";
471
472   // Print out jump tables referenced by the function.
473   EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
474
475   // Emit post-function debug information.
476   DW->EndFunction(&MF);
477
478   // We didn't modify anything.
479   return false;
480 }
481
482
483 /*!
484   Emit a global variable according to its section, alignment, etc.
485
486   \note This code was shamelessly copied from the PowerPC's assembly printer,
487   which sort of screams for some kind of refactorization of common code.
488  */
489 void LinuxAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
490   const TargetData *TD = TM.getTargetData();
491
492   if (!GVar->hasInitializer())
493     return;
494
495   // Check to see if this is a special global used by LLVM, if so, emit it.
496   if (EmitSpecialLLVMGlobal(GVar))
497     return;
498
499   std::string name = Mang->getMangledName(GVar);
500
501   printVisibility(name, GVar->getVisibility());
502
503   Constant *C = GVar->getInitializer();
504   const Type *Type = C->getType();
505   unsigned Size = TD->getTypeAllocSize(Type);
506   unsigned Align = TD->getPreferredAlignmentLog(GVar);
507
508   OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang,
509                                                                   TM));
510
511   if (C->isNullValue() && /* FIXME: Verify correct */
512       !GVar->hasSection() &&
513       (GVar->hasLocalLinkage() || GVar->hasExternalLinkage() ||
514        GVar->isWeakForLinker())) {
515       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
516
517       if (GVar->hasExternalLinkage()) {
518         O << "\t.global " << name << '\n';
519         O << "\t.type " << name << ", @object\n";
520         O << name << ":\n";
521         O << "\t.zero " << Size << '\n';
522       } else if (GVar->hasLocalLinkage()) {
523         O << MAI->getLCOMMDirective() << name << ',' << Size;
524       } else {
525         O << ".comm " << name << ',' << Size;
526       }
527       O << "\t\t" << MAI->getCommentString() << " '";
528       WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
529       O << "'\n";
530       return;
531   }
532
533   switch (GVar->getLinkage()) {
534     // Should never be seen for the CellSPU platform...
535    case GlobalValue::LinkOnceAnyLinkage:
536    case GlobalValue::LinkOnceODRLinkage:
537    case GlobalValue::WeakAnyLinkage:
538    case GlobalValue::WeakODRLinkage:
539    case GlobalValue::CommonLinkage:
540     O << "\t.global " << name << '\n'
541       << "\t.type " << name << ", @object\n"
542       << "\t.weak " << name << '\n';
543     break;
544    case GlobalValue::AppendingLinkage:
545     // FIXME: appending linkage variables should go into a section of
546     // their name or something.  For now, just emit them as external.
547    case GlobalValue::ExternalLinkage:
548     // If external or appending, declare as a global symbol
549     O << "\t.global " << name << '\n'
550       << "\t.type " << name << ", @object\n";
551     // FALL THROUGH
552    case GlobalValue::PrivateLinkage:
553    case GlobalValue::LinkerPrivateLinkage:
554    case GlobalValue::InternalLinkage:
555     break;
556    default:
557     llvm_report_error("Unknown linkage type!");
558   }
559
560   EmitAlignment(Align, GVar);
561   O << name << ":\t\t\t\t" << MAI->getCommentString() << " '";
562   WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
563   O << "'\n";
564
565   EmitGlobalConstant(C);
566   O << '\n';
567 }
568
569 // Force static initialization.
570 extern "C" void LLVMInitializeCellSPUAsmPrinter() { 
571   RegisterAsmPrinter<LinuxAsmPrinter> X(TheCellSPUTarget);
572 }