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