Add new helpers for registering targets.
[oota-llvm.git] / lib / Target / SystemZ / AsmPrinter / SystemZAsmPrinter.cpp
1 //===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly writer ---------------===//
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 the SystemZ assembly language.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #define DEBUG_TYPE "asm-printer"
16 #include "SystemZ.h"
17 #include "SystemZInstrInfo.h"
18 #include "SystemZTargetMachine.h"
19 #include "llvm/Constants.h"
20 #include "llvm/DerivedTypes.h"
21 #include "llvm/Module.h"
22 #include "llvm/CodeGen/AsmPrinter.h"
23 #include "llvm/CodeGen/DwarfWriter.h"
24 #include "llvm/CodeGen/MachineModuleInfo.h"
25 #include "llvm/CodeGen/MachineFunctionPass.h"
26 #include "llvm/CodeGen/MachineConstantPool.h"
27 #include "llvm/CodeGen/MachineInstr.h"
28 #include "llvm/Target/TargetAsmInfo.h"
29 #include "llvm/Target/TargetData.h"
30 #include "llvm/Target/TargetRegistry.h"
31 #include "llvm/ADT/Statistic.h"
32 #include "llvm/Support/Compiler.h"
33 #include "llvm/Support/FormattedStream.h"
34 #include "llvm/Support/Mangler.h"
35
36 using namespace llvm;
37
38 STATISTIC(EmittedInsts, "Number of machine instrs printed");
39
40 namespace {
41   class VISIBILITY_HIDDEN SystemZAsmPrinter : public AsmPrinter {
42   public:
43     SystemZAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
44                       const TargetAsmInfo *TAI, bool V)
45       : AsmPrinter(O, TM, TAI, V) {}
46
47     virtual const char *getPassName() const {
48       return "SystemZ Assembly Printer";
49     }
50
51     void printOperand(const MachineInstr *MI, int OpNum,
52                       const char* Modifier = 0);
53     void printPCRelImmOperand(const MachineInstr *MI, int OpNum);
54     void printRIAddrOperand(const MachineInstr *MI, int OpNum,
55                             const char* Modifier = 0);
56     void printRRIAddrOperand(const MachineInstr *MI, int OpNum,
57                              const char* Modifier = 0);
58     void printS16ImmOperand(const MachineInstr *MI, int OpNum) {
59       O << (int16_t)MI->getOperand(OpNum).getImm();
60     }
61     void printS32ImmOperand(const MachineInstr *MI, int OpNum) {
62       O << (int32_t)MI->getOperand(OpNum).getImm();
63     }
64
65     bool printInstruction(const MachineInstr *MI);  // autogenerated.
66     void printMachineInstruction(const MachineInstr * MI);
67
68     void emitFunctionHeader(const MachineFunction &MF);
69     bool runOnMachineFunction(MachineFunction &F);
70     void PrintGlobalVariable(const GlobalVariable* GVar);
71
72     void getAnalysisUsage(AnalysisUsage &AU) const {
73       AsmPrinter::getAnalysisUsage(AU);
74       AU.setPreservesAll();
75     }
76   };
77 } // end of anonymous namespace
78
79 #include "SystemZGenAsmWriter.inc"
80
81 void SystemZAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
82   unsigned FnAlign = MF.getAlignment();
83   const Function *F = MF.getFunction();
84
85   SwitchToSection(TAI->SectionForGlobal(F));
86
87   EmitAlignment(FnAlign, F);
88
89   switch (F->getLinkage()) {
90   default: assert(0 && "Unknown linkage type!");
91   case Function::InternalLinkage:  // Symbols default to internal.
92   case Function::PrivateLinkage:
93   case Function::LinkerPrivateLinkage:
94     break;
95   case Function::ExternalLinkage:
96     O << "\t.globl\t" << CurrentFnName << '\n';
97     break;
98   case Function::LinkOnceAnyLinkage:
99   case Function::LinkOnceODRLinkage:
100   case Function::WeakAnyLinkage:
101   case Function::WeakODRLinkage:
102     O << "\t.weak\t" << CurrentFnName << '\n';
103     break;
104   }
105
106   printVisibility(CurrentFnName, F->getVisibility());
107
108   O << "\t.type\t" << CurrentFnName << ",@function\n"
109     << CurrentFnName << ":\n";
110 }
111
112 bool SystemZAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
113   SetupMachineFunction(MF);
114   O << "\n\n";
115
116   // Print out constants referenced by the function
117   EmitConstantPool(MF.getConstantPool());
118
119   // Print the 'header' of function
120   emitFunctionHeader(MF);
121
122   // Print out code for the function.
123   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
124        I != E; ++I) {
125     // Print a label for the basic block.
126     if (!VerboseAsm && (I->pred_empty() || I->isOnlyReachableByFallthrough())) {
127       // This is an entry block or a block that's only reachable via a
128       // fallthrough edge. In non-VerboseAsm mode, don't print the label.
129     } else {
130       printBasicBlockLabel(I, true, true, VerboseAsm);
131       O << '\n';
132     }
133
134     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
135          II != E; ++II)
136       // Print the assembly for the instruction.
137       printMachineInstruction(II);
138   }
139
140   if (TAI->hasDotTypeDotSizeDirective())
141     O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n';
142
143   // Print out jump tables referenced by the function.
144   EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
145
146   O.flush();
147
148   // We didn't modify anything
149   return false;
150 }
151
152 void SystemZAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
153   ++EmittedInsts;
154
155   // Call the autogenerated instruction printer routines.
156   if (printInstruction(MI))
157     return;
158
159   llvm_unreachable("Unreachable!");
160 }
161
162 void SystemZAsmPrinter::printPCRelImmOperand(const MachineInstr *MI, int OpNum) {
163   const MachineOperand &MO = MI->getOperand(OpNum);
164   switch (MO.getType()) {
165   case MachineOperand::MO_Immediate:
166     O << MO.getImm();
167     return;
168   case MachineOperand::MO_MachineBasicBlock:
169     printBasicBlockLabel(MO.getMBB(), false, false, VerboseAsm);
170     return;
171   case MachineOperand::MO_GlobalAddress: {
172     const GlobalValue *GV = MO.getGlobal();
173     std::string Name = Mang->getMangledName(GV);
174
175     O << Name;
176
177     // Assemble calls via PLT for externally visible symbols if PIC.
178     if (TM.getRelocationModel() == Reloc::PIC_ &&
179         !GV->hasHiddenVisibility() && !GV->hasProtectedVisibility() &&
180         !GV->hasLocalLinkage())
181       O << "@PLT";
182
183     printOffset(MO.getOffset());
184     return;
185   }
186   case MachineOperand::MO_ExternalSymbol: {
187     std::string Name(TAI->getGlobalPrefix());
188     Name += MO.getSymbolName();
189     O << Name;
190
191     if (TM.getRelocationModel() == Reloc::PIC_)
192       O << "@PLT";
193
194     return;
195   }
196   default:
197     assert(0 && "Not implemented yet!");
198   }
199 }
200
201
202 void SystemZAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
203                                      const char* Modifier) {
204   const MachineOperand &MO = MI->getOperand(OpNum);
205   switch (MO.getType()) {
206   case MachineOperand::MO_Register: {
207     assert (TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
208             "Virtual registers should be already mapped!");
209     unsigned Reg = MO.getReg();
210     if (Modifier && strncmp(Modifier, "subreg", 6) == 0) {
211       if (strncmp(Modifier + 7, "even", 4) == 0)
212         Reg = TRI->getSubReg(Reg, SystemZ::SUBREG_EVEN);
213       else if (strncmp(Modifier + 7, "odd", 3) == 0)
214         Reg = TRI->getSubReg(Reg, SystemZ::SUBREG_ODD);
215       else
216         assert(0 && "Invalid subreg modifier");
217     }
218
219     O << '%' << TRI->getAsmName(Reg);
220     return;
221   }
222   case MachineOperand::MO_Immediate:
223     O << MO.getImm();
224     return;
225   case MachineOperand::MO_MachineBasicBlock:
226     printBasicBlockLabel(MO.getMBB());
227     return;
228   case MachineOperand::MO_JumpTableIndex:
229     O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
230       << MO.getIndex();
231
232     return;
233   case MachineOperand::MO_ConstantPoolIndex:
234     O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
235       << MO.getIndex();
236
237     printOffset(MO.getOffset());
238     break;
239   case MachineOperand::MO_GlobalAddress: {
240     const GlobalValue *GV = MO.getGlobal();
241     std::string Name = Mang->getMangledName(GV);
242
243     O << Name;
244     break;
245   }
246   case MachineOperand::MO_ExternalSymbol: {
247     std::string Name(TAI->getGlobalPrefix());
248     Name += MO.getSymbolName();
249     O << Name;
250     break;
251   }
252   default:
253     assert(0 && "Not implemented yet!");
254   }
255
256   switch (MO.getTargetFlags()) {
257   default:
258     llvm_unreachable("Unknown target flag on GV operand");
259   case SystemZII::MO_NO_FLAG:
260     break;
261   case SystemZII::MO_GOTENT:    O << "@GOTENT";    break;
262   case SystemZII::MO_PLT:       O << "@PLT";       break;
263   }
264
265   printOffset(MO.getOffset());
266 }
267
268 void SystemZAsmPrinter::printRIAddrOperand(const MachineInstr *MI, int OpNum,
269                                            const char* Modifier) {
270   const MachineOperand &Base = MI->getOperand(OpNum);
271
272   // Print displacement operand.
273   printOperand(MI, OpNum+1);
274
275   // Print base operand (if any)
276   if (Base.getReg()) {
277     O << '(';
278     printOperand(MI, OpNum);
279     O << ')';
280   }
281 }
282
283 void SystemZAsmPrinter::printRRIAddrOperand(const MachineInstr *MI, int OpNum,
284                                             const char* Modifier) {
285   const MachineOperand &Base = MI->getOperand(OpNum);
286   const MachineOperand &Index = MI->getOperand(OpNum+2);
287
288   // Print displacement operand.
289   printOperand(MI, OpNum+1);
290
291   // Print base operand (if any)
292   if (Base.getReg()) {
293     O << '(';
294     printOperand(MI, OpNum);
295     if (Index.getReg()) {
296       O << ',';
297       printOperand(MI, OpNum+2);
298     }
299     O << ')';
300   } else
301     assert(!Index.getReg() && "Should allocate base register first!");
302 }
303
304 /// PrintUnmangledNameSafely - Print out the printable characters in the name.
305 /// Don't print things like \\n or \\0.
306 static void PrintUnmangledNameSafely(const Value *V, formatted_raw_ostream &OS) {
307   for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
308        Name != E; ++Name)
309     if (isprint(*Name))
310       OS << *Name;
311 }
312
313 void SystemZAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
314   const TargetData *TD = TM.getTargetData();
315
316   if (!GVar->hasInitializer())
317     return;   // External global require no code
318
319   // Check to see if this is a special global used by LLVM, if so, emit it.
320   if (EmitSpecialLLVMGlobal(GVar))
321     return;
322
323   std::string name = Mang->getMangledName(GVar);
324   Constant *C = GVar->getInitializer();
325   unsigned Size = TD->getTypeAllocSize(C->getType());
326   unsigned Align = std::max(1U, TD->getPreferredAlignmentLog(GVar));
327
328   printVisibility(name, GVar->getVisibility());
329
330   O << "\t.type\t" << name << ",@object\n";
331
332   SwitchToSection(TAI->SectionForGlobal(GVar));
333
334   if (C->isNullValue() && !GVar->hasSection() &&
335       !GVar->isThreadLocal() &&
336       (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
337
338     if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
339
340     if (GVar->hasLocalLinkage())
341       O << "\t.local\t" << name << '\n';
342
343     O << TAI->getCOMMDirective()  << name << ',' << Size;
344     if (TAI->getCOMMDirectiveTakesAlignment())
345       O << ',' << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
346
347     if (VerboseAsm) {
348       O << "\t\t" << TAI->getCommentString() << ' ';
349       PrintUnmangledNameSafely(GVar, O);
350     }
351     O << '\n';
352     return;
353   }
354
355   switch (GVar->getLinkage()) {
356   case GlobalValue::CommonLinkage:
357   case GlobalValue::LinkOnceAnyLinkage:
358   case GlobalValue::LinkOnceODRLinkage:
359   case GlobalValue::WeakAnyLinkage:
360   case GlobalValue::WeakODRLinkage:
361     O << "\t.weak\t" << name << '\n';
362     break;
363   case GlobalValue::DLLExportLinkage:
364   case GlobalValue::AppendingLinkage:
365     // FIXME: appending linkage variables should go into a section of
366     // their name or something.  For now, just emit them as external.
367   case GlobalValue::ExternalLinkage:
368     // If external or appending, declare as a global symbol
369     O << "\t.globl " << name << '\n';
370     // FALL THROUGH
371   case GlobalValue::PrivateLinkage:
372   case GlobalValue::LinkerPrivateLinkage:
373   case GlobalValue::InternalLinkage:
374      break;
375   default:
376     assert(0 && "Unknown linkage type!");
377   }
378
379   // Use 16-bit alignment by default to simplify bunch of stuff
380   EmitAlignment(Align, GVar, 1);
381   O << name << ":";
382   if (VerboseAsm) {
383     O << "\t\t\t\t" << TAI->getCommentString() << ' ';
384     PrintUnmangledNameSafely(GVar, O);
385   }
386   O << '\n';
387   if (TAI->hasDotTypeDotSizeDirective())
388     O << "\t.size\t" << name << ", " << Size << '\n';
389
390   EmitGlobalConstant(C);
391 }
392
393 // Force static initialization.
394 extern "C" void LLVMInitializeSystemZAsmPrinter() {
395   RegisterAsmPrinter<SystemZAsmPrinter> X(TheSystemZTarget);
396 }