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