blob: a2a4c09d29781a849b2ccded48c3af46d61c0a2a [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"
Chris Lattnerc0776212009-08-15 06:13:40 +000011#include "MCSectionPIC16.h"
Chris Lattnerf0144122009-07-28 03:13:23 +000012#include "PIC16ISelLowering.h"
13#include "PIC16TargetMachine.h"
14#include "llvm/DerivedTypes.h"
15#include "llvm/Module.h"
Chris Lattnera87dea42009-07-31 18:48:30 +000016#include "llvm/MC/MCSection.h"
Chris Lattnerfbf1d272009-08-08 20:14:13 +000017#include "llvm/MC/MCContext.h"
Chris Lattner93b6db32009-08-08 23:39:42 +000018#include "llvm/Support/raw_ostream.h"
Chris Lattnerf0144122009-07-28 03:13:23 +000019using namespace llvm;
20
Chris Lattner93b6db32009-08-08 23:39:42 +000021
Sanjiv Guptab9ef7642009-08-25 19:39:05 +000022MCSectionPIC16 *MCSectionPIC16::Create(const StringRef &Name, SectionKind K,
Sanjiv Gupta72f9ab02009-09-01 10:47:31 +000023 int Address, int Color, MCContext &Ctx) {
24 return new (Ctx) MCSectionPIC16(Name, K, Address, Color);
Chris Lattner93b6db32009-08-08 23:39:42 +000025}
26
27
Chris Lattner33adcfb2009-08-22 21:43:10 +000028void MCSectionPIC16::PrintSwitchToSection(const MCAsmInfo &MAI,
Chris Lattner93b6db32009-08-08 23:39:42 +000029 raw_ostream &OS) const {
30 OS << getName() << '\n';
31}
32
33
34
35
Daniel Dunbar967ce7f2009-08-02 01:25:15 +000036PIC16TargetObjectFile::PIC16TargetObjectFile()
Chris Lattner759b8882009-08-06 16:27:28 +000037 : ExternalVarDecls(0), ExternalVarDefs(0) {
Daniel Dunbar967ce7f2009-08-02 01:25:15 +000038}
39
Chris Lattner93b6db32009-08-08 23:39:42 +000040const MCSectionPIC16 *PIC16TargetObjectFile::
Sanjiv Gupta72f9ab02009-09-01 10:47:31 +000041getPIC16Section(const char *Name, SectionKind Kind,
42 int Address, int Color) const {
Chris Lattner873bc4c2009-08-13 00:26:52 +000043 MCSectionPIC16 *&Entry = SectionsByName[Name];
44 if (Entry)
45 return Entry;
46
Sanjiv Gupta72f9ab02009-09-01 10:47:31 +000047 return Entry = MCSectionPIC16::Create(Name, Kind, Address, Color,
48 getContext());
Chris Lattnerfbf1d272009-08-08 20:14:13 +000049}
50
51
Chris Lattnera87dea42009-07-31 18:48:30 +000052void PIC16TargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &tm){
53 TargetLoweringObjectFile::Initialize(Ctx, tm);
54 TM = &tm;
55
Sanjiv Gupta72f9ab02009-09-01 10:47:31 +000056 BSSSection = getPIC16Section("udata.# UDATA", MCSectionPIC16::UDATA_Kind());
Chris Lattner93b6db32009-08-08 23:39:42 +000057 ReadOnlySection = getPIC16Section("romdata.# ROMDATA",
Sanjiv Gupta72f9ab02009-09-01 10:47:31 +000058 MCSectionPIC16::ROMDATA_Kind());
59 DataSection = getPIC16Section("idata.# IDATA", MCSectionPIC16::IDATA_Kind());
Chris Lattnerf0144122009-07-28 03:13:23 +000060
61 // Need because otherwise a .text symbol is emitted by DwarfWriter
62 // in BeginModule, and gpasm cribbs for that .text symbol.
Chris Lattner93b6db32009-08-08 23:39:42 +000063 TextSection = getPIC16Section("", SectionKind::getText());
Chris Lattnerf0144122009-07-28 03:13:23 +000064
Chris Lattner93b6db32009-08-08 23:39:42 +000065 ROSections.push_back(new PIC16Section((MCSectionPIC16*)ReadOnlySection));
Chris Lattnerf0144122009-07-28 03:13:23 +000066
67 // FIXME: I don't know what the classification of these sections really is.
Sanjiv Gupta72f9ab02009-09-01 10:47:31 +000068 // These aren't really objects belonging to any section. Just emit them
69 // in AsmPrinter and remove this code from here.
Chris Lattner9aee1812009-08-08 20:23:47 +000070 ExternalVarDecls = new PIC16Section(getPIC16Section("ExternalVarDecls",
Chris Lattner1ef9be22009-08-02 00:02:44 +000071 SectionKind::getMetadata()));
Chris Lattner9aee1812009-08-08 20:23:47 +000072 ExternalVarDefs = new PIC16Section(getPIC16Section("ExternalVarDefs",
Chris Lattner1ef9be22009-08-02 00:02:44 +000073 SectionKind::getMetadata()));
Chris Lattnerf0144122009-07-28 03:13:23 +000074}
75
Chris Lattner759b8882009-08-06 16:27:28 +000076const MCSection *PIC16TargetObjectFile::
Chris Lattner35a27c82009-08-21 23:12:15 +000077getSectionForFunction(const std::string &FnName) const {
78 std::string T = PAN::getCodeSectionName(FnName);
Chris Lattner93b6db32009-08-08 23:39:42 +000079 return getPIC16Section(T.c_str(), SectionKind::getText());
Chris Lattner759b8882009-08-06 16:27:28 +000080}
81
82
83const MCSection *PIC16TargetObjectFile::
84getSectionForFunctionFrame(const std::string &FnName) const {
85 std::string T = PAN::getFrameSectionName(FnName);
Chris Lattner93b6db32009-08-08 23:39:42 +000086 return getPIC16Section(T.c_str(), SectionKind::getDataRel());
Chris Lattner759b8882009-08-06 16:27:28 +000087}
Chris Lattnerf0144122009-07-28 03:13:23 +000088
Chris Lattnera87dea42009-07-31 18:48:30 +000089const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +000090PIC16TargetObjectFile::getBSSSectionForGlobal(const GlobalVariable *GV) const {
91 assert(GV->hasInitializer() && "This global doesn't need space");
92 Constant *C = GV->getInitializer();
93 assert(C->isNullValue() && "Unitialized globals has non-zero initializer");
94
95 // Find how much space this global needs.
Chris Lattnera87dea42009-07-31 18:48:30 +000096 const TargetData *TD = TM->getTargetData();
Chris Lattnerf0144122009-07-28 03:13:23 +000097 const Type *Ty = C->getType();
98 unsigned ValSize = TD->getTypeAllocSize(Ty);
99
100 // Go through all BSS Sections and assign this variable
101 // to the first available section having enough space.
102 PIC16Section *FoundBSS = NULL;
103 for (unsigned i = 0; i < BSSSections.size(); i++) {
104 if (DataBankSize - BSSSections[i]->Size >= ValSize) {
105 FoundBSS = BSSSections[i];
106 break;
107 }
108 }
109
110 // No BSS section spacious enough was found. Crate a new one.
111 if (!FoundBSS) {
112 std::string name = PAN::getUdataSectionName(BSSSections.size());
Chris Lattner93b6db32009-08-08 23:39:42 +0000113 const MCSectionPIC16 *NewSection
Sanjiv Gupta72f9ab02009-09-01 10:47:31 +0000114 = getPIC16Section(name.c_str(), MCSectionPIC16::UDATA_Kind());
Chris Lattnerf0144122009-07-28 03:13:23 +0000115
116 FoundBSS = new PIC16Section(NewSection);
117
118 // Add this newly created BSS section to the list of BSSSections.
119 BSSSections.push_back(FoundBSS);
120 }
121
122 // Insert the GV into this BSS.
123 FoundBSS->Items.push_back(GV);
124 FoundBSS->Size += ValSize;
125 return FoundBSS->S_;
126}
127
Chris Lattnera87dea42009-07-31 18:48:30 +0000128const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000129PIC16TargetObjectFile::getIDATASectionForGlobal(const GlobalVariable *GV) const{
130 assert(GV->hasInitializer() && "This global doesn't need space");
131 Constant *C = GV->getInitializer();
132 assert(!C->isNullValue() && "initialized globals has zero initializer");
133 assert(GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
134 "can split initialized RAM data only");
135
136 // Find how much space this global needs.
Chris Lattnera87dea42009-07-31 18:48:30 +0000137 const TargetData *TD = TM->getTargetData();
Chris Lattnerf0144122009-07-28 03:13:23 +0000138 const Type *Ty = C->getType();
139 unsigned ValSize = TD->getTypeAllocSize(Ty);
140
141 // Go through all IDATA Sections and assign this variable
142 // to the first available section having enough space.
143 PIC16Section *FoundIDATA = NULL;
144 for (unsigned i = 0; i < IDATASections.size(); i++) {
145 if (DataBankSize - IDATASections[i]->Size >= ValSize) {
146 FoundIDATA = IDATASections[i];
147 break;
148 }
149 }
150
151 // No IDATA section spacious enough was found. Crate a new one.
152 if (!FoundIDATA) {
153 std::string name = PAN::getIdataSectionName(IDATASections.size());
Chris Lattner93b6db32009-08-08 23:39:42 +0000154 const MCSectionPIC16 *NewSection =
Sanjiv Gupta72f9ab02009-09-01 10:47:31 +0000155 getPIC16Section(name.c_str(), MCSectionPIC16::IDATA_Kind());
Chris Lattnerf0144122009-07-28 03:13:23 +0000156
157 FoundIDATA = new PIC16Section(NewSection);
158
159 // Add this newly created IDATA section to the list of IDATASections.
160 IDATASections.push_back(FoundIDATA);
161 }
162
163 // Insert the GV into this IDATA.
164 FoundIDATA->Items.push_back(GV);
165 FoundIDATA->Size += ValSize;
166 return FoundIDATA->S_;
167}
168
169// Get the section for an automatic variable of a function.
170// For PIC16 they are globals only with mangled names.
Chris Lattnera87dea42009-07-31 18:48:30 +0000171const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000172PIC16TargetObjectFile::getSectionForAuto(const GlobalVariable *GV) const {
173
174 const std::string name = PAN::getSectionNameForSym(GV->getName());
175
176 // Go through all Auto Sections and assign this variable
177 // to the appropriate section.
178 PIC16Section *FoundAutoSec = NULL;
179 for (unsigned i = 0; i < AutosSections.size(); i++) {
180 if (AutosSections[i]->S_->getName() == name) {
181 FoundAutoSec = AutosSections[i];
182 break;
183 }
184 }
185
186 // No Auto section was found. Crate a new one.
187 if (!FoundAutoSec) {
Chris Lattner93b6db32009-08-08 23:39:42 +0000188 const MCSectionPIC16 *NewSection =
Sanjiv Gupta72f9ab02009-09-01 10:47:31 +0000189 getPIC16Section(name.c_str(), MCSectionPIC16::UDATA_OVR_Kind());
Chris Lattnerf0144122009-07-28 03:13:23 +0000190
191 FoundAutoSec = new PIC16Section(NewSection);
192
193 // Add this newly created autos section to the list of AutosSections.
194 AutosSections.push_back(FoundAutoSec);
195 }
196
197 // Insert the auto into this section.
198 FoundAutoSec->Items.push_back(GV);
199
200 return FoundAutoSec->S_;
201}
202
203
204// Override default implementation to put the true globals into
205// multiple data sections if required.
Chris Lattnera87dea42009-07-31 18:48:30 +0000206const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000207PIC16TargetObjectFile::SelectSectionForGlobal(const GlobalValue *GV1,
Chris Lattnerf9650c02009-08-01 21:46:23 +0000208 SectionKind Kind,
Chris Lattnere53a6002009-07-29 05:09:30 +0000209 Mangler *Mang,
Chris Lattnerf0144122009-07-28 03:13:23 +0000210 const TargetMachine &TM) const {
211 // We select the section based on the initializer here, so it really
212 // has to be a GlobalVariable.
213 const GlobalVariable *GV = dyn_cast<GlobalVariable>(GV1);
214 if (!GV)
Chris Lattnerf9650c02009-08-01 21:46:23 +0000215 return TargetLoweringObjectFile::SelectSectionForGlobal(GV1, Kind, Mang,TM);
Chris Lattnerf0144122009-07-28 03:13:23 +0000216
217 // Record External Var Decls.
218 if (GV->isDeclaration()) {
219 ExternalVarDecls->Items.push_back(GV);
220 return ExternalVarDecls->S_;
221 }
222
223 assert(GV->hasInitializer() && "A def without initializer?");
224
225 // First, if this is an automatic variable for a function, get the section
226 // name for it and return.
227 std::string name = GV->getName();
228 if (PAN::isLocalName(name))
229 return getSectionForAuto(GV);
230
231 // Record Exteranl Var Defs.
232 if (GV->hasExternalLinkage() || GV->hasCommonLinkage())
233 ExternalVarDefs->Items.push_back(GV);
234
235 // See if this is an uninitialized global.
236 const Constant *C = GV->getInitializer();
237 if (C->isNullValue())
238 return getBSSSectionForGlobal(GV);
239
240 // If this is initialized data in RAM. Put it in the correct IDATA section.
241 if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE)
242 return getIDATASectionForGlobal(GV);
243
244 // This is initialized data in rom, put it in the readonly section.
245 if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE)
246 return getROSectionForGlobal(GV);
247
248 // Else let the default implementation take care of it.
Chris Lattnerf9650c02009-08-01 21:46:23 +0000249 return TargetLoweringObjectFile::SelectSectionForGlobal(GV, Kind, Mang,TM);
Chris Lattnerf0144122009-07-28 03:13:23 +0000250}
251
252PIC16TargetObjectFile::~PIC16TargetObjectFile() {
253 for (unsigned i = 0; i < BSSSections.size(); i++)
254 delete BSSSections[i];
255 for (unsigned i = 0; i < IDATASections.size(); i++)
256 delete IDATASections[i];
257 for (unsigned i = 0; i < AutosSections.size(); i++)
258 delete AutosSections[i];
259 for (unsigned i = 0; i < ROSections.size(); i++)
260 delete ROSections[i];
261 delete ExternalVarDecls;
262 delete ExternalVarDefs;
263}
264
265
266/// getSpecialCasedSectionGlobals - Allow the target to completely override
267/// section assignment of a global.
Chris Lattner24f654c2009-08-06 16:39:58 +0000268const MCSection *PIC16TargetObjectFile::
269getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
270 Mangler *Mang, const TargetMachine &TM) const {
271 assert(GV->hasSection());
272
273 if (const GlobalVariable *GVar = cast<GlobalVariable>(GV)) {
274 std::string SectName = GVar->getSection();
275 // If address for a variable is specified, get the address and create
276 // section.
277 std::string AddrStr = "Address=";
278 if (SectName.compare(0, AddrStr.length(), AddrStr) == 0) {
279 std::string SectAddr = SectName.substr(AddrStr.length());
280 return CreateSectionForGlobal(GVar, Mang, SectAddr);
Chris Lattnerf0144122009-07-28 03:13:23 +0000281 }
Chris Lattner24f654c2009-08-06 16:39:58 +0000282
283 // Create the section specified with section attribute.
284 return CreateSectionForGlobal(GVar, Mang);
Chris Lattnerf0144122009-07-28 03:13:23 +0000285 }
286
Chris Lattner93b6db32009-08-08 23:39:42 +0000287 return getPIC16Section(GV->getSection().c_str(), Kind);
Chris Lattnerf0144122009-07-28 03:13:23 +0000288}
289
290// Create a new section for global variable. If Addr is given then create
291// section at that address else create by name.
Chris Lattnera87dea42009-07-31 18:48:30 +0000292const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000293PIC16TargetObjectFile::CreateSectionForGlobal(const GlobalVariable *GV,
Chris Lattnere53a6002009-07-29 05:09:30 +0000294 Mangler *Mang,
Chris Lattnerf0144122009-07-28 03:13:23 +0000295 const std::string &Addr) const {
296 // See if this is an uninitialized global.
297 const Constant *C = GV->getInitializer();
298 if (C->isNullValue())
299 return CreateBSSSectionForGlobal(GV, Addr);
300
301 // If this is initialized data in RAM. Put it in the correct IDATA section.
302 if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE)
303 return CreateIDATASectionForGlobal(GV, Addr);
304
305 // This is initialized data in rom, put it in the readonly section.
306 if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE)
307 return CreateROSectionForGlobal(GV, Addr);
308
309 // Else let the default implementation take care of it.
Chris Lattnera87dea42009-07-31 18:48:30 +0000310 return TargetLoweringObjectFile::SectionForGlobal(GV, Mang, *TM);
Chris Lattnerf0144122009-07-28 03:13:23 +0000311}
312
313// Create uninitialized section for a variable.
Chris Lattnera87dea42009-07-31 18:48:30 +0000314const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000315PIC16TargetObjectFile::CreateBSSSectionForGlobal(const GlobalVariable *GV,
316 std::string Addr) const {
317 assert(GV->hasInitializer() && "This global doesn't need space");
318 assert(GV->getInitializer()->isNullValue() &&
319 "Unitialized global has non-zero initializer");
320 std::string Name;
321 // If address is given then create a section at that address else create a
322 // section by section name specified in GV.
323 PIC16Section *FoundBSS = NULL;
324 if (Addr.empty()) {
325 Name = GV->getSection() + " UDATA";
326 for (unsigned i = 0; i < BSSSections.size(); i++) {
327 if (BSSSections[i]->S_->getName() == Name) {
328 FoundBSS = BSSSections[i];
329 break;
330 }
331 }
332 } else {
333 std::string Prefix = GV->getNameStr() + "." + Addr + ".";
334 Name = PAN::getUdataSectionName(BSSSections.size(), Prefix) + " " + Addr;
335 }
336
337 PIC16Section *NewBSS = FoundBSS;
338 if (NewBSS == NULL) {
Chris Lattner93b6db32009-08-08 23:39:42 +0000339 const MCSectionPIC16 *NewSection =
Sanjiv Gupta72f9ab02009-09-01 10:47:31 +0000340 getPIC16Section(Name.c_str(), MCSectionPIC16::UDATA_Kind());
Chris Lattnerf0144122009-07-28 03:13:23 +0000341 NewBSS = new PIC16Section(NewSection);
342 BSSSections.push_back(NewBSS);
343 }
344
345 // Insert the GV into this BSS.
346 NewBSS->Items.push_back(GV);
347
348 // We do not want to put any GV without explicit section into this section
349 // so set its size to DatabankSize.
350 NewBSS->Size = DataBankSize;
351 return NewBSS->S_;
352}
353
354// Get rom section for a variable. Currently there can be only one rom section
355// unless a variable explicitly requests a section.
Chris Lattnera87dea42009-07-31 18:48:30 +0000356const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000357PIC16TargetObjectFile::getROSectionForGlobal(const GlobalVariable *GV) const {
358 ROSections[0]->Items.push_back(GV);
359 return ROSections[0]->S_;
360}
361
362// Create initialized data section for a variable.
Chris Lattnera87dea42009-07-31 18:48:30 +0000363const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000364PIC16TargetObjectFile::CreateIDATASectionForGlobal(const GlobalVariable *GV,
365 std::string Addr) const {
366 assert(GV->hasInitializer() && "This global doesn't need space");
367 assert(!GV->getInitializer()->isNullValue() &&
368 "initialized global has zero initializer");
369 assert(GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
370 "can be used for initialized RAM data only");
371
372 std::string Name;
373 // If address is given then create a section at that address else create a
374 // section by section name specified in GV.
375 PIC16Section *FoundIDATASec = NULL;
376 if (Addr.empty()) {
377 Name = GV->getSection() + " IDATA";
378 for (unsigned i = 0; i < IDATASections.size(); i++) {
379 if (IDATASections[i]->S_->getName() == Name) {
380 FoundIDATASec = IDATASections[i];
381 break;
382 }
383 }
384 } else {
385 std::string Prefix = GV->getNameStr() + "." + Addr + ".";
386 Name = PAN::getIdataSectionName(IDATASections.size(), Prefix) + " " + Addr;
387 }
388
389 PIC16Section *NewIDATASec = FoundIDATASec;
390 if (NewIDATASec == NULL) {
Chris Lattner93b6db32009-08-08 23:39:42 +0000391 const MCSectionPIC16 *NewSection =
Sanjiv Gupta72f9ab02009-09-01 10:47:31 +0000392 getPIC16Section(Name.c_str(), MCSectionPIC16::IDATA_Kind());
Chris Lattnerf0144122009-07-28 03:13:23 +0000393 NewIDATASec = new PIC16Section(NewSection);
394 IDATASections.push_back(NewIDATASec);
395 }
396 // Insert the GV into this IDATA Section.
397 NewIDATASec->Items.push_back(GV);
398 // We do not want to put any GV without explicit section into this section
399 // so set its size to DatabankSize.
400 NewIDATASec->Size = DataBankSize;
401 return NewIDATASec->S_;
402}
403
404// Create a section in rom for a variable.
Chris Lattnera87dea42009-07-31 18:48:30 +0000405const MCSection *
Chris Lattnerf0144122009-07-28 03:13:23 +0000406PIC16TargetObjectFile::CreateROSectionForGlobal(const GlobalVariable *GV,
407 std::string Addr) const {
408 assert(GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE &&
409 "can be used for ROM data only");
410
411 std::string Name;
412 // If address is given then create a section at that address else create a
413 // section by section name specified in GV.
414 PIC16Section *FoundROSec = NULL;
415 if (Addr.empty()) {
416 Name = GV->getSection() + " ROMDATA";
417 for (unsigned i = 1; i < ROSections.size(); i++) {
418 if (ROSections[i]->S_->getName() == Name) {
419 FoundROSec = ROSections[i];
420 break;
421 }
422 }
423 } else {
424 std::string Prefix = GV->getNameStr() + "." + Addr + ".";
425 Name = PAN::getRomdataSectionName(ROSections.size(), Prefix) + " " + Addr;
426 }
427
428 PIC16Section *NewRomSec = FoundROSec;
429 if (NewRomSec == NULL) {
Chris Lattner93b6db32009-08-08 23:39:42 +0000430 const MCSectionPIC16 *NewSection =
Sanjiv Gupta72f9ab02009-09-01 10:47:31 +0000431 getPIC16Section(Name.c_str(), MCSectionPIC16::ROMDATA_Kind());
Chris Lattnerf0144122009-07-28 03:13:23 +0000432 NewRomSec = new PIC16Section(NewSection);
433 ROSections.push_back(NewRomSec);
434 }
435
436 // Insert the GV into this ROM Section.
437 NewRomSec->Items.push_back(GV);
438 return NewRomSec->S_;
439}
440