blob: 3900929f466d98725943176e33e571bbaf761ba6 [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 Lattnerfbf1d272009-08-08 20:14:13 +000016#include "llvm/MC/MCContext.h"
Chris Lattnerf0144122009-07-28 03:13:23 +000017using namespace llvm;
18
Daniel Dunbar967ce7f2009-08-02 01:25:15 +000019PIC16TargetObjectFile::PIC16TargetObjectFile()
Chris Lattner759b8882009-08-06 16:27:28 +000020 : ExternalVarDecls(0), ExternalVarDefs(0) {
Daniel Dunbar967ce7f2009-08-02 01:25:15 +000021}
22
Chris Lattnerfbf1d272009-08-08 20:14:13 +000023const MCSection *PIC16TargetObjectFile::
Chris Lattner9aee1812009-08-08 20:23:47 +000024getPIC16Section(const char *Name, bool isDirective, SectionKind Kind) const {
Chris Lattnerfbf1d272009-08-08 20:14:13 +000025 if (MCSection *S = getContext().GetSection(Name))
26 return S;
27 return MCSection::Create(Name, isDirective, Kind, getContext());
28}
29
30
Chris Lattnera87dea42009-07-31 18:48:30 +000031void PIC16TargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &tm){
32 TargetLoweringObjectFile::Initialize(Ctx, tm);
33 TM = &tm;
34
Chris Lattner9aee1812009-08-08 20:23:47 +000035 BSSSection = getPIC16Section("udata.# UDATA", false,
36 SectionKind::getBSS());
37 ReadOnlySection = getPIC16Section("romdata.# ROMDATA", false,
38 SectionKind::getReadOnly());
39 DataSection = getPIC16Section("idata.# IDATA", false,
40 SectionKind::getDataRel());
Chris Lattnerf0144122009-07-28 03:13:23 +000041
42 // Need because otherwise a .text symbol is emitted by DwarfWriter
43 // in BeginModule, and gpasm cribbs for that .text symbol.
Chris Lattner9aee1812009-08-08 20:23:47 +000044 TextSection = getPIC16Section("", true, SectionKind::getText());
Chris Lattnerf0144122009-07-28 03:13:23 +000045
Chris Lattnera87dea42009-07-31 18:48:30 +000046 ROSections.push_back(new PIC16Section(ReadOnlySection));
Chris Lattnerf0144122009-07-28 03:13:23 +000047
48 // FIXME: I don't know what the classification of these sections really is.
Chris Lattner9aee1812009-08-08 20:23:47 +000049 ExternalVarDecls = new PIC16Section(getPIC16Section("ExternalVarDecls",
50 false,
Chris Lattner1ef9be22009-08-02 00:02:44 +000051 SectionKind::getMetadata()));
Chris Lattner9aee1812009-08-08 20:23:47 +000052 ExternalVarDefs = new PIC16Section(getPIC16Section("ExternalVarDefs",
53 false,
Chris Lattner1ef9be22009-08-02 00:02:44 +000054 SectionKind::getMetadata()));
Chris Lattnerf0144122009-07-28 03:13:23 +000055}
56
Chris Lattner759b8882009-08-06 16:27:28 +000057const MCSection *PIC16TargetObjectFile::
58getSectionForFunction(const std::string &FnName) const {
59 std::string T = PAN::getCodeSectionName(FnName);
Chris Lattner9aee1812009-08-08 20:23:47 +000060 return getPIC16Section(T.c_str(), false, SectionKind::getText());
Chris Lattner759b8882009-08-06 16:27:28 +000061}
62
63
64const MCSection *PIC16TargetObjectFile::
65getSectionForFunctionFrame(const std::string &FnName) const {
66 std::string T = PAN::getFrameSectionName(FnName);
Chris Lattner9aee1812009-08-08 20:23:47 +000067 return getPIC16Section(T.c_str(), false, SectionKind::getDataRel());
Chris Lattner759b8882009-08-06 16:27:28 +000068}
Chris Lattnerf0144122009-07-28 03:13:23 +000069
Chris Lattnera87dea42009-07-31 18:48:30 +000070const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +000071PIC16TargetObjectFile::getBSSSectionForGlobal(const GlobalVariable *GV) const {
72 assert(GV->hasInitializer() && "This global doesn't need space");
73 Constant *C = GV->getInitializer();
74 assert(C->isNullValue() && "Unitialized globals has non-zero initializer");
75
76 // Find how much space this global needs.
Chris Lattnera87dea42009-07-31 18:48:30 +000077 const TargetData *TD = TM->getTargetData();
Chris Lattnerf0144122009-07-28 03:13:23 +000078 const Type *Ty = C->getType();
79 unsigned ValSize = TD->getTypeAllocSize(Ty);
80
81 // Go through all BSS Sections and assign this variable
82 // to the first available section having enough space.
83 PIC16Section *FoundBSS = NULL;
84 for (unsigned i = 0; i < BSSSections.size(); i++) {
85 if (DataBankSize - BSSSections[i]->Size >= ValSize) {
86 FoundBSS = BSSSections[i];
87 break;
88 }
89 }
90
91 // No BSS section spacious enough was found. Crate a new one.
92 if (!FoundBSS) {
93 std::string name = PAN::getUdataSectionName(BSSSections.size());
Chris Lattner9aee1812009-08-08 20:23:47 +000094 const MCSection *NewSection = getPIC16Section(name.c_str(), false,
95 // FIXME.
96 SectionKind::getMetadata());
Chris Lattnerf0144122009-07-28 03:13:23 +000097
98 FoundBSS = new PIC16Section(NewSection);
99
100 // Add this newly created BSS section to the list of BSSSections.
101 BSSSections.push_back(FoundBSS);
102 }
103
104 // Insert the GV into this BSS.
105 FoundBSS->Items.push_back(GV);
106 FoundBSS->Size += ValSize;
107 return FoundBSS->S_;
108}
109
Chris Lattnera87dea42009-07-31 18:48:30 +0000110const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000111PIC16TargetObjectFile::getIDATASectionForGlobal(const GlobalVariable *GV) const{
112 assert(GV->hasInitializer() && "This global doesn't need space");
113 Constant *C = GV->getInitializer();
114 assert(!C->isNullValue() && "initialized globals has zero initializer");
115 assert(GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
116 "can split initialized RAM data only");
117
118 // Find how much space this global needs.
Chris Lattnera87dea42009-07-31 18:48:30 +0000119 const TargetData *TD = TM->getTargetData();
Chris Lattnerf0144122009-07-28 03:13:23 +0000120 const Type *Ty = C->getType();
121 unsigned ValSize = TD->getTypeAllocSize(Ty);
122
123 // Go through all IDATA Sections and assign this variable
124 // to the first available section having enough space.
125 PIC16Section *FoundIDATA = NULL;
126 for (unsigned i = 0; i < IDATASections.size(); i++) {
127 if (DataBankSize - IDATASections[i]->Size >= ValSize) {
128 FoundIDATA = IDATASections[i];
129 break;
130 }
131 }
132
133 // No IDATA section spacious enough was found. Crate a new one.
134 if (!FoundIDATA) {
135 std::string name = PAN::getIdataSectionName(IDATASections.size());
Chris Lattner9aee1812009-08-08 20:23:47 +0000136 const MCSection *NewSection = getPIC16Section(name.c_str(), false,
137 // FIXME.
138 SectionKind::getMetadata());
Chris Lattnerf0144122009-07-28 03:13:23 +0000139
140 FoundIDATA = new PIC16Section(NewSection);
141
142 // Add this newly created IDATA section to the list of IDATASections.
143 IDATASections.push_back(FoundIDATA);
144 }
145
146 // Insert the GV into this IDATA.
147 FoundIDATA->Items.push_back(GV);
148 FoundIDATA->Size += ValSize;
149 return FoundIDATA->S_;
150}
151
152// Get the section for an automatic variable of a function.
153// For PIC16 they are globals only with mangled names.
Chris Lattnera87dea42009-07-31 18:48:30 +0000154const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000155PIC16TargetObjectFile::getSectionForAuto(const GlobalVariable *GV) const {
156
157 const std::string name = PAN::getSectionNameForSym(GV->getName());
158
159 // Go through all Auto Sections and assign this variable
160 // to the appropriate section.
161 PIC16Section *FoundAutoSec = NULL;
162 for (unsigned i = 0; i < AutosSections.size(); i++) {
163 if (AutosSections[i]->S_->getName() == name) {
164 FoundAutoSec = AutosSections[i];
165 break;
166 }
167 }
168
169 // No Auto section was found. Crate a new one.
170 if (!FoundAutoSec) {
Chris Lattner9aee1812009-08-08 20:23:47 +0000171 const MCSection *NewSection = getPIC16Section(name.c_str(),
172 // FIXME.
173 false,
Chris Lattner1ef9be22009-08-02 00:02:44 +0000174 SectionKind::getMetadata());
Chris Lattnerf0144122009-07-28 03:13:23 +0000175
176 FoundAutoSec = new PIC16Section(NewSection);
177
178 // Add this newly created autos section to the list of AutosSections.
179 AutosSections.push_back(FoundAutoSec);
180 }
181
182 // Insert the auto into this section.
183 FoundAutoSec->Items.push_back(GV);
184
185 return FoundAutoSec->S_;
186}
187
188
189// Override default implementation to put the true globals into
190// multiple data sections if required.
Chris Lattnera87dea42009-07-31 18:48:30 +0000191const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000192PIC16TargetObjectFile::SelectSectionForGlobal(const GlobalValue *GV1,
Chris Lattnerf9650c02009-08-01 21:46:23 +0000193 SectionKind Kind,
Chris Lattnere53a6002009-07-29 05:09:30 +0000194 Mangler *Mang,
Chris Lattnerf0144122009-07-28 03:13:23 +0000195 const TargetMachine &TM) const {
196 // We select the section based on the initializer here, so it really
197 // has to be a GlobalVariable.
198 const GlobalVariable *GV = dyn_cast<GlobalVariable>(GV1);
199 if (!GV)
Chris Lattnerf9650c02009-08-01 21:46:23 +0000200 return TargetLoweringObjectFile::SelectSectionForGlobal(GV1, Kind, Mang,TM);
Chris Lattnerf0144122009-07-28 03:13:23 +0000201
202 // Record External Var Decls.
203 if (GV->isDeclaration()) {
204 ExternalVarDecls->Items.push_back(GV);
205 return ExternalVarDecls->S_;
206 }
207
208 assert(GV->hasInitializer() && "A def without initializer?");
209
210 // First, if this is an automatic variable for a function, get the section
211 // name for it and return.
212 std::string name = GV->getName();
213 if (PAN::isLocalName(name))
214 return getSectionForAuto(GV);
215
216 // Record Exteranl Var Defs.
217 if (GV->hasExternalLinkage() || GV->hasCommonLinkage())
218 ExternalVarDefs->Items.push_back(GV);
219
220 // See if this is an uninitialized global.
221 const Constant *C = GV->getInitializer();
222 if (C->isNullValue())
223 return getBSSSectionForGlobal(GV);
224
225 // If this is initialized data in RAM. Put it in the correct IDATA section.
226 if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE)
227 return getIDATASectionForGlobal(GV);
228
229 // This is initialized data in rom, put it in the readonly section.
230 if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE)
231 return getROSectionForGlobal(GV);
232
233 // Else let the default implementation take care of it.
Chris Lattnerf9650c02009-08-01 21:46:23 +0000234 return TargetLoweringObjectFile::SelectSectionForGlobal(GV, Kind, Mang,TM);
Chris Lattnerf0144122009-07-28 03:13:23 +0000235}
236
237PIC16TargetObjectFile::~PIC16TargetObjectFile() {
238 for (unsigned i = 0; i < BSSSections.size(); i++)
239 delete BSSSections[i];
240 for (unsigned i = 0; i < IDATASections.size(); i++)
241 delete IDATASections[i];
242 for (unsigned i = 0; i < AutosSections.size(); i++)
243 delete AutosSections[i];
244 for (unsigned i = 0; i < ROSections.size(); i++)
245 delete ROSections[i];
246 delete ExternalVarDecls;
247 delete ExternalVarDefs;
248}
249
250
251/// getSpecialCasedSectionGlobals - Allow the target to completely override
252/// section assignment of a global.
Chris Lattner24f654c2009-08-06 16:39:58 +0000253const MCSection *PIC16TargetObjectFile::
254getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
255 Mangler *Mang, const TargetMachine &TM) const {
256 assert(GV->hasSection());
257
258 if (const GlobalVariable *GVar = cast<GlobalVariable>(GV)) {
259 std::string SectName = GVar->getSection();
260 // If address for a variable is specified, get the address and create
261 // section.
262 std::string AddrStr = "Address=";
263 if (SectName.compare(0, AddrStr.length(), AddrStr) == 0) {
264 std::string SectAddr = SectName.substr(AddrStr.length());
265 return CreateSectionForGlobal(GVar, Mang, SectAddr);
Chris Lattnerf0144122009-07-28 03:13:23 +0000266 }
Chris Lattner24f654c2009-08-06 16:39:58 +0000267
268 // Create the section specified with section attribute.
269 return CreateSectionForGlobal(GVar, Mang);
Chris Lattnerf0144122009-07-28 03:13:23 +0000270 }
271
Chris Lattner9aee1812009-08-08 20:23:47 +0000272 return getPIC16Section(GV->getSection().c_str(), false, Kind);
Chris Lattnerf0144122009-07-28 03:13:23 +0000273}
274
275// Create a new section for global variable. If Addr is given then create
276// section at that address else create by name.
Chris Lattnera87dea42009-07-31 18:48:30 +0000277const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000278PIC16TargetObjectFile::CreateSectionForGlobal(const GlobalVariable *GV,
Chris Lattnere53a6002009-07-29 05:09:30 +0000279 Mangler *Mang,
Chris Lattnerf0144122009-07-28 03:13:23 +0000280 const std::string &Addr) const {
281 // See if this is an uninitialized global.
282 const Constant *C = GV->getInitializer();
283 if (C->isNullValue())
284 return CreateBSSSectionForGlobal(GV, Addr);
285
286 // If this is initialized data in RAM. Put it in the correct IDATA section.
287 if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE)
288 return CreateIDATASectionForGlobal(GV, Addr);
289
290 // This is initialized data in rom, put it in the readonly section.
291 if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE)
292 return CreateROSectionForGlobal(GV, Addr);
293
294 // Else let the default implementation take care of it.
Chris Lattnera87dea42009-07-31 18:48:30 +0000295 return TargetLoweringObjectFile::SectionForGlobal(GV, Mang, *TM);
Chris Lattnerf0144122009-07-28 03:13:23 +0000296}
297
298// Create uninitialized section for a variable.
Chris Lattnera87dea42009-07-31 18:48:30 +0000299const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000300PIC16TargetObjectFile::CreateBSSSectionForGlobal(const GlobalVariable *GV,
301 std::string Addr) const {
302 assert(GV->hasInitializer() && "This global doesn't need space");
303 assert(GV->getInitializer()->isNullValue() &&
304 "Unitialized global has non-zero initializer");
305 std::string Name;
306 // If address is given then create a section at that address else create a
307 // section by section name specified in GV.
308 PIC16Section *FoundBSS = NULL;
309 if (Addr.empty()) {
310 Name = GV->getSection() + " UDATA";
311 for (unsigned i = 0; i < BSSSections.size(); i++) {
312 if (BSSSections[i]->S_->getName() == Name) {
313 FoundBSS = BSSSections[i];
314 break;
315 }
316 }
317 } else {
318 std::string Prefix = GV->getNameStr() + "." + Addr + ".";
319 Name = PAN::getUdataSectionName(BSSSections.size(), Prefix) + " " + Addr;
320 }
321
322 PIC16Section *NewBSS = FoundBSS;
323 if (NewBSS == NULL) {
Chris Lattner9aee1812009-08-08 20:23:47 +0000324 const MCSection *NewSection = getPIC16Section(Name.c_str(), false,
325 SectionKind::getBSS());
Chris Lattnerf0144122009-07-28 03:13:23 +0000326 NewBSS = new PIC16Section(NewSection);
327 BSSSections.push_back(NewBSS);
328 }
329
330 // Insert the GV into this BSS.
331 NewBSS->Items.push_back(GV);
332
333 // We do not want to put any GV without explicit section into this section
334 // so set its size to DatabankSize.
335 NewBSS->Size = DataBankSize;
336 return NewBSS->S_;
337}
338
339// Get rom section for a variable. Currently there can be only one rom section
340// unless a variable explicitly requests a section.
Chris Lattnera87dea42009-07-31 18:48:30 +0000341const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000342PIC16TargetObjectFile::getROSectionForGlobal(const GlobalVariable *GV) const {
343 ROSections[0]->Items.push_back(GV);
344 return ROSections[0]->S_;
345}
346
347// Create initialized data section for a variable.
Chris Lattnera87dea42009-07-31 18:48:30 +0000348const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000349PIC16TargetObjectFile::CreateIDATASectionForGlobal(const GlobalVariable *GV,
350 std::string Addr) const {
351 assert(GV->hasInitializer() && "This global doesn't need space");
352 assert(!GV->getInitializer()->isNullValue() &&
353 "initialized global has zero initializer");
354 assert(GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
355 "can be used for initialized RAM data only");
356
357 std::string Name;
358 // If address is given then create a section at that address else create a
359 // section by section name specified in GV.
360 PIC16Section *FoundIDATASec = NULL;
361 if (Addr.empty()) {
362 Name = GV->getSection() + " IDATA";
363 for (unsigned i = 0; i < IDATASections.size(); i++) {
364 if (IDATASections[i]->S_->getName() == Name) {
365 FoundIDATASec = IDATASections[i];
366 break;
367 }
368 }
369 } else {
370 std::string Prefix = GV->getNameStr() + "." + Addr + ".";
371 Name = PAN::getIdataSectionName(IDATASections.size(), Prefix) + " " + Addr;
372 }
373
374 PIC16Section *NewIDATASec = FoundIDATASec;
375 if (NewIDATASec == NULL) {
Chris Lattner9aee1812009-08-08 20:23:47 +0000376 const MCSection *NewSection = getPIC16Section(Name.c_str(), false,
377 // FIXME:
378 SectionKind::getMetadata());
Chris Lattnerf0144122009-07-28 03:13:23 +0000379 NewIDATASec = new PIC16Section(NewSection);
380 IDATASections.push_back(NewIDATASec);
381 }
382 // Insert the GV into this IDATA Section.
383 NewIDATASec->Items.push_back(GV);
384 // We do not want to put any GV without explicit section into this section
385 // so set its size to DatabankSize.
386 NewIDATASec->Size = DataBankSize;
387 return NewIDATASec->S_;
388}
389
390// Create a section in rom for a variable.
Chris Lattnera87dea42009-07-31 18:48:30 +0000391const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000392PIC16TargetObjectFile::CreateROSectionForGlobal(const GlobalVariable *GV,
393 std::string Addr) const {
394 assert(GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE &&
395 "can be used for ROM data only");
396
397 std::string Name;
398 // If address is given then create a section at that address else create a
399 // section by section name specified in GV.
400 PIC16Section *FoundROSec = NULL;
401 if (Addr.empty()) {
402 Name = GV->getSection() + " ROMDATA";
403 for (unsigned i = 1; i < ROSections.size(); i++) {
404 if (ROSections[i]->S_->getName() == Name) {
405 FoundROSec = ROSections[i];
406 break;
407 }
408 }
409 } else {
410 std::string Prefix = GV->getNameStr() + "." + Addr + ".";
411 Name = PAN::getRomdataSectionName(ROSections.size(), Prefix) + " " + Addr;
412 }
413
414 PIC16Section *NewRomSec = FoundROSec;
415 if (NewRomSec == NULL) {
Chris Lattner9aee1812009-08-08 20:23:47 +0000416 const MCSection *NewSection = getPIC16Section(Name.c_str(), false,
417 SectionKind::getReadOnly());
Chris Lattnerf0144122009-07-28 03:13:23 +0000418 NewRomSec = new PIC16Section(NewSection);
419 ROSections.push_back(NewRomSec);
420 }
421
422 // Insert the GV into this ROM Section.
423 NewRomSec->Items.push_back(GV);
424 return NewRomSec->S_;
425}
426