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