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