Revert "Complete Rewrite of AsmPrinter, TargetObjectFile based on new
[oota-llvm.git] / lib / Target / PIC16 / PIC16TargetObjectFile.cpp
1 //===-- PIC16TargetObjectFile.cpp - PIC16 object files --------------------===//
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 #include "PIC16TargetObjectFile.h"
11 #include "MCSectionPIC16.h"
12 #include "PIC16ISelLowering.h"
13 #include "PIC16TargetMachine.h"
14 #include "llvm/DerivedTypes.h"
15 #include "llvm/Module.h"
16 #include "llvm/MC/MCSection.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/Support/raw_ostream.h"
19 using namespace llvm;
20
21
22 MCSectionPIC16 *MCSectionPIC16::Create(const StringRef &Name, SectionKind K, 
23                                        int Address, int Color, MCContext &Ctx) {
24   return new (Ctx) MCSectionPIC16(Name, K, Address, Color);
25 }
26
27
28 void MCSectionPIC16::PrintSwitchToSection(const MCAsmInfo &MAI,
29                                           raw_ostream &OS) const {
30   OS << getName() << '\n';
31 }
32
33
34
35
36 PIC16TargetObjectFile::PIC16TargetObjectFile()
37   : ExternalVarDecls(0), ExternalVarDefs(0) {
38 }
39
40 const MCSectionPIC16 *PIC16TargetObjectFile::
41 getPIC16Section(const char *Name, SectionKind Kind, 
42                 int Address, int Color) const {
43   MCSectionPIC16 *&Entry = SectionsByName[Name];
44   if (Entry)
45     return Entry;
46
47   return Entry = MCSectionPIC16::Create(Name, Kind, Address, Color, 
48                                         getContext());
49 }
50
51
52 void PIC16TargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &tm){
53   TargetLoweringObjectFile::Initialize(Ctx, tm);
54   TM = &tm;
55   
56   BSSSection = getPIC16Section("udata.# UDATA", MCSectionPIC16::UDATA_Kind());
57   ReadOnlySection = getPIC16Section("romdata.# ROMDATA", 
58                                     MCSectionPIC16::ROMDATA_Kind());
59   DataSection = getPIC16Section("idata.# IDATA", MCSectionPIC16::IDATA_Kind());
60   
61   // Need because otherwise a .text symbol is emitted by DwarfWriter
62   // in BeginModule, and gpasm cribbs for that .text symbol.
63   TextSection = getPIC16Section("", SectionKind::getText());
64
65   ROSections.push_back(new PIC16Section((MCSectionPIC16*)ReadOnlySection));
66   
67   // FIXME: I don't know what the classification of these sections really is.
68   // These aren't really objects belonging to any section. Just emit them
69   // in AsmPrinter and remove this code from here. 
70   ExternalVarDecls = new PIC16Section(getPIC16Section("ExternalVarDecls",
71                                       SectionKind::getMetadata()));
72   ExternalVarDefs = new PIC16Section(getPIC16Section("ExternalVarDefs",
73                                       SectionKind::getMetadata()));
74 }
75
76 const MCSection *PIC16TargetObjectFile::
77 getSectionForFunction(const std::string &FnName) const {
78   std::string T = PAN::getCodeSectionName(FnName);
79   return getPIC16Section(T.c_str(), SectionKind::getText());
80 }
81
82
83 const MCSection *PIC16TargetObjectFile::
84 getSectionForFunctionFrame(const std::string &FnName) const {
85   std::string T = PAN::getFrameSectionName(FnName);
86   return getPIC16Section(T.c_str(), SectionKind::getDataRel());
87 }
88
89 const MCSection *
90 PIC16TargetObjectFile::getBSSSectionForGlobal(const GlobalVariable *GV) const {
91   assert(GV->hasInitializer() && "This global doesn't need space");
92   Constant *C = GV->getInitializer();
93   assert(C->isNullValue() && "Unitialized globals has non-zero initializer");
94
95   // Find how much space this global needs.
96   const TargetData *TD = TM->getTargetData();
97   const Type *Ty = C->getType(); 
98   unsigned ValSize = TD->getTypeAllocSize(Ty);
99  
100   // Go through all BSS Sections and assign this variable
101   // to the first available section having enough space.
102   PIC16Section *FoundBSS = NULL;
103   for (unsigned i = 0; i < BSSSections.size(); i++) {
104     if (DataBankSize - BSSSections[i]->Size >= ValSize) {
105       FoundBSS = BSSSections[i];
106       break;
107     }
108   }
109
110   // No BSS section spacious enough was found. Crate a new one.
111   if (!FoundBSS) {
112     std::string name = PAN::getUdataSectionName(BSSSections.size());
113     const MCSectionPIC16 *NewSection
114       = getPIC16Section(name.c_str(), MCSectionPIC16::UDATA_Kind());
115
116     FoundBSS = new PIC16Section(NewSection);
117
118     // Add this newly created BSS section to the list of BSSSections.
119     BSSSections.push_back(FoundBSS);
120   }
121   
122   // Insert the GV into this BSS.
123   FoundBSS->Items.push_back(GV);
124   FoundBSS->Size += ValSize;
125   return FoundBSS->S_;
126
127
128 const MCSection *
129 PIC16TargetObjectFile::getIDATASectionForGlobal(const GlobalVariable *GV) const{
130   assert(GV->hasInitializer() && "This global doesn't need space");
131   Constant *C = GV->getInitializer();
132   assert(!C->isNullValue() && "initialized globals has zero initializer");
133   assert(GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
134          "can split initialized RAM data only");
135
136   // Find how much space this global needs.
137   const TargetData *TD = TM->getTargetData();
138   const Type *Ty = C->getType(); 
139   unsigned ValSize = TD->getTypeAllocSize(Ty);
140  
141   // Go through all IDATA Sections and assign this variable
142   // to the first available section having enough space.
143   PIC16Section *FoundIDATA = NULL;
144   for (unsigned i = 0; i < IDATASections.size(); i++) {
145     if (DataBankSize - IDATASections[i]->Size >= ValSize) {
146       FoundIDATA = IDATASections[i]; 
147       break;
148     }
149   }
150
151   // No IDATA section spacious enough was found. Crate a new one.
152   if (!FoundIDATA) {
153     std::string name = PAN::getIdataSectionName(IDATASections.size());
154     const MCSectionPIC16 *NewSection =
155       getPIC16Section(name.c_str(), MCSectionPIC16::IDATA_Kind());
156
157     FoundIDATA = new PIC16Section(NewSection);
158
159     // Add this newly created IDATA section to the list of IDATASections.
160     IDATASections.push_back(FoundIDATA);
161   }
162   
163   // Insert the GV into this IDATA.
164   FoundIDATA->Items.push_back(GV);
165   FoundIDATA->Size += ValSize;
166   return FoundIDATA->S_;
167
168
169 // Get the section for an automatic variable of a function.
170 // For PIC16 they are globals only with mangled names.
171 const MCSection *
172 PIC16TargetObjectFile::getSectionForAuto(const GlobalVariable *GV) const {
173
174   const std::string name = PAN::getSectionNameForSym(GV->getName());
175
176   // Go through all Auto Sections and assign this variable
177   // to the appropriate section.
178   PIC16Section *FoundAutoSec = NULL;
179   for (unsigned i = 0; i < AutosSections.size(); i++) {
180     if (AutosSections[i]->S_->getName() == name) {
181       FoundAutoSec = AutosSections[i];
182       break;
183     }
184   }
185
186   // No Auto section was found. Crate a new one.
187   if (!FoundAutoSec) {
188     const MCSectionPIC16 *NewSection =
189       getPIC16Section(name.c_str(), MCSectionPIC16::UDATA_OVR_Kind());
190
191     FoundAutoSec = new PIC16Section(NewSection);
192
193     // Add this newly created autos section to the list of AutosSections.
194     AutosSections.push_back(FoundAutoSec);
195   }
196
197   // Insert the auto into this section.
198   FoundAutoSec->Items.push_back(GV);
199
200   return FoundAutoSec->S_;
201 }
202
203
204 // Override default implementation to put the true globals into
205 // multiple data sections if required.
206 const MCSection *
207 PIC16TargetObjectFile::SelectSectionForGlobal(const GlobalValue *GV1,
208                                               SectionKind Kind,
209                                               Mangler *Mang,
210                                               const TargetMachine &TM) const {
211   // We select the section based on the initializer here, so it really
212   // has to be a GlobalVariable.
213   const GlobalVariable *GV = dyn_cast<GlobalVariable>(GV1); 
214   if (!GV)
215     return TargetLoweringObjectFile::SelectSectionForGlobal(GV1, Kind, Mang,TM);
216
217   // Record External Var Decls.
218   if (GV->isDeclaration()) {
219     ExternalVarDecls->Items.push_back(GV);
220     return ExternalVarDecls->S_;
221   }
222     
223   assert(GV->hasInitializer() && "A def without initializer?");
224
225   // First, if this is an automatic variable for a function, get the section
226   // name for it and return.
227   std::string name = GV->getName();
228   if (PAN::isLocalName(name))
229     return getSectionForAuto(GV);
230
231   // Record Exteranl Var Defs.
232   if (GV->hasExternalLinkage() || GV->hasCommonLinkage())
233     ExternalVarDefs->Items.push_back(GV);
234
235   // See if this is an uninitialized global.
236   const Constant *C = GV->getInitializer();
237   if (C->isNullValue()) 
238     return getBSSSectionForGlobal(GV); 
239
240   // If this is initialized data in RAM. Put it in the correct IDATA section.
241   if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) 
242     return getIDATASectionForGlobal(GV);
243
244   // This is initialized data in rom, put it in the readonly section.
245   if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) 
246     return getROSectionForGlobal(GV);
247
248   // Else let the default implementation take care of it.
249   return TargetLoweringObjectFile::SelectSectionForGlobal(GV, Kind, Mang,TM);
250 }
251
252 PIC16TargetObjectFile::~PIC16TargetObjectFile() {
253   for (unsigned i = 0; i < BSSSections.size(); i++)
254     delete BSSSections[i]; 
255   for (unsigned i = 0; i < IDATASections.size(); i++)
256     delete IDATASections[i]; 
257   for (unsigned i = 0; i < AutosSections.size(); i++)
258     delete AutosSections[i]; 
259   for (unsigned i = 0; i < ROSections.size(); i++)
260     delete ROSections[i];
261   delete ExternalVarDecls;
262   delete ExternalVarDefs;
263 }
264
265
266 /// getSpecialCasedSectionGlobals - Allow the target to completely override
267 /// section assignment of a global.
268 const MCSection *PIC16TargetObjectFile::
269 getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, 
270                          Mangler *Mang, const TargetMachine &TM) const {
271   assert(GV->hasSection());
272   
273   if (const GlobalVariable *GVar = cast<GlobalVariable>(GV)) {
274     std::string SectName = GVar->getSection();
275     // If address for a variable is specified, get the address and create
276     // section.
277     std::string AddrStr = "Address=";
278     if (SectName.compare(0, AddrStr.length(), AddrStr) == 0) {
279       std::string SectAddr = SectName.substr(AddrStr.length());
280       return CreateSectionForGlobal(GVar, Mang, SectAddr);
281     }
282      
283     // Create the section specified with section attribute. 
284     return CreateSectionForGlobal(GVar, Mang);
285   }
286
287   return getPIC16Section(GV->getSection().c_str(), Kind);
288 }
289
290 // Create a new section for global variable. If Addr is given then create
291 // section at that address else create by name.
292 const MCSection *
293 PIC16TargetObjectFile::CreateSectionForGlobal(const GlobalVariable *GV,
294                                               Mangler *Mang,
295                                               const std::string &Addr) const {
296   // See if this is an uninitialized global.
297   const Constant *C = GV->getInitializer();
298   if (C->isNullValue())
299     return CreateBSSSectionForGlobal(GV, Addr);
300
301   // If this is initialized data in RAM. Put it in the correct IDATA section.
302   if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE)
303     return CreateIDATASectionForGlobal(GV, Addr);
304
305   // This is initialized data in rom, put it in the readonly section.
306   if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) 
307     return CreateROSectionForGlobal(GV, Addr);
308
309   // Else let the default implementation take care of it.
310   return TargetLoweringObjectFile::SectionForGlobal(GV, Mang, *TM);
311 }
312
313 // Create uninitialized section for a variable.
314 const MCSection *
315 PIC16TargetObjectFile::CreateBSSSectionForGlobal(const GlobalVariable *GV,
316                                                  std::string Addr) const {
317   assert(GV->hasInitializer() && "This global doesn't need space");
318   assert(GV->getInitializer()->isNullValue() &&
319          "Unitialized global has non-zero initializer");
320   std::string Name;
321   // If address is given then create a section at that address else create a
322   // section by section name specified in GV.
323   PIC16Section *FoundBSS = NULL;
324   if (Addr.empty()) { 
325     Name = GV->getSection() + " UDATA";
326     for (unsigned i = 0; i < BSSSections.size(); i++) {
327       if (BSSSections[i]->S_->getName() == Name) {
328         FoundBSS = BSSSections[i];
329         break;
330       }
331     }
332   } else {
333     std::string Prefix = GV->getNameStr() + "." + Addr + ".";
334     Name = PAN::getUdataSectionName(BSSSections.size(), Prefix) + " " + Addr;
335   }
336   
337   PIC16Section *NewBSS = FoundBSS;
338   if (NewBSS == NULL) {
339     const MCSectionPIC16 *NewSection =
340       getPIC16Section(Name.c_str(), MCSectionPIC16::UDATA_Kind());
341     NewBSS = new PIC16Section(NewSection);
342     BSSSections.push_back(NewBSS);
343   }
344
345   // Insert the GV into this BSS.
346   NewBSS->Items.push_back(GV);
347
348   // We do not want to put any  GV without explicit section into this section
349   // so set its size to DatabankSize.
350   NewBSS->Size = DataBankSize;
351   return NewBSS->S_;
352 }
353
354 // Get rom section for a variable. Currently there can be only one rom section
355 // unless a variable explicitly requests a section.
356 const MCSection *
357 PIC16TargetObjectFile::getROSectionForGlobal(const GlobalVariable *GV) const {
358   ROSections[0]->Items.push_back(GV);
359   return ROSections[0]->S_;
360 }
361
362 // Create initialized data section for a variable.
363 const MCSection *
364 PIC16TargetObjectFile::CreateIDATASectionForGlobal(const GlobalVariable *GV,
365                                                    std::string Addr) const {
366   assert(GV->hasInitializer() && "This global doesn't need space");
367   assert(!GV->getInitializer()->isNullValue() &&
368          "initialized global has zero initializer");
369   assert(GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
370          "can be used for initialized RAM data only");
371
372   std::string Name;
373   // If address is given then create a section at that address else create a
374   // section by section name specified in GV.
375   PIC16Section *FoundIDATASec = NULL;
376   if (Addr.empty()) {
377     Name = GV->getSection() + " IDATA";
378     for (unsigned i = 0; i < IDATASections.size(); i++) {
379       if (IDATASections[i]->S_->getName() == Name) {
380         FoundIDATASec = IDATASections[i];
381         break;
382       }
383     }
384   } else {
385     std::string Prefix = GV->getNameStr() + "." + Addr + ".";
386     Name = PAN::getIdataSectionName(IDATASections.size(), Prefix) + " " + Addr;
387   }
388
389   PIC16Section *NewIDATASec = FoundIDATASec;
390   if (NewIDATASec == NULL) {
391     const MCSectionPIC16 *NewSection =
392       getPIC16Section(Name.c_str(), MCSectionPIC16::IDATA_Kind());
393     NewIDATASec = new PIC16Section(NewSection);
394     IDATASections.push_back(NewIDATASec);
395   }
396   // Insert the GV into this IDATA Section.
397   NewIDATASec->Items.push_back(GV);
398   // We do not want to put any  GV without explicit section into this section 
399   // so set its size to DatabankSize.
400   NewIDATASec->Size = DataBankSize;
401   return NewIDATASec->S_;
402 }
403
404 // Create a section in rom for a variable.
405 const MCSection *
406 PIC16TargetObjectFile::CreateROSectionForGlobal(const GlobalVariable *GV,
407                                                 std::string Addr) const {
408   assert(GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE &&
409          "can be used for ROM data only");
410
411   std::string Name;
412   // If address is given then create a section at that address else create a
413   // section by section name specified in GV.
414   PIC16Section *FoundROSec = NULL;
415   if (Addr.empty()) {
416     Name = GV->getSection() + " ROMDATA";
417     for (unsigned i = 1; i < ROSections.size(); i++) {
418       if (ROSections[i]->S_->getName() == Name) {
419         FoundROSec = ROSections[i];
420         break;
421       }
422     }
423   } else {
424     std::string Prefix = GV->getNameStr() + "." + Addr + ".";
425     Name = PAN::getRomdataSectionName(ROSections.size(), Prefix) + " " + Addr;
426   }
427
428   PIC16Section *NewRomSec = FoundROSec;
429   if (NewRomSec == NULL) {
430     const MCSectionPIC16 *NewSection =
431       getPIC16Section(Name.c_str(), MCSectionPIC16::ROMDATA_Kind());
432     NewRomSec = new PIC16Section(NewSection);
433     ROSections.push_back(NewRomSec);
434   }
435
436   // Insert the GV into this ROM Section.
437   NewRomSec->Items.push_back(GV);
438   return NewRomSec->S_;
439 }
440