blob: b09ad305c28222a9e462bf7fc50daecd3cc7f161 [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
Daniel Dunbar967ce7f2009-08-02 01:25:15 +000018PIC16TargetObjectFile::PIC16TargetObjectFile()
Chris Lattner759b8882009-08-06 16:27:28 +000019 : ExternalVarDecls(0), ExternalVarDefs(0) {
Daniel Dunbar967ce7f2009-08-02 01:25:15 +000020}
21
Chris Lattnera87dea42009-07-31 18:48:30 +000022void PIC16TargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &tm){
23 TargetLoweringObjectFile::Initialize(Ctx, tm);
24 TM = &tm;
25
Chris Lattner82458382009-08-01 21:56:13 +000026 BSSSection = getOrCreateSection("udata.# UDATA", false,
Chris Lattner1ef9be22009-08-02 00:02:44 +000027 SectionKind::getBSS());
Chris Lattnerf0144122009-07-28 03:13:23 +000028 ReadOnlySection = getOrCreateSection("romdata.# ROMDATA", false,
Chris Lattner1ef9be22009-08-02 00:02:44 +000029 SectionKind::getReadOnly());
Chris Lattner968ff112009-08-01 21:11:14 +000030 DataSection = getOrCreateSection("idata.# IDATA", false,
Chris Lattner1ef9be22009-08-02 00:02:44 +000031 SectionKind::getDataRel());
Chris Lattnerf0144122009-07-28 03:13:23 +000032
33 // Need because otherwise a .text symbol is emitted by DwarfWriter
34 // in BeginModule, and gpasm cribbs for that .text symbol.
Chris Lattner968ff112009-08-01 21:11:14 +000035 TextSection = getOrCreateSection("", true,
Chris Lattner1ef9be22009-08-02 00:02:44 +000036 SectionKind::getText());
Chris Lattnerf0144122009-07-28 03:13:23 +000037
Chris Lattnera87dea42009-07-31 18:48:30 +000038 ROSections.push_back(new PIC16Section(ReadOnlySection));
Chris Lattnerf0144122009-07-28 03:13:23 +000039
40 // FIXME: I don't know what the classification of these sections really is.
41 ExternalVarDecls = new PIC16Section(getOrCreateSection("ExternalVarDecls",
42 false,
Chris Lattner1ef9be22009-08-02 00:02:44 +000043 SectionKind::getMetadata()));
Chris Lattnerf0144122009-07-28 03:13:23 +000044 ExternalVarDefs = new PIC16Section(getOrCreateSection("ExternalVarDefs",
45 false,
Chris Lattner1ef9be22009-08-02 00:02:44 +000046 SectionKind::getMetadata()));
Chris Lattnerf0144122009-07-28 03:13:23 +000047}
48
Chris Lattner759b8882009-08-06 16:27:28 +000049const MCSection *PIC16TargetObjectFile::
50getSectionForFunction(const std::string &FnName) const {
51 std::string T = PAN::getCodeSectionName(FnName);
52 return getOrCreateSection(T.c_str(), false, SectionKind::getText());
53}
54
55
56const MCSection *PIC16TargetObjectFile::
57getSectionForFunctionFrame(const std::string &FnName) const {
58 std::string T = PAN::getFrameSectionName(FnName);
59 return getOrCreateSection(T.c_str(), false, SectionKind::getDataRel());
60}
Chris Lattnerf0144122009-07-28 03:13:23 +000061
Chris Lattnera87dea42009-07-31 18:48:30 +000062const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +000063PIC16TargetObjectFile::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.
Chris Lattnera87dea42009-07-31 18:48:30 +000069 const TargetData *TD = TM->getTargetData();
Chris Lattnerf0144122009-07-28 03:13:23 +000070 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());
Chris Lattnera87dea42009-07-31 18:48:30 +000086 const MCSection *NewSection = getOrCreateSection(name.c_str(), false,
87 // FIXME.
Chris Lattner1ef9be22009-08-02 00:02:44 +000088 SectionKind::getMetadata());
Chris Lattnerf0144122009-07-28 03:13:23 +000089
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
Chris Lattnera87dea42009-07-31 18:48:30 +0000102const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000103PIC16TargetObjectFile::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.
Chris Lattnera87dea42009-07-31 18:48:30 +0000111 const TargetData *TD = TM->getTargetData();
Chris Lattnerf0144122009-07-28 03:13:23 +0000112 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());
Chris Lattnera87dea42009-07-31 18:48:30 +0000128 const MCSection *NewSection = getOrCreateSection(name.c_str(), false,
Chris Lattnerf0144122009-07-28 03:13:23 +0000129 // FIXME.
Chris Lattner1ef9be22009-08-02 00:02:44 +0000130 SectionKind::getMetadata());
Chris Lattnerf0144122009-07-28 03:13:23 +0000131
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.
Chris Lattnera87dea42009-07-31 18:48:30 +0000146const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000147PIC16TargetObjectFile::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) {
Chris Lattnera87dea42009-07-31 18:48:30 +0000163 const MCSection *NewSection = getOrCreateSection(name.c_str(),
164 // FIXME.
165 false,
Chris Lattner1ef9be22009-08-02 00:02:44 +0000166 SectionKind::getMetadata());
Chris Lattnerf0144122009-07-28 03:13:23 +0000167
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.
Chris Lattnera87dea42009-07-31 18:48:30 +0000183const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000184PIC16TargetObjectFile::SelectSectionForGlobal(const GlobalValue *GV1,
Chris Lattnerf9650c02009-08-01 21:46:23 +0000185 SectionKind Kind,
Chris Lattnere53a6002009-07-29 05:09:30 +0000186 Mangler *Mang,
Chris Lattnerf0144122009-07-28 03:13:23 +0000187 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)
Chris Lattnerf9650c02009-08-01 21:46:23 +0000192 return TargetLoweringObjectFile::SelectSectionForGlobal(GV1, Kind, Mang,TM);
Chris Lattnerf0144122009-07-28 03:13:23 +0000193
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.
Chris Lattnerf9650c02009-08-01 21:46:23 +0000226 return TargetLoweringObjectFile::SelectSectionForGlobal(GV, Kind, Mang,TM);
Chris Lattnerf0144122009-07-28 03:13:23 +0000227}
228
229PIC16TargetObjectFile::~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.
Chris Lattner24f654c2009-08-06 16:39:58 +0000245const MCSection *PIC16TargetObjectFile::
246getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
247 Mangler *Mang, const TargetMachine &TM) const {
248 assert(GV->hasSection());
249
250 if (const GlobalVariable *GVar = cast<GlobalVariable>(GV)) {
251 std::string SectName = GVar->getSection();
252 // If address for a variable is specified, get the address and create
253 // section.
254 std::string AddrStr = "Address=";
255 if (SectName.compare(0, AddrStr.length(), AddrStr) == 0) {
256 std::string SectAddr = SectName.substr(AddrStr.length());
257 return CreateSectionForGlobal(GVar, Mang, SectAddr);
Chris Lattnerf0144122009-07-28 03:13:23 +0000258 }
Chris Lattner24f654c2009-08-06 16:39:58 +0000259
260 // Create the section specified with section attribute.
261 return CreateSectionForGlobal(GVar, Mang);
Chris Lattnerf0144122009-07-28 03:13:23 +0000262 }
263
Chris Lattner24f654c2009-08-06 16:39:58 +0000264 return getOrCreateSection(GV->getSection().c_str(), false, Kind);
Chris Lattnerf0144122009-07-28 03:13:23 +0000265}
266
267// Create a new section for global variable. If Addr is given then create
268// section at that address else create by name.
Chris Lattnera87dea42009-07-31 18:48:30 +0000269const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000270PIC16TargetObjectFile::CreateSectionForGlobal(const GlobalVariable *GV,
Chris Lattnere53a6002009-07-29 05:09:30 +0000271 Mangler *Mang,
Chris Lattnerf0144122009-07-28 03:13:23 +0000272 const std::string &Addr) const {
273 // See if this is an uninitialized global.
274 const Constant *C = GV->getInitializer();
275 if (C->isNullValue())
276 return CreateBSSSectionForGlobal(GV, Addr);
277
278 // If this is initialized data in RAM. Put it in the correct IDATA section.
279 if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE)
280 return CreateIDATASectionForGlobal(GV, Addr);
281
282 // This is initialized data in rom, put it in the readonly section.
283 if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE)
284 return CreateROSectionForGlobal(GV, Addr);
285
286 // Else let the default implementation take care of it.
Chris Lattnera87dea42009-07-31 18:48:30 +0000287 return TargetLoweringObjectFile::SectionForGlobal(GV, Mang, *TM);
Chris Lattnerf0144122009-07-28 03:13:23 +0000288}
289
290// Create uninitialized section for a variable.
Chris Lattnera87dea42009-07-31 18:48:30 +0000291const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000292PIC16TargetObjectFile::CreateBSSSectionForGlobal(const GlobalVariable *GV,
293 std::string Addr) const {
294 assert(GV->hasInitializer() && "This global doesn't need space");
295 assert(GV->getInitializer()->isNullValue() &&
296 "Unitialized global has non-zero initializer");
297 std::string Name;
298 // If address is given then create a section at that address else create a
299 // section by section name specified in GV.
300 PIC16Section *FoundBSS = NULL;
301 if (Addr.empty()) {
302 Name = GV->getSection() + " UDATA";
303 for (unsigned i = 0; i < BSSSections.size(); i++) {
304 if (BSSSections[i]->S_->getName() == Name) {
305 FoundBSS = BSSSections[i];
306 break;
307 }
308 }
309 } else {
310 std::string Prefix = GV->getNameStr() + "." + Addr + ".";
311 Name = PAN::getUdataSectionName(BSSSections.size(), Prefix) + " " + Addr;
312 }
313
314 PIC16Section *NewBSS = FoundBSS;
315 if (NewBSS == NULL) {
Chris Lattnera87dea42009-07-31 18:48:30 +0000316 const MCSection *NewSection = getOrCreateSection(Name.c_str(), false,
Chris Lattner1ef9be22009-08-02 00:02:44 +0000317 SectionKind::getBSS());
Chris Lattnerf0144122009-07-28 03:13:23 +0000318 NewBSS = new PIC16Section(NewSection);
319 BSSSections.push_back(NewBSS);
320 }
321
322 // Insert the GV into this BSS.
323 NewBSS->Items.push_back(GV);
324
325 // We do not want to put any GV without explicit section into this section
326 // so set its size to DatabankSize.
327 NewBSS->Size = DataBankSize;
328 return NewBSS->S_;
329}
330
331// Get rom section for a variable. Currently there can be only one rom section
332// unless a variable explicitly requests a section.
Chris Lattnera87dea42009-07-31 18:48:30 +0000333const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000334PIC16TargetObjectFile::getROSectionForGlobal(const GlobalVariable *GV) const {
335 ROSections[0]->Items.push_back(GV);
336 return ROSections[0]->S_;
337}
338
339// Create initialized data section for a variable.
Chris Lattnera87dea42009-07-31 18:48:30 +0000340const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000341PIC16TargetObjectFile::CreateIDATASectionForGlobal(const GlobalVariable *GV,
342 std::string Addr) const {
343 assert(GV->hasInitializer() && "This global doesn't need space");
344 assert(!GV->getInitializer()->isNullValue() &&
345 "initialized global has zero initializer");
346 assert(GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
347 "can be used for initialized RAM data only");
348
349 std::string Name;
350 // If address is given then create a section at that address else create a
351 // section by section name specified in GV.
352 PIC16Section *FoundIDATASec = NULL;
353 if (Addr.empty()) {
354 Name = GV->getSection() + " IDATA";
355 for (unsigned i = 0; i < IDATASections.size(); i++) {
356 if (IDATASections[i]->S_->getName() == Name) {
357 FoundIDATASec = IDATASections[i];
358 break;
359 }
360 }
361 } else {
362 std::string Prefix = GV->getNameStr() + "." + Addr + ".";
363 Name = PAN::getIdataSectionName(IDATASections.size(), Prefix) + " " + Addr;
364 }
365
366 PIC16Section *NewIDATASec = FoundIDATASec;
367 if (NewIDATASec == NULL) {
Chris Lattnera87dea42009-07-31 18:48:30 +0000368 const MCSection *NewSection = getOrCreateSection(Name.c_str(), false,
Chris Lattnerf0144122009-07-28 03:13:23 +0000369 // FIXME:
Chris Lattner1ef9be22009-08-02 00:02:44 +0000370 SectionKind::getMetadata());
Chris Lattnerf0144122009-07-28 03:13:23 +0000371 NewIDATASec = new PIC16Section(NewSection);
372 IDATASections.push_back(NewIDATASec);
373 }
374 // Insert the GV into this IDATA Section.
375 NewIDATASec->Items.push_back(GV);
376 // We do not want to put any GV without explicit section into this section
377 // so set its size to DatabankSize.
378 NewIDATASec->Size = DataBankSize;
379 return NewIDATASec->S_;
380}
381
382// Create a section in rom for a variable.
Chris Lattnera87dea42009-07-31 18:48:30 +0000383const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000384PIC16TargetObjectFile::CreateROSectionForGlobal(const GlobalVariable *GV,
385 std::string Addr) const {
386 assert(GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE &&
387 "can be used for ROM data only");
388
389 std::string Name;
390 // If address is given then create a section at that address else create a
391 // section by section name specified in GV.
392 PIC16Section *FoundROSec = NULL;
393 if (Addr.empty()) {
394 Name = GV->getSection() + " ROMDATA";
395 for (unsigned i = 1; i < ROSections.size(); i++) {
396 if (ROSections[i]->S_->getName() == Name) {
397 FoundROSec = ROSections[i];
398 break;
399 }
400 }
401 } else {
402 std::string Prefix = GV->getNameStr() + "." + Addr + ".";
403 Name = PAN::getRomdataSectionName(ROSections.size(), Prefix) + " " + Addr;
404 }
405
406 PIC16Section *NewRomSec = FoundROSec;
407 if (NewRomSec == NULL) {
Chris Lattnera87dea42009-07-31 18:48:30 +0000408 const MCSection *NewSection = getOrCreateSection(Name.c_str(), false,
Chris Lattner1ef9be22009-08-02 00:02:44 +0000409 SectionKind::getReadOnly());
Chris Lattnerf0144122009-07-28 03:13:23 +0000410 NewRomSec = new PIC16Section(NewSection);
411 ROSections.push_back(NewRomSec);
412 }
413
414 // Insert the GV into this ROM Section.
415 NewRomSec->Items.push_back(GV);
416 return NewRomSec->S_;
417}
418