Remove old style hacks to register AsmPrinter into TargetMachine.
[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/MDNode.h"
23 #include "llvm/Assembly/Writer.h"
24 #include "llvm/CodeGen/AsmPrinter.h"
25 #include "llvm/CodeGen/DwarfWriter.h"
26 #include "llvm/CodeGen/MachineModuleInfo.h"
27 #include "llvm/CodeGen/MachineFunctionPass.h"
28 #include "llvm/CodeGen/MachineInstr.h"
29 #include "llvm/Support/Mangler.h"
30 #include "llvm/Support/MathExtras.h"
31 #include "llvm/Support/CommandLine.h"
32 #include "llvm/Support/Debug.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/Compiler.h"
35 #include "llvm/Support/FormattedStream.h"
36 #include "llvm/Target/TargetAsmInfo.h"
37 #include "llvm/Target/TargetRegisterInfo.h"
38 #include "llvm/Target/TargetInstrInfo.h"
39 #include "llvm/Target/TargetOptions.h"
40 #include "llvm/Target/TargetRegistry.h"
41 #include "llvm/ADT/Statistic.h"
42 #include "llvm/ADT/StringExtras.h"
43 #include <set>
44 using namespace llvm;
45
46 namespace {
47   STATISTIC(EmittedInsts, "Number of machine instrs printed");
48
49   const std::string bss_section(".bss");
50
51   class VISIBILITY_HIDDEN SPUAsmPrinter : public AsmPrinter {
52     std::set<std::string> FnStubs, GVStubs;
53   public:
54     explicit SPUAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
55                            const TargetAsmInfo *T, bool V) :
56       AsmPrinter(O, TM, T, V) {}
57
58     virtual const char *getPassName() const {
59       return "STI CBEA SPU Assembly Printer";
60     }
61
62     SPUTargetMachine &getTM() {
63       return static_cast<SPUTargetMachine&>(TM);
64     }
65
66     /// printInstruction - This method is automatically generated by tablegen
67     /// from the instruction set description.  This method returns true if the
68     /// machine instruction was sufficiently described to print it, otherwise it
69     /// returns false.
70     bool printInstruction(const MachineInstr *MI);
71
72     void printMachineInstruction(const MachineInstr *MI);
73     void printOp(const MachineOperand &MO);
74
75     /// printRegister - Print register according to target requirements.
76     ///
77     void printRegister(const MachineOperand &MO, bool R0AsZero) {
78       unsigned RegNo = MO.getReg();
79       assert(TargetRegisterInfo::isPhysicalRegister(RegNo) &&
80              "Not physreg??");
81       O << TM.getRegisterInfo()->get(RegNo).AsmName;
82     }
83
84     void printOperand(const MachineInstr *MI, unsigned OpNo) {
85       const MachineOperand &MO = MI->getOperand(OpNo);
86       if (MO.isReg()) {
87         assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physreg??");
88         O << TM.getRegisterInfo()->get(MO.getReg()).AsmName;
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 << TM.getRegisterInfo()->get(MO.getReg()).AsmName;
156       O << ", ";
157       printOperand(MI, OpNo+1);
158     }
159
160     void
161     printU18ImmOperand(const MachineInstr *MI, unsigned OpNo)
162     {
163       unsigned int value = MI->getOperand(OpNo).getImm();
164       assert(value <= (1 << 19) - 1 && "Invalid u18 argument");
165       O << value;
166     }
167
168     void
169     printS10ImmOperand(const MachineInstr *MI, unsigned OpNo)
170     {
171       short value = (short) (((int) MI->getOperand(OpNo).getImm() << 16)
172                              >> 16);
173       assert((value >= -(1 << 9) && value <= (1 << 9) - 1)
174              && "Invalid s10 argument");
175       O << value;
176     }
177
178     void
179     printU10ImmOperand(const MachineInstr *MI, unsigned OpNo)
180     {
181       short value = (short) (((int) MI->getOperand(OpNo).getImm() << 16)
182                              >> 16);
183       assert((value <= (1 << 10) - 1) && "Invalid u10 argument");
184       O << value;
185     }
186
187     void
188     printDFormAddr(const MachineInstr *MI, unsigned OpNo)
189     {
190       assert(MI->getOperand(OpNo).isImm() &&
191              "printDFormAddr first operand is not immediate");
192       int64_t value = int64_t(MI->getOperand(OpNo).getImm());
193       int16_t value16 = int16_t(value);
194       assert((value16 >= -(1 << (9+4)) && value16 <= (1 << (9+4)) - 1)
195              && "Invalid dform s10 offset argument");
196       O << (value16 & ~0xf) << "(";
197       printOperand(MI, OpNo+1);
198       O << ")";
199     }
200
201     void
202     printAddr256K(const MachineInstr *MI, unsigned OpNo)
203     {
204       /* Note: operand 1 is an offset or symbol name. */
205       if (MI->getOperand(OpNo).isImm()) {
206         printS16ImmOperand(MI, OpNo);
207       } else {
208         printOp(MI->getOperand(OpNo));
209         if (MI->getOperand(OpNo+1).isImm()) {
210           int displ = int(MI->getOperand(OpNo+1).getImm());
211           if (displ > 0)
212             O << "+" << displ;
213           else if (displ < 0)
214             O << displ;
215         }
216       }
217     }
218
219     void printCallOperand(const MachineInstr *MI, unsigned OpNo) {
220       printOp(MI->getOperand(OpNo));
221     }
222
223     void printPCRelativeOperand(const MachineInstr *MI, unsigned OpNo) {
224       // Used to generate a ".-<target>", but it turns out that the assembler
225       // really wants the target.
226       //
227       // N.B.: This operand is used for call targets. Branch hints are another
228       // animal entirely.
229       printOp(MI->getOperand(OpNo));
230     }
231
232     void printHBROperand(const MachineInstr *MI, unsigned OpNo) {
233       // HBR operands are generated in front of branches, hence, the
234       // program counter plus the target.
235       O << ".+";
236       printOp(MI->getOperand(OpNo));
237     }
238
239     void printSymbolHi(const MachineInstr *MI, unsigned OpNo) {
240       if (MI->getOperand(OpNo).isImm()) {
241         printS16ImmOperand(MI, OpNo);
242       } else {
243         printOp(MI->getOperand(OpNo));
244         O << "@h";
245       }
246     }
247
248     void printSymbolLo(const MachineInstr *MI, unsigned OpNo) {
249       if (MI->getOperand(OpNo).isImm()) {
250         printS16ImmOperand(MI, OpNo);
251       } else {
252         printOp(MI->getOperand(OpNo));
253         O << "@l";
254       }
255     }
256
257     /// Print local store address
258     void printSymbolLSA(const MachineInstr *MI, unsigned OpNo) {
259       printOp(MI->getOperand(OpNo));
260     }
261
262     void printROTHNeg7Imm(const MachineInstr *MI, unsigned OpNo) {
263       if (MI->getOperand(OpNo).isImm()) {
264         int value = (int) MI->getOperand(OpNo).getImm();
265         assert((value >= 0 && value < 16)
266                && "Invalid negated immediate rotate 7-bit argument");
267         O << -value;
268       } else {
269         llvm_unreachable("Invalid/non-immediate rotate amount in printRotateNeg7Imm");
270       }
271     }
272
273     void printROTNeg7Imm(const MachineInstr *MI, unsigned OpNo) {
274       if (MI->getOperand(OpNo).isImm()) {
275         int value = (int) MI->getOperand(OpNo).getImm();
276         assert((value >= 0 && value <= 32)
277                && "Invalid negated immediate rotate 7-bit argument");
278         O << -value;
279       } else {
280         llvm_unreachable("Invalid/non-immediate rotate amount in printRotateNeg7Imm");
281       }
282     }
283
284     virtual bool runOnMachineFunction(MachineFunction &F) = 0;
285     //! Assembly printer cleanup after function has been emitted
286     virtual bool doFinalization(Module &M) = 0;
287   };
288
289   /// LinuxAsmPrinter - SPU assembly printer, customized for Linux
290   class VISIBILITY_HIDDEN LinuxAsmPrinter : public SPUAsmPrinter {
291     DwarfWriter *DW;
292   public:
293     explicit LinuxAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
294                              const TargetAsmInfo *T, bool V)
295       : SPUAsmPrinter(O, TM, T, V), DW(0) {}
296
297     virtual const char *getPassName() const {
298       return "STI CBEA SPU Assembly Printer";
299     }
300
301     bool runOnMachineFunction(MachineFunction &F);
302     bool doInitialization(Module &M);
303     //! Dump globals, perform cleanup after function emission
304     bool doFinalization(Module &M);
305
306     void getAnalysisUsage(AnalysisUsage &AU) const {
307       AU.setPreservesAll();
308       AU.addRequired<MachineModuleInfo>();
309       AU.addRequired<DwarfWriter>();
310       SPUAsmPrinter::getAnalysisUsage(AU);
311     }
312
313     //! Emit a global variable according to its section and type
314     void printModuleLevelGV(const GlobalVariable* GVar);
315   };
316 } // end of anonymous namespace
317
318 // Include the auto-generated portion of the assembly writer
319 #include "SPUGenAsmWriter.inc"
320
321 void SPUAsmPrinter::printOp(const MachineOperand &MO) {
322   switch (MO.getType()) {
323   case MachineOperand::MO_Immediate:
324     llvm_report_error("printOp() does not handle immediate values");
325     return;
326
327   case MachineOperand::MO_MachineBasicBlock:
328     printBasicBlockLabel(MO.getMBB());
329     return;
330   case MachineOperand::MO_JumpTableIndex:
331     O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
332       << '_' << MO.getIndex();
333     return;
334   case MachineOperand::MO_ConstantPoolIndex:
335     O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
336       << '_' << MO.getIndex();
337     return;
338   case MachineOperand::MO_ExternalSymbol:
339     // Computing the address of an external symbol, not calling it.
340     if (TM.getRelocationModel() != Reloc::Static) {
341       std::string Name(TAI->getGlobalPrefix()); Name += MO.getSymbolName();
342       GVStubs.insert(Name);
343       O << "L" << Name << "$non_lazy_ptr";
344       return;
345     }
346     O << TAI->getGlobalPrefix() << MO.getSymbolName();
347     return;
348   case MachineOperand::MO_GlobalAddress: {
349     // Computing the address of a global symbol, not calling it.
350     GlobalValue *GV = MO.getGlobal();
351     std::string Name = Mang->getMangledName(GV);
352
353     // External or weakly linked global variables need non-lazily-resolved
354     // stubs
355     if (TM.getRelocationModel() != Reloc::Static) {
356       if (((GV->isDeclaration() || GV->hasWeakLinkage() ||
357             GV->hasLinkOnceLinkage() || GV->hasCommonLinkage()))) {
358         GVStubs.insert(Name);
359         O << "L" << Name << "$non_lazy_ptr";
360         return;
361       }
362     }
363     O << Name;
364     return;
365   }
366
367   default:
368     O << "<unknown operand type: " << MO.getType() << ">";
369     return;
370   }
371 }
372
373 /// PrintAsmOperand - Print out an operand for an inline asm expression.
374 ///
375 bool SPUAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
376                                     unsigned AsmVariant,
377                                     const char *ExtraCode) {
378   // Does this asm operand have a single letter operand modifier?
379   if (ExtraCode && ExtraCode[0]) {
380     if (ExtraCode[1] != 0) return true; // Unknown modifier.
381
382     switch (ExtraCode[0]) {
383     default: return true;  // Unknown modifier.
384     case 'L': // Write second word of DImode reference.
385       // Verify that this operand has two consecutive registers.
386       if (!MI->getOperand(OpNo).isReg() ||
387           OpNo+1 == MI->getNumOperands() ||
388           !MI->getOperand(OpNo+1).isReg())
389         return true;
390       ++OpNo;   // Return the high-part.
391       break;
392     }
393   }
394
395   printOperand(MI, OpNo);
396   return false;
397 }
398
399 bool SPUAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
400                                           unsigned OpNo,
401                                           unsigned AsmVariant,
402                                           const char *ExtraCode) {
403   if (ExtraCode && ExtraCode[0])
404     return true; // Unknown modifier.
405   printMemRegReg(MI, OpNo);
406   return false;
407 }
408
409 /// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax
410 /// to the current output stream.
411 ///
412 void SPUAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
413   ++EmittedInsts;
414   printInstruction(MI);
415 }
416
417 /// runOnMachineFunction - This uses the printMachineInstruction()
418 /// method to print assembly for each instruction.
419 ///
420 bool
421 LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF)
422 {
423   this->MF = &MF;
424
425   SetupMachineFunction(MF);
426   O << "\n\n";
427
428   // Print out constants referenced by the function
429   EmitConstantPool(MF.getConstantPool());
430
431   // Print out labels for the function.
432   const Function *F = MF.getFunction();
433
434   SwitchToSection(TAI->SectionForGlobal(F));
435   EmitAlignment(MF.getAlignment(), F);
436
437   switch (F->getLinkage()) {
438   default: llvm_unreachable("Unknown linkage type!");
439   case Function::PrivateLinkage:
440   case Function::InternalLinkage:  // Symbols default to internal.
441     break;
442   case Function::ExternalLinkage:
443     O << "\t.global\t" << CurrentFnName << "\n"
444       << "\t.type\t" << CurrentFnName << ", @function\n";
445     break;
446   case Function::WeakAnyLinkage:
447   case Function::WeakODRLinkage:
448   case Function::LinkOnceAnyLinkage:
449   case Function::LinkOnceODRLinkage:
450     O << "\t.global\t" << CurrentFnName << "\n";
451     O << "\t.weak_definition\t" << CurrentFnName << "\n";
452     break;
453   }
454   O << CurrentFnName << ":\n";
455
456   // Emit pre-function debug information.
457   DW->BeginFunction(&MF);
458
459   // Print out code for the function.
460   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
461        I != E; ++I) {
462     // Print a label for the basic block.
463     if (I != MF.begin()) {
464       printBasicBlockLabel(I, true, true);
465       O << '\n';
466     }
467     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
468          II != E; ++II) {
469       // Print the assembly for the instruction.
470       printMachineInstruction(II);
471     }
472   }
473
474   O << "\t.size\t" << CurrentFnName << ",.-" << CurrentFnName << "\n";
475
476   // Print out jump tables referenced by the function.
477   EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
478
479   // Emit post-function debug information.
480   DW->EndFunction(&MF);
481
482   // We didn't modify anything.
483   return false;
484 }
485
486
487 bool LinuxAsmPrinter::doInitialization(Module &M) {
488   bool Result = AsmPrinter::doInitialization(M);
489   DW = getAnalysisIfAvailable<DwarfWriter>();
490   SwitchToTextSection("\t.text");
491   return Result;
492 }
493
494 /// PrintUnmangledNameSafely - Print out the printable characters in the name.
495 /// Don't print things like \\n or \\0.
496 static void PrintUnmangledNameSafely(const Value *V, formatted_raw_ostream &OS) {
497   for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
498        Name != E; ++Name)
499     if (isprint(*Name))
500       OS << *Name;
501 }
502
503 /*!
504   Emit a global variable according to its section, alignment, etc.
505
506   \note This code was shamelessly copied from the PowerPC's assembly printer,
507   which sort of screams for some kind of refactorization of common code.
508  */
509 void LinuxAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
510   const TargetData *TD = TM.getTargetData();
511
512   if (!GVar->hasInitializer())
513     return;
514
515   // Check to see if this is a special global used by LLVM, if so, emit it.
516   if (EmitSpecialLLVMGlobal(GVar))
517     return;
518
519   std::string name = Mang->getMangledName(GVar);
520
521   printVisibility(name, GVar->getVisibility());
522
523   Constant *C = GVar->getInitializer();
524   if (isa<MDNode>(C) || isa<MDString>(C))
525     return;
526   const Type *Type = C->getType();
527   unsigned Size = TD->getTypeAllocSize(Type);
528   unsigned Align = TD->getPreferredAlignmentLog(GVar);
529
530   SwitchToSection(TAI->SectionForGlobal(GVar));
531
532   if (C->isNullValue() && /* FIXME: Verify correct */
533       !GVar->hasSection() &&
534       (GVar->hasLocalLinkage() || GVar->hasExternalLinkage() ||
535        GVar->isWeakForLinker())) {
536       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
537
538       if (GVar->hasExternalLinkage()) {
539         O << "\t.global " << name << '\n';
540         O << "\t.type " << name << ", @object\n";
541         O << name << ":\n";
542         O << "\t.zero " << Size << '\n';
543       } else if (GVar->hasLocalLinkage()) {
544         O << TAI->getLCOMMDirective() << name << ',' << Size;
545       } else {
546         O << ".comm " << name << ',' << Size;
547       }
548       O << "\t\t" << TAI->getCommentString() << " '";
549       PrintUnmangledNameSafely(GVar, O);
550       O << "'\n";
551       return;
552   }
553
554   switch (GVar->getLinkage()) {
555     // Should never be seen for the CellSPU platform...
556    case GlobalValue::LinkOnceAnyLinkage:
557    case GlobalValue::LinkOnceODRLinkage:
558    case GlobalValue::WeakAnyLinkage:
559    case GlobalValue::WeakODRLinkage:
560    case GlobalValue::CommonLinkage:
561     O << "\t.global " << name << '\n'
562       << "\t.type " << name << ", @object\n"
563       << "\t.weak " << name << '\n';
564     break;
565    case GlobalValue::AppendingLinkage:
566     // FIXME: appending linkage variables should go into a section of
567     // their name or something.  For now, just emit them as external.
568    case GlobalValue::ExternalLinkage:
569     // If external or appending, declare as a global symbol
570     O << "\t.global " << name << '\n'
571       << "\t.type " << name << ", @object\n";
572     // FALL THROUGH
573    case GlobalValue::PrivateLinkage:
574    case GlobalValue::InternalLinkage:
575     break;
576    default:
577     llvm_report_error("Unknown linkage type!");
578   }
579
580   EmitAlignment(Align, GVar);
581   O << name << ":\t\t\t\t" << TAI->getCommentString() << " '";
582   PrintUnmangledNameSafely(GVar, O);
583   O << "'\n";
584
585   EmitGlobalConstant(C);
586   O << '\n';
587 }
588
589 bool LinuxAsmPrinter::doFinalization(Module &M) {
590   // Print out module-level global variables here.
591   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
592        I != E; ++I)
593     printModuleLevelGV(I);
594
595   return AsmPrinter::doFinalization(M);
596 }
597
598 /// createSPUCodePrinterPass - Returns a pass that prints the Cell SPU
599 /// assembly code for a MachineFunction to the given output stream, in a format
600 /// that the Linux SPU assembler can deal with.
601 ///
602 FunctionPass *llvm::createSPUAsmPrinterPass(formatted_raw_ostream &o,
603                                             TargetMachine &tm,
604                                             bool verbose) {
605   return new LinuxAsmPrinter(o, tm, tm.getTargetAsmInfo(), verbose);
606 }
607
608 // Force static initialization.
609 extern "C" void LLVMInitializeCellSPUAsmPrinter() { 
610   extern Target TheCellSPUTarget;
611   TargetRegistry::RegisterAsmPrinter(TheCellSPUTarget, createSPUAsmPrinterPass);
612 }