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