Rename getABITypeSize to getTypePaddedSize, as
[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   struct VISIBILITY_HIDDEN SPUAsmPrinter : public AsmPrinter {
49     std::set<std::string> FnStubs, GVStubs;
50
51     SPUAsmPrinter(raw_ostream &O, TargetMachine &TM, const TargetAsmInfo *T) :
52       AsmPrinter(O, TM, T)
53     {
54     }
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       const MachineOperand &MO = MI->getOperand(OpNo);
189       assert(MO.isImm() &&
190              "printDFormAddr first operand is not immedate");
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         assert(0 &&"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         assert(0 &&"Invalid/non-immediate rotate amount in printRotateNeg7Imm");
280       }
281     }
282
283     virtual bool runOnMachineFunction(MachineFunction &F) = 0;
284     //! Assembly printer cleanup after function has been emitted
285     virtual bool doFinalization(Module &M) = 0;
286   };
287
288   /// LinuxAsmPrinter - SPU assembly printer, customized for Linux
289   struct VISIBILITY_HIDDEN LinuxAsmPrinter : public SPUAsmPrinter {
290   
291     DwarfWriter *DW;
292     MachineModuleInfo *MMI;
293
294     LinuxAsmPrinter(raw_ostream &O, SPUTargetMachine &TM,
295                     const TargetAsmInfo *T) :
296       SPUAsmPrinter(O, TM, T),
297       DW(0),
298       MMI(0)
299     { }
300
301     virtual const char *getPassName() const {
302       return "STI CBEA SPU Assembly Printer";
303     }
304     
305     bool runOnMachineFunction(MachineFunction &F);
306     bool doInitialization(Module &M);
307     //! Dump globals, perform cleanup after function emission
308     bool doFinalization(Module &M);
309     
310     void getAnalysisUsage(AnalysisUsage &AU) const {
311       AU.setPreservesAll();
312       AU.addRequired<MachineModuleInfo>();
313       AU.addRequired<DwarfWriter>();
314       SPUAsmPrinter::getAnalysisUsage(AU);
315     }
316
317     //! Emit a global variable according to its section and type
318     void printModuleLevelGV(const GlobalVariable* GVar);
319   };
320 } // end of anonymous namespace
321
322 // Include the auto-generated portion of the assembly writer
323 #include "SPUGenAsmWriter.inc"
324
325 void SPUAsmPrinter::printOp(const MachineOperand &MO) {
326   switch (MO.getType()) {
327   case MachineOperand::MO_Immediate:
328     cerr << "printOp() does not handle immediate values\n";
329     abort();
330     return;
331
332   case MachineOperand::MO_MachineBasicBlock:
333     printBasicBlockLabel(MO.getMBB());
334     return;
335   case MachineOperand::MO_JumpTableIndex:
336     O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
337       << '_' << MO.getIndex();
338     return;
339   case MachineOperand::MO_ConstantPoolIndex:
340     O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
341       << '_' << MO.getIndex();
342     return;
343   case MachineOperand::MO_ExternalSymbol:
344     // Computing the address of an external symbol, not calling it.
345     if (TM.getRelocationModel() != Reloc::Static) {
346       std::string Name(TAI->getGlobalPrefix()); Name += MO.getSymbolName();
347       GVStubs.insert(Name);
348       O << "L" << Name << "$non_lazy_ptr";
349       return;
350     }
351     O << TAI->getGlobalPrefix() << MO.getSymbolName();
352     return;
353   case MachineOperand::MO_GlobalAddress: {
354     // Computing the address of a global symbol, not calling it.
355     GlobalValue *GV = MO.getGlobal();
356     std::string Name = Mang->getValueName(GV);
357
358     // External or weakly linked global variables need non-lazily-resolved
359     // stubs
360     if (TM.getRelocationModel() != Reloc::Static) {
361       if (((GV->isDeclaration() || GV->hasWeakLinkage() ||
362             GV->hasLinkOnceLinkage() || GV->hasCommonLinkage()))) {
363         GVStubs.insert(Name);
364         O << "L" << Name << "$non_lazy_ptr";
365         return;
366       }
367     }
368     O << Name;
369     
370     if (GV->hasExternalWeakLinkage())
371       ExtWeakSymbols.insert(GV);
372     return;
373   }
374
375   default:
376     O << "<unknown operand type: " << MO.getType() << ">";
377     return;
378   }
379 }
380
381 /// PrintAsmOperand - Print out an operand for an inline asm expression.
382 ///
383 bool SPUAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
384                                     unsigned AsmVariant, 
385                                     const char *ExtraCode) {
386   // Does this asm operand have a single letter operand modifier?
387   if (ExtraCode && ExtraCode[0]) {
388     if (ExtraCode[1] != 0) return true; // Unknown modifier.
389     
390     switch (ExtraCode[0]) {
391     default: return true;  // Unknown modifier.
392     case 'L': // Write second word of DImode reference.  
393       // Verify that this operand has two consecutive registers.
394       if (!MI->getOperand(OpNo).isReg() ||
395           OpNo+1 == MI->getNumOperands() ||
396           !MI->getOperand(OpNo+1).isReg())
397         return true;
398       ++OpNo;   // Return the high-part.
399       break;
400     }
401   }
402   
403   printOperand(MI, OpNo);
404   return false;
405 }
406
407 bool SPUAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
408                                           unsigned OpNo,
409                                           unsigned AsmVariant, 
410                                           const char *ExtraCode) {
411   if (ExtraCode && ExtraCode[0])
412     return true; // Unknown modifier.
413   printMemRegReg(MI, OpNo);
414   return false;
415 }
416
417 /// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax
418 /// to the current output stream.
419 ///
420 void SPUAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
421   ++EmittedInsts;
422   printInstruction(MI);
423 }
424
425 /// runOnMachineFunction - This uses the printMachineInstruction()
426 /// method to print assembly for each instruction.
427 ///
428 bool
429 LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF)
430 {
431   SetupMachineFunction(MF);
432   O << "\n\n";
433   
434   // Print out constants referenced by the function
435   EmitConstantPool(MF.getConstantPool());
436
437   // Print out labels for the function.
438   const Function *F = MF.getFunction();
439
440   SwitchToSection(TAI->SectionForGlobal(F));
441   EmitAlignment(3, F);
442
443   switch (F->getLinkage()) {
444   default: assert(0 && "Unknown linkage type!");
445   case Function::InternalLinkage:  // Symbols default to internal.
446     break;
447   case Function::ExternalLinkage:
448     O << "\t.global\t" << CurrentFnName << "\n"
449       << "\t.type\t" << CurrentFnName << ", @function\n";
450     break;
451   case Function::WeakLinkage:
452   case Function::LinkOnceLinkage:
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   SwitchToTextSection("\t.text");
493   // Emit initial debug information.
494   DW = getAnalysisToUpdate<DwarfWriter>();
495   assert(DW && "Dwarf Writer is not available");
496   MMI = getAnalysisToUpdate<MachineModuleInfo>();
497   DW->BeginModule(&M, MMI, O, this, TAI);
498   return Result;
499 }
500
501 /// PrintUnmangledNameSafely - Print out the printable characters in the name.
502 /// Don't print things like \n or \0.
503 static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) {
504   for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
505        Name != E; ++Name)
506     if (isprint(*Name))
507       OS << *Name;
508 }
509
510 /*!
511   Emit a global variable according to its section, alignment, etc.
512   
513   \note This code was shamelessly copied from the PowerPC's assembly printer,
514   which sort of screams for some kind of refactorization of common code.
515  */
516 void LinuxAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
517   const TargetData *TD = TM.getTargetData();
518
519   if (!GVar->hasInitializer())
520     return;
521
522   // Check to see if this is a special global used by LLVM, if so, emit it.
523   if (EmitSpecialLLVMGlobal(GVar))
524     return;
525
526   std::string name = Mang->getValueName(GVar);
527
528   printVisibility(name, GVar->getVisibility());
529
530   Constant *C = GVar->getInitializer();
531   const Type *Type = C->getType();
532   unsigned Size = TD->getTypePaddedSize(Type);
533   unsigned Align = TD->getPreferredAlignmentLog(GVar);
534
535   SwitchToSection(TAI->SectionForGlobal(GVar));
536
537   if (C->isNullValue() && /* FIXME: Verify correct */
538       !GVar->hasSection() &&
539       (GVar->hasInternalLinkage() || GVar->hasExternalLinkage() ||
540        GVar->mayBeOverridden())) {
541       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
542
543       if (GVar->hasExternalLinkage()) {
544         O << "\t.global " << name << '\n';
545         O << "\t.type " << name << ", @object\n";
546         O << name << ":\n";
547         O << "\t.zero " << Size << '\n';
548       } else if (GVar->hasInternalLinkage()) {
549         O << TAI->getLCOMMDirective() << name << ',' << Size;
550       } else {
551         O << ".comm " << name << ',' << Size;
552       }
553       O << "\t\t" << TAI->getCommentString() << " '";
554       PrintUnmangledNameSafely(GVar, O);
555       O << "'\n";
556       return;
557   }
558
559   switch (GVar->getLinkage()) {
560     // Should never be seen for the CellSPU platform...
561    case GlobalValue::LinkOnceLinkage:
562    case GlobalValue::WeakLinkage:
563    case GlobalValue::CommonLinkage:
564     O << "\t.global " << name << '\n'
565       << "\t.type " << name << ", @object\n"
566       << "\t.weak " << name << '\n';
567     break;
568    case GlobalValue::AppendingLinkage:
569     // FIXME: appending linkage variables should go into a section of
570     // their name or something.  For now, just emit them as external.
571    case GlobalValue::ExternalLinkage:
572     // If external or appending, declare as a global symbol
573     O << "\t.global " << name << '\n'
574       << "\t.type " << name << ", @object\n";
575     // FALL THROUGH
576    case GlobalValue::InternalLinkage:
577     break;
578    default:
579     cerr << "Unknown linkage type!";
580     abort();
581   }
582
583   EmitAlignment(Align, GVar);
584   O << name << ":\t\t\t\t" << TAI->getCommentString() << " '";
585   PrintUnmangledNameSafely(GVar, O);
586   O << "'\n";
587
588   // If the initializer is a extern weak symbol, remember to emit the weak
589   // reference!
590   if (const GlobalValue *GV = dyn_cast<GlobalValue>(C))
591     if (GV->hasExternalWeakLinkage())
592       ExtWeakSymbols.insert(GV);
593
594   EmitGlobalConstant(C);
595   O << '\n';
596 }
597
598 bool LinuxAsmPrinter::doFinalization(Module &M) {
599   // Print out module-level global variables here.
600   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
601        I != E; ++I)
602     printModuleLevelGV(I);
603
604   // TODO
605
606   // Emit initial debug information.
607   DW->EndModule();
608
609   return AsmPrinter::doFinalization(M);
610 }
611
612 /// createSPUCodePrinterPass - Returns a pass that prints the Cell SPU
613 /// assembly code for a MachineFunction to the given output stream, in a format
614 /// that the Linux SPU assembler can deal with.
615 ///
616 FunctionPass *llvm::createSPUAsmPrinterPass(raw_ostream &o,
617                                             SPUTargetMachine &tm) {
618   return new LinuxAsmPrinter(o, tm, tm.getTargetAsmInfo());
619 }
620