1 //===-- PIC16TargetObjectFile.cpp - PIC16 object files --------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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"
18 PIC16TargetObjectFile::PIC16TargetObjectFile()
19 : ExternalVarDecls(0), ExternalVarDefs(0) {
22 void PIC16TargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &tm){
23 TargetLoweringObjectFile::Initialize(Ctx, tm);
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());
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());
38 ROSections.push_back(new PIC16Section(ReadOnlySection));
40 // FIXME: I don't know what the classification of these sections really is.
41 ExternalVarDecls = new PIC16Section(getOrCreateSection("ExternalVarDecls",
43 SectionKind::getMetadata()));
44 ExternalVarDefs = new PIC16Section(getOrCreateSection("ExternalVarDefs",
46 SectionKind::getMetadata()));
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());
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());
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");
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);
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];
83 // No BSS section spacious enough was found. Crate a new one.
85 std::string name = PAN::getUdataSectionName(BSSSections.size());
86 const MCSection *NewSection = getOrCreateSection(name.c_str(), false,
88 SectionKind::getMetadata());
90 FoundBSS = new PIC16Section(NewSection);
92 // Add this newly created BSS section to the list of BSSSections.
93 BSSSections.push_back(FoundBSS);
96 // Insert the GV into this BSS.
97 FoundBSS->Items.push_back(GV);
98 FoundBSS->Size += ValSize;
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");
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);
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];
125 // No IDATA section spacious enough was found. Crate a new one.
127 std::string name = PAN::getIdataSectionName(IDATASections.size());
128 const MCSection *NewSection = getOrCreateSection(name.c_str(), false,
130 SectionKind::getMetadata());
132 FoundIDATA = new PIC16Section(NewSection);
134 // Add this newly created IDATA section to the list of IDATASections.
135 IDATASections.push_back(FoundIDATA);
138 // Insert the GV into this IDATA.
139 FoundIDATA->Items.push_back(GV);
140 FoundIDATA->Size += ValSize;
141 return FoundIDATA->S_;
144 // Get the section for an automatic variable of a function.
145 // For PIC16 they are globals only with mangled names.
147 PIC16TargetObjectFile::getSectionForAuto(const GlobalVariable *GV) const {
149 const std::string name = PAN::getSectionNameForSym(GV->getName());
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];
161 // No Auto section was found. Crate a new one.
163 const MCSection *NewSection = getOrCreateSection(name.c_str(),
166 SectionKind::getMetadata());
168 FoundAutoSec = new PIC16Section(NewSection);
170 // Add this newly created autos section to the list of AutosSections.
171 AutosSections.push_back(FoundAutoSec);
174 // Insert the auto into this section.
175 FoundAutoSec->Items.push_back(GV);
177 return FoundAutoSec->S_;
181 // Override default implementation to put the true globals into
182 // multiple data sections if required.
184 PIC16TargetObjectFile::SelectSectionForGlobal(const GlobalValue *GV1,
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);
192 return TargetLoweringObjectFile::SelectSectionForGlobal(GV1, Kind, Mang,TM);
194 // Record External Var Decls.
195 if (GV->isDeclaration()) {
196 ExternalVarDecls->Items.push_back(GV);
197 return ExternalVarDecls->S_;
200 assert(GV->hasInitializer() && "A def without initializer?");
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);
208 // Record Exteranl Var Defs.
209 if (GV->hasExternalLinkage() || GV->hasCommonLinkage())
210 ExternalVarDefs->Items.push_back(GV);
212 // See if this is an uninitialized global.
213 const Constant *C = GV->getInitializer();
214 if (C->isNullValue())
215 return getBSSSectionForGlobal(GV);
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);
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);
225 // Else let the default implementation take care of it.
226 return TargetLoweringObjectFile::SelectSectionForGlobal(GV, Kind, Mang,TM);
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;
243 /// getSpecialCasedSectionGlobals - Allow the target to completely override
244 /// section assignment of a global.
246 PIC16TargetObjectFile::getSpecialCasedSectionGlobals(const GlobalValue *GV,
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
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);
261 // Create the section specified with section attribute.
262 return CreateSectionForGlobal(GVar, Mang);
269 // Create a new section for global variable. If Addr is given then create
270 // section at that address else create by name.
272 PIC16TargetObjectFile::CreateSectionForGlobal(const GlobalVariable *GV,
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);
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);
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);
288 // Else let the default implementation take care of it.
289 return TargetLoweringObjectFile::SectionForGlobal(GV, Mang, *TM);
292 // Create uninitialized section for a variable.
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");
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;
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];
312 std::string Prefix = GV->getNameStr() + "." + Addr + ".";
313 Name = PAN::getUdataSectionName(BSSSections.size(), Prefix) + " " + Addr;
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);
324 // Insert the GV into this BSS.
325 NewBSS->Items.push_back(GV);
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;
333 // Get rom section for a variable. Currently there can be only one rom section
334 // unless a variable explicitly requests a section.
336 PIC16TargetObjectFile::getROSectionForGlobal(const GlobalVariable *GV) const {
337 ROSections[0]->Items.push_back(GV);
338 return ROSections[0]->S_;
341 // Create initialized data section for a variable.
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");
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;
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];
364 std::string Prefix = GV->getNameStr() + "." + Addr + ".";
365 Name = PAN::getIdataSectionName(IDATASections.size(), Prefix) + " " + Addr;
368 PIC16Section *NewIDATASec = FoundIDATASec;
369 if (NewIDATASec == NULL) {
370 const MCSection *NewSection = getOrCreateSection(Name.c_str(), false,
372 SectionKind::getMetadata());
373 NewIDATASec = new PIC16Section(NewSection);
374 IDATASections.push_back(NewIDATASec);
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_;
384 // Create a section in rom for a variable.
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");
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;
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];
404 std::string Prefix = GV->getNameStr() + "." + Addr + ".";
405 Name = PAN::getRomdataSectionName(ROSections.size(), Prefix) + " " + Addr;
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);
416 // Insert the GV into this ROM Section.
417 NewRomSec->Items.push_back(GV);
418 return NewRomSec->S_;