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