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