blob: 78e88ca935cdb32b179c07449945b8b5be930d76 [file] [log] [blame]
Chris Lattnerf0144122009-07-28 03:13:23 +00001//===-- 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"
Chris Lattnera87dea42009-07-31 18:48:30 +000015#include "llvm/MC/MCSection.h"
Chris Lattnerf0144122009-07-28 03:13:23 +000016using namespace llvm;
17
Chris Lattnera87dea42009-07-31 18:48:30 +000018void PIC16TargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &tm){
19 TargetLoweringObjectFile::Initialize(Ctx, tm);
20 TM = &tm;
21
Chris Lattner968ff112009-08-01 21:11:14 +000022 BSSSection_ = getOrCreateSection("udata.# UDATA", false,
23 SectionKind::get(SectionKind::BSS));
Chris Lattnerf0144122009-07-28 03:13:23 +000024 ReadOnlySection = getOrCreateSection("romdata.# ROMDATA", false,
Chris Lattner968ff112009-08-01 21:11:14 +000025 SectionKind::get(SectionKind::ReadOnly));
26 DataSection = getOrCreateSection("idata.# IDATA", false,
27 SectionKind::get(SectionKind::DataRel));
Chris Lattnerf0144122009-07-28 03:13:23 +000028
29 // Need because otherwise a .text symbol is emitted by DwarfWriter
30 // in BeginModule, and gpasm cribbs for that .text symbol.
Chris Lattner968ff112009-08-01 21:11:14 +000031 TextSection = getOrCreateSection("", true,
32 SectionKind::get(SectionKind::Text));
Chris Lattnerf0144122009-07-28 03:13:23 +000033
Chris Lattnera87dea42009-07-31 18:48:30 +000034 ROSections.push_back(new PIC16Section(ReadOnlySection));
Chris Lattnerf0144122009-07-28 03:13:23 +000035
36 // FIXME: I don't know what the classification of these sections really is.
37 ExternalVarDecls = new PIC16Section(getOrCreateSection("ExternalVarDecls",
38 false,
Chris Lattner968ff112009-08-01 21:11:14 +000039 SectionKind::get(SectionKind::Metadata)));
Chris Lattnerf0144122009-07-28 03:13:23 +000040 ExternalVarDefs = new PIC16Section(getOrCreateSection("ExternalVarDefs",
41 false,
Chris Lattner968ff112009-08-01 21:11:14 +000042 SectionKind::get(SectionKind::Metadata)));
Chris Lattnerf0144122009-07-28 03:13:23 +000043}
44
45
Chris Lattnera87dea42009-07-31 18:48:30 +000046const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +000047PIC16TargetObjectFile::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.
Chris Lattnera87dea42009-07-31 18:48:30 +000053 const TargetData *TD = TM->getTargetData();
Chris Lattnerf0144122009-07-28 03:13:23 +000054 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());
Chris Lattnera87dea42009-07-31 18:48:30 +000070 const MCSection *NewSection = getOrCreateSection(name.c_str(), false,
71 // FIXME.
Chris Lattner968ff112009-08-01 21:11:14 +000072 SectionKind::get(SectionKind::Metadata));
Chris Lattnerf0144122009-07-28 03:13:23 +000073
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
Chris Lattnera87dea42009-07-31 18:48:30 +000086const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +000087PIC16TargetObjectFile::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.
Chris Lattnera87dea42009-07-31 18:48:30 +000095 const TargetData *TD = TM->getTargetData();
Chris Lattnerf0144122009-07-28 03:13:23 +000096 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());
Chris Lattnera87dea42009-07-31 18:48:30 +0000112 const MCSection *NewSection = getOrCreateSection(name.c_str(), false,
Chris Lattnerf0144122009-07-28 03:13:23 +0000113 // FIXME.
Chris Lattner968ff112009-08-01 21:11:14 +0000114 SectionKind::get(SectionKind::Metadata));
Chris Lattnerf0144122009-07-28 03:13:23 +0000115
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.
Chris Lattnera87dea42009-07-31 18:48:30 +0000130const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000131PIC16TargetObjectFile::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) {
Chris Lattnera87dea42009-07-31 18:48:30 +0000147 const MCSection *NewSection = getOrCreateSection(name.c_str(),
148 // FIXME.
149 false,
Chris Lattner968ff112009-08-01 21:11:14 +0000150 SectionKind::get(SectionKind::Metadata));
Chris Lattnerf0144122009-07-28 03:13:23 +0000151
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.
Chris Lattnera87dea42009-07-31 18:48:30 +0000167const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000168PIC16TargetObjectFile::SelectSectionForGlobal(const GlobalValue *GV1,
Chris Lattnerf9650c02009-08-01 21:46:23 +0000169 SectionKind Kind,
Chris Lattnere53a6002009-07-29 05:09:30 +0000170 Mangler *Mang,
Chris Lattnerf0144122009-07-28 03:13:23 +0000171 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)
Chris Lattnerf9650c02009-08-01 21:46:23 +0000176 return TargetLoweringObjectFile::SelectSectionForGlobal(GV1, Kind, Mang,TM);
Chris Lattnerf0144122009-07-28 03:13:23 +0000177
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.
Chris Lattnerf9650c02009-08-01 21:46:23 +0000210 return TargetLoweringObjectFile::SelectSectionForGlobal(GV, Kind, Mang,TM);
Chris Lattnerf0144122009-07-28 03:13:23 +0000211}
212
213PIC16TargetObjectFile::~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.
Chris Lattnera87dea42009-07-31 18:48:30 +0000229const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000230PIC16TargetObjectFile::getSpecialCasedSectionGlobals(const GlobalValue *GV,
Chris Lattnere53a6002009-07-29 05:09:30 +0000231 Mangler *Mang,
Chris Lattnerf9650c02009-08-01 21:46:23 +0000232 SectionKind Kind) const {
Chris Lattnerf0144122009-07-28 03:13:23 +0000233 // 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());
Chris Lattnere53a6002009-07-29 05:09:30 +0000242 return CreateSectionForGlobal(GVar, Mang, SectAddr);
Chris Lattnerf0144122009-07-28 03:13:23 +0000243 }
244
245 // Create the section specified with section attribute.
Chris Lattnere53a6002009-07-29 05:09:30 +0000246 return CreateSectionForGlobal(GVar, Mang);
Chris Lattnerf0144122009-07-28 03:13:23 +0000247 }
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.
Chris Lattnera87dea42009-07-31 18:48:30 +0000255const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000256PIC16TargetObjectFile::CreateSectionForGlobal(const GlobalVariable *GV,
Chris Lattnere53a6002009-07-29 05:09:30 +0000257 Mangler *Mang,
Chris Lattnerf0144122009-07-28 03:13:23 +0000258 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.
Chris Lattnera87dea42009-07-31 18:48:30 +0000273 return TargetLoweringObjectFile::SectionForGlobal(GV, Mang, *TM);
Chris Lattnerf0144122009-07-28 03:13:23 +0000274}
275
276// Create uninitialized section for a variable.
Chris Lattnera87dea42009-07-31 18:48:30 +0000277const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000278PIC16TargetObjectFile::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) {
Chris Lattnera87dea42009-07-31 18:48:30 +0000302 const MCSection *NewSection = getOrCreateSection(Name.c_str(), false,
Chris Lattner968ff112009-08-01 21:11:14 +0000303 SectionKind::get(SectionKind::BSS));
Chris Lattnerf0144122009-07-28 03:13:23 +0000304 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.
Chris Lattnera87dea42009-07-31 18:48:30 +0000319const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000320PIC16TargetObjectFile::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.
Chris Lattnera87dea42009-07-31 18:48:30 +0000326const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000327PIC16TargetObjectFile::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) {
Chris Lattnera87dea42009-07-31 18:48:30 +0000354 const MCSection *NewSection = getOrCreateSection(Name.c_str(), false,
Chris Lattnerf0144122009-07-28 03:13:23 +0000355 // FIXME:
Chris Lattner968ff112009-08-01 21:11:14 +0000356 SectionKind::get(SectionKind::Metadata));
Chris Lattnerf0144122009-07-28 03:13:23 +0000357 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.
Chris Lattnera87dea42009-07-31 18:48:30 +0000369const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000370PIC16TargetObjectFile::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) {
Chris Lattnera87dea42009-07-31 18:48:30 +0000394 const MCSection *NewSection = getOrCreateSection(Name.c_str(), false,
Chris Lattner968ff112009-08-01 21:11:14 +0000395 SectionKind::get(SectionKind::ReadOnly));
Chris Lattnerf0144122009-07-28 03:13:23 +0000396 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