blob: 7b5d5574e5c8e3cc2becff3a8db6870403cdb9ea [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()
19 : ExternalVarDecls(0), ExternalVarDefs(0)
20{
21}
22
Chris Lattnera87dea42009-07-31 18:48:30 +000023void PIC16TargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &tm){
24 TargetLoweringObjectFile::Initialize(Ctx, tm);
25 TM = &tm;
26
Chris Lattner82458382009-08-01 21:56:13 +000027 BSSSection = getOrCreateSection("udata.# UDATA", false,
Chris Lattner1ef9be22009-08-02 00:02:44 +000028 SectionKind::getBSS());
Chris Lattnerf0144122009-07-28 03:13:23 +000029 ReadOnlySection = getOrCreateSection("romdata.# ROMDATA", false,
Chris Lattner1ef9be22009-08-02 00:02:44 +000030 SectionKind::getReadOnly());
Chris Lattner968ff112009-08-01 21:11:14 +000031 DataSection = getOrCreateSection("idata.# IDATA", false,
Chris Lattner1ef9be22009-08-02 00:02:44 +000032 SectionKind::getDataRel());
Chris Lattnerf0144122009-07-28 03:13:23 +000033
34 // Need because otherwise a .text symbol is emitted by DwarfWriter
35 // in BeginModule, and gpasm cribbs for that .text symbol.
Chris Lattner968ff112009-08-01 21:11:14 +000036 TextSection = getOrCreateSection("", true,
Chris Lattner1ef9be22009-08-02 00:02:44 +000037 SectionKind::getText());
Chris Lattnerf0144122009-07-28 03:13:23 +000038
Chris Lattnera87dea42009-07-31 18:48:30 +000039 ROSections.push_back(new PIC16Section(ReadOnlySection));
Chris Lattnerf0144122009-07-28 03:13:23 +000040
41 // FIXME: I don't know what the classification of these sections really is.
42 ExternalVarDecls = new PIC16Section(getOrCreateSection("ExternalVarDecls",
43 false,
Chris Lattner1ef9be22009-08-02 00:02:44 +000044 SectionKind::getMetadata()));
Chris Lattnerf0144122009-07-28 03:13:23 +000045 ExternalVarDefs = new PIC16Section(getOrCreateSection("ExternalVarDefs",
46 false,
Chris Lattner1ef9be22009-08-02 00:02:44 +000047 SectionKind::getMetadata()));
Chris Lattnerf0144122009-07-28 03:13:23 +000048}
49
50
Chris Lattnera87dea42009-07-31 18:48:30 +000051const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +000052PIC16TargetObjectFile::getBSSSectionForGlobal(const GlobalVariable *GV) const {
53 assert(GV->hasInitializer() && "This global doesn't need space");
54 Constant *C = GV->getInitializer();
55 assert(C->isNullValue() && "Unitialized globals has non-zero initializer");
56
57 // Find how much space this global needs.
Chris Lattnera87dea42009-07-31 18:48:30 +000058 const TargetData *TD = TM->getTargetData();
Chris Lattnerf0144122009-07-28 03:13:23 +000059 const Type *Ty = C->getType();
60 unsigned ValSize = TD->getTypeAllocSize(Ty);
61
62 // Go through all BSS Sections and assign this variable
63 // to the first available section having enough space.
64 PIC16Section *FoundBSS = NULL;
65 for (unsigned i = 0; i < BSSSections.size(); i++) {
66 if (DataBankSize - BSSSections[i]->Size >= ValSize) {
67 FoundBSS = BSSSections[i];
68 break;
69 }
70 }
71
72 // No BSS section spacious enough was found. Crate a new one.
73 if (!FoundBSS) {
74 std::string name = PAN::getUdataSectionName(BSSSections.size());
Chris Lattnera87dea42009-07-31 18:48:30 +000075 const MCSection *NewSection = getOrCreateSection(name.c_str(), false,
76 // FIXME.
Chris Lattner1ef9be22009-08-02 00:02:44 +000077 SectionKind::getMetadata());
Chris Lattnerf0144122009-07-28 03:13:23 +000078
79 FoundBSS = new PIC16Section(NewSection);
80
81 // Add this newly created BSS section to the list of BSSSections.
82 BSSSections.push_back(FoundBSS);
83 }
84
85 // Insert the GV into this BSS.
86 FoundBSS->Items.push_back(GV);
87 FoundBSS->Size += ValSize;
88 return FoundBSS->S_;
89}
90
Chris Lattnera87dea42009-07-31 18:48:30 +000091const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +000092PIC16TargetObjectFile::getIDATASectionForGlobal(const GlobalVariable *GV) const{
93 assert(GV->hasInitializer() && "This global doesn't need space");
94 Constant *C = GV->getInitializer();
95 assert(!C->isNullValue() && "initialized globals has zero initializer");
96 assert(GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
97 "can split initialized RAM data only");
98
99 // Find how much space this global needs.
Chris Lattnera87dea42009-07-31 18:48:30 +0000100 const TargetData *TD = TM->getTargetData();
Chris Lattnerf0144122009-07-28 03:13:23 +0000101 const Type *Ty = C->getType();
102 unsigned ValSize = TD->getTypeAllocSize(Ty);
103
104 // Go through all IDATA Sections and assign this variable
105 // to the first available section having enough space.
106 PIC16Section *FoundIDATA = NULL;
107 for (unsigned i = 0; i < IDATASections.size(); i++) {
108 if (DataBankSize - IDATASections[i]->Size >= ValSize) {
109 FoundIDATA = IDATASections[i];
110 break;
111 }
112 }
113
114 // No IDATA section spacious enough was found. Crate a new one.
115 if (!FoundIDATA) {
116 std::string name = PAN::getIdataSectionName(IDATASections.size());
Chris Lattnera87dea42009-07-31 18:48:30 +0000117 const MCSection *NewSection = getOrCreateSection(name.c_str(), false,
Chris Lattnerf0144122009-07-28 03:13:23 +0000118 // FIXME.
Chris Lattner1ef9be22009-08-02 00:02:44 +0000119 SectionKind::getMetadata());
Chris Lattnerf0144122009-07-28 03:13:23 +0000120
121 FoundIDATA = new PIC16Section(NewSection);
122
123 // Add this newly created IDATA section to the list of IDATASections.
124 IDATASections.push_back(FoundIDATA);
125 }
126
127 // Insert the GV into this IDATA.
128 FoundIDATA->Items.push_back(GV);
129 FoundIDATA->Size += ValSize;
130 return FoundIDATA->S_;
131}
132
133// Get the section for an automatic variable of a function.
134// For PIC16 they are globals only with mangled names.
Chris Lattnera87dea42009-07-31 18:48:30 +0000135const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000136PIC16TargetObjectFile::getSectionForAuto(const GlobalVariable *GV) const {
137
138 const std::string name = PAN::getSectionNameForSym(GV->getName());
139
140 // Go through all Auto Sections and assign this variable
141 // to the appropriate section.
142 PIC16Section *FoundAutoSec = NULL;
143 for (unsigned i = 0; i < AutosSections.size(); i++) {
144 if (AutosSections[i]->S_->getName() == name) {
145 FoundAutoSec = AutosSections[i];
146 break;
147 }
148 }
149
150 // No Auto section was found. Crate a new one.
151 if (!FoundAutoSec) {
Chris Lattnera87dea42009-07-31 18:48:30 +0000152 const MCSection *NewSection = getOrCreateSection(name.c_str(),
153 // FIXME.
154 false,
Chris Lattner1ef9be22009-08-02 00:02:44 +0000155 SectionKind::getMetadata());
Chris Lattnerf0144122009-07-28 03:13:23 +0000156
157 FoundAutoSec = new PIC16Section(NewSection);
158
159 // Add this newly created autos section to the list of AutosSections.
160 AutosSections.push_back(FoundAutoSec);
161 }
162
163 // Insert the auto into this section.
164 FoundAutoSec->Items.push_back(GV);
165
166 return FoundAutoSec->S_;
167}
168
169
170// Override default implementation to put the true globals into
171// multiple data sections if required.
Chris Lattnera87dea42009-07-31 18:48:30 +0000172const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000173PIC16TargetObjectFile::SelectSectionForGlobal(const GlobalValue *GV1,
Chris Lattnerf9650c02009-08-01 21:46:23 +0000174 SectionKind Kind,
Chris Lattnere53a6002009-07-29 05:09:30 +0000175 Mangler *Mang,
Chris Lattnerf0144122009-07-28 03:13:23 +0000176 const TargetMachine &TM) const {
177 // We select the section based on the initializer here, so it really
178 // has to be a GlobalVariable.
179 const GlobalVariable *GV = dyn_cast<GlobalVariable>(GV1);
180 if (!GV)
Chris Lattnerf9650c02009-08-01 21:46:23 +0000181 return TargetLoweringObjectFile::SelectSectionForGlobal(GV1, Kind, Mang,TM);
Chris Lattnerf0144122009-07-28 03:13:23 +0000182
183 // Record External Var Decls.
184 if (GV->isDeclaration()) {
185 ExternalVarDecls->Items.push_back(GV);
186 return ExternalVarDecls->S_;
187 }
188
189 assert(GV->hasInitializer() && "A def without initializer?");
190
191 // First, if this is an automatic variable for a function, get the section
192 // name for it and return.
193 std::string name = GV->getName();
194 if (PAN::isLocalName(name))
195 return getSectionForAuto(GV);
196
197 // Record Exteranl Var Defs.
198 if (GV->hasExternalLinkage() || GV->hasCommonLinkage())
199 ExternalVarDefs->Items.push_back(GV);
200
201 // See if this is an uninitialized global.
202 const Constant *C = GV->getInitializer();
203 if (C->isNullValue())
204 return getBSSSectionForGlobal(GV);
205
206 // If this is initialized data in RAM. Put it in the correct IDATA section.
207 if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE)
208 return getIDATASectionForGlobal(GV);
209
210 // This is initialized data in rom, put it in the readonly section.
211 if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE)
212 return getROSectionForGlobal(GV);
213
214 // Else let the default implementation take care of it.
Chris Lattnerf9650c02009-08-01 21:46:23 +0000215 return TargetLoweringObjectFile::SelectSectionForGlobal(GV, Kind, Mang,TM);
Chris Lattnerf0144122009-07-28 03:13:23 +0000216}
217
218PIC16TargetObjectFile::~PIC16TargetObjectFile() {
219 for (unsigned i = 0; i < BSSSections.size(); i++)
220 delete BSSSections[i];
221 for (unsigned i = 0; i < IDATASections.size(); i++)
222 delete IDATASections[i];
223 for (unsigned i = 0; i < AutosSections.size(); i++)
224 delete AutosSections[i];
225 for (unsigned i = 0; i < ROSections.size(); i++)
226 delete ROSections[i];
227 delete ExternalVarDecls;
228 delete ExternalVarDefs;
229}
230
231
232/// getSpecialCasedSectionGlobals - Allow the target to completely override
233/// section assignment of a global.
Chris Lattnera87dea42009-07-31 18:48:30 +0000234const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000235PIC16TargetObjectFile::getSpecialCasedSectionGlobals(const GlobalValue *GV,
Chris Lattnere53a6002009-07-29 05:09:30 +0000236 Mangler *Mang,
Chris Lattnerf9650c02009-08-01 21:46:23 +0000237 SectionKind Kind) const {
Chris Lattnerf0144122009-07-28 03:13:23 +0000238 // If GV has a sectin name or section address create that section now.
239 if (GV->hasSection()) {
240 if (const GlobalVariable *GVar = cast<GlobalVariable>(GV)) {
241 std::string SectName = GVar->getSection();
242 // If address for a variable is specified, get the address and create
243 // section.
244 std::string AddrStr = "Address=";
245 if (SectName.compare(0, AddrStr.length(), AddrStr) == 0) {
246 std::string SectAddr = SectName.substr(AddrStr.length());
Chris Lattnere53a6002009-07-29 05:09:30 +0000247 return CreateSectionForGlobal(GVar, Mang, SectAddr);
Chris Lattnerf0144122009-07-28 03:13:23 +0000248 }
249
250 // Create the section specified with section attribute.
Chris Lattnere53a6002009-07-29 05:09:30 +0000251 return CreateSectionForGlobal(GVar, Mang);
Chris Lattnerf0144122009-07-28 03:13:23 +0000252 }
253 }
254
255 return 0;
256}
257
258// Create a new section for global variable. If Addr is given then create
259// section at that address else create by name.
Chris Lattnera87dea42009-07-31 18:48:30 +0000260const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000261PIC16TargetObjectFile::CreateSectionForGlobal(const GlobalVariable *GV,
Chris Lattnere53a6002009-07-29 05:09:30 +0000262 Mangler *Mang,
Chris Lattnerf0144122009-07-28 03:13:23 +0000263 const std::string &Addr) const {
264 // See if this is an uninitialized global.
265 const Constant *C = GV->getInitializer();
266 if (C->isNullValue())
267 return CreateBSSSectionForGlobal(GV, Addr);
268
269 // If this is initialized data in RAM. Put it in the correct IDATA section.
270 if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE)
271 return CreateIDATASectionForGlobal(GV, Addr);
272
273 // This is initialized data in rom, put it in the readonly section.
274 if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE)
275 return CreateROSectionForGlobal(GV, Addr);
276
277 // Else let the default implementation take care of it.
Chris Lattnera87dea42009-07-31 18:48:30 +0000278 return TargetLoweringObjectFile::SectionForGlobal(GV, Mang, *TM);
Chris Lattnerf0144122009-07-28 03:13:23 +0000279}
280
281// Create uninitialized section for a variable.
Chris Lattnera87dea42009-07-31 18:48:30 +0000282const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000283PIC16TargetObjectFile::CreateBSSSectionForGlobal(const GlobalVariable *GV,
284 std::string Addr) const {
285 assert(GV->hasInitializer() && "This global doesn't need space");
286 assert(GV->getInitializer()->isNullValue() &&
287 "Unitialized global has non-zero initializer");
288 std::string Name;
289 // If address is given then create a section at that address else create a
290 // section by section name specified in GV.
291 PIC16Section *FoundBSS = NULL;
292 if (Addr.empty()) {
293 Name = GV->getSection() + " UDATA";
294 for (unsigned i = 0; i < BSSSections.size(); i++) {
295 if (BSSSections[i]->S_->getName() == Name) {
296 FoundBSS = BSSSections[i];
297 break;
298 }
299 }
300 } else {
301 std::string Prefix = GV->getNameStr() + "." + Addr + ".";
302 Name = PAN::getUdataSectionName(BSSSections.size(), Prefix) + " " + Addr;
303 }
304
305 PIC16Section *NewBSS = FoundBSS;
306 if (NewBSS == NULL) {
Chris Lattnera87dea42009-07-31 18:48:30 +0000307 const MCSection *NewSection = getOrCreateSection(Name.c_str(), false,
Chris Lattner1ef9be22009-08-02 00:02:44 +0000308 SectionKind::getBSS());
Chris Lattnerf0144122009-07-28 03:13:23 +0000309 NewBSS = new PIC16Section(NewSection);
310 BSSSections.push_back(NewBSS);
311 }
312
313 // Insert the GV into this BSS.
314 NewBSS->Items.push_back(GV);
315
316 // We do not want to put any GV without explicit section into this section
317 // so set its size to DatabankSize.
318 NewBSS->Size = DataBankSize;
319 return NewBSS->S_;
320}
321
322// Get rom section for a variable. Currently there can be only one rom section
323// unless a variable explicitly requests a section.
Chris Lattnera87dea42009-07-31 18:48:30 +0000324const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000325PIC16TargetObjectFile::getROSectionForGlobal(const GlobalVariable *GV) const {
326 ROSections[0]->Items.push_back(GV);
327 return ROSections[0]->S_;
328}
329
330// Create initialized data section for a variable.
Chris Lattnera87dea42009-07-31 18:48:30 +0000331const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000332PIC16TargetObjectFile::CreateIDATASectionForGlobal(const GlobalVariable *GV,
333 std::string Addr) const {
334 assert(GV->hasInitializer() && "This global doesn't need space");
335 assert(!GV->getInitializer()->isNullValue() &&
336 "initialized global has zero initializer");
337 assert(GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
338 "can be used for initialized RAM data only");
339
340 std::string Name;
341 // If address is given then create a section at that address else create a
342 // section by section name specified in GV.
343 PIC16Section *FoundIDATASec = NULL;
344 if (Addr.empty()) {
345 Name = GV->getSection() + " IDATA";
346 for (unsigned i = 0; i < IDATASections.size(); i++) {
347 if (IDATASections[i]->S_->getName() == Name) {
348 FoundIDATASec = IDATASections[i];
349 break;
350 }
351 }
352 } else {
353 std::string Prefix = GV->getNameStr() + "." + Addr + ".";
354 Name = PAN::getIdataSectionName(IDATASections.size(), Prefix) + " " + Addr;
355 }
356
357 PIC16Section *NewIDATASec = FoundIDATASec;
358 if (NewIDATASec == NULL) {
Chris Lattnera87dea42009-07-31 18:48:30 +0000359 const MCSection *NewSection = getOrCreateSection(Name.c_str(), false,
Chris Lattnerf0144122009-07-28 03:13:23 +0000360 // FIXME:
Chris Lattner1ef9be22009-08-02 00:02:44 +0000361 SectionKind::getMetadata());
Chris Lattnerf0144122009-07-28 03:13:23 +0000362 NewIDATASec = new PIC16Section(NewSection);
363 IDATASections.push_back(NewIDATASec);
364 }
365 // Insert the GV into this IDATA Section.
366 NewIDATASec->Items.push_back(GV);
367 // We do not want to put any GV without explicit section into this section
368 // so set its size to DatabankSize.
369 NewIDATASec->Size = DataBankSize;
370 return NewIDATASec->S_;
371}
372
373// Create a section in rom for a variable.
Chris Lattnera87dea42009-07-31 18:48:30 +0000374const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000375PIC16TargetObjectFile::CreateROSectionForGlobal(const GlobalVariable *GV,
376 std::string Addr) const {
377 assert(GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE &&
378 "can be used for ROM data only");
379
380 std::string Name;
381 // If address is given then create a section at that address else create a
382 // section by section name specified in GV.
383 PIC16Section *FoundROSec = NULL;
384 if (Addr.empty()) {
385 Name = GV->getSection() + " ROMDATA";
386 for (unsigned i = 1; i < ROSections.size(); i++) {
387 if (ROSections[i]->S_->getName() == Name) {
388 FoundROSec = ROSections[i];
389 break;
390 }
391 }
392 } else {
393 std::string Prefix = GV->getNameStr() + "." + Addr + ".";
394 Name = PAN::getRomdataSectionName(ROSections.size(), Prefix) + " " + Addr;
395 }
396
397 PIC16Section *NewRomSec = FoundROSec;
398 if (NewRomSec == NULL) {
Chris Lattnera87dea42009-07-31 18:48:30 +0000399 const MCSection *NewSection = getOrCreateSection(Name.c_str(), false,
Chris Lattner1ef9be22009-08-02 00:02:44 +0000400 SectionKind::getReadOnly());
Chris Lattnerf0144122009-07-28 03:13:23 +0000401 NewRomSec = new PIC16Section(NewSection);
402 ROSections.push_back(NewRomSec);
403 }
404
405 // Insert the GV into this ROM Section.
406 NewRomSec->Items.push_back(GV);
407 return NewRomSec->S_;
408}
409