1 //===-- PIC16TargetAsmInfo.cpp - PIC16 asm properties ---------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the declarations of the PIC16TargetAsmInfo properties.
12 //===----------------------------------------------------------------------===//
14 #include "PIC16TargetAsmInfo.h"
15 #include "PIC16TargetMachine.h"
16 #include "llvm/GlobalValue.h"
17 #include "llvm/GlobalVariable.h"
18 #include "llvm/DerivedTypes.h"
23 PIC16TargetAsmInfo(const PIC16TargetMachine &TM)
26 Data8bitsDirective = " db ";
27 Data16bitsDirective = " dw ";
28 Data32bitsDirective = " dl ";
29 RomData8bitsDirective = " dw ";
30 RomData16bitsDirective = " rom_di ";
31 RomData32bitsDirective = " rom_dl ";
33 AsciiDirective = " dt ";
34 AscizDirective = NULL;
35 BSSSection_ = getNamedSection("udata.# UDATA",
36 SectionFlags::Writeable | SectionFlags::BSS);
37 ReadOnlySection = getNamedSection("romdata.# ROMDATA", SectionFlags::None);
38 DataSection = getNamedSection("idata.# IDATA", SectionFlags::Writeable);
39 SwitchToSectionDirective = "";
40 // Need because otherwise a .text symbol is emitted by DwarfWriter
41 // in BeginModule, and gpasm cribbs for that .text symbol.
42 TextSection = getUnnamedSection("", SectionFlags::Code);
45 const char *PIC16TargetAsmInfo::getRomDirective(unsigned size) const
48 return RomData8bitsDirective;
50 return RomData16bitsDirective;
52 return RomData32bitsDirective;
58 const char *PIC16TargetAsmInfo::getASDirective(unsigned size,
60 if (AS == PIC16ISD::ROM_SPACE)
61 return getRomDirective(size);
67 PIC16TargetAsmInfo::getBSSSectionForGlobal(const GlobalVariable *GV) const {
68 assert (GV->hasInitializer() && "This global doesn't need space");
69 Constant *C = GV->getInitializer();
70 assert (C->isNullValue() && "Unitialized globals has non-zero initializer");
72 // Find how much space this global needs.
73 const TargetData *TD = TM.getTargetData();
74 const Type *Ty = C->getType();
75 unsigned ValSize = TD->getTypePaddedSize(Ty);
77 // Go through all BSS Sections and assign this variable
78 // to the first available section having enough space.
79 PIC16Section *FoundBSS = NULL;
80 for (unsigned i = 0; i < BSSSections.size(); i++) {
81 if (DataBankSize - BSSSections[i]->Size >= ValSize) {
82 FoundBSS = BSSSections[i];
87 // No BSS section spacious enough was found. Crate a new one.
89 char *name = new char[32];
90 sprintf (name, "udata.%d.# UDATA", BSSSections.size());
91 const Section *NewSection = getNamedSection (name);
93 FoundBSS = new PIC16Section(NewSection);
95 // Add this newly created BSS section to the list of BSSSections.
96 BSSSections.push_back(FoundBSS);
99 // Insert the GV into this BSS.
100 FoundBSS->Items.push_back(GV);
101 FoundBSS->Size += ValSize;
103 // We can't do this here because GV is const .
104 // const std::string SName = FoundBSS->S_->getName();
105 // GV->setSection(SName);
111 PIC16TargetAsmInfo::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");
118 // Find how much space this global needs.
119 const TargetData *TD = TM.getTargetData();
120 const Type *Ty = C->getType();
121 unsigned ValSize = TD->getTypePaddedSize(Ty);
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];
133 // No IDATA section spacious enough was found. Crate a new one.
135 char *name = new char[32];
136 sprintf (name, "idata.%d.# IDATA", IDATASections.size());
137 const Section *NewSection = getNamedSection (name);
139 FoundIDATA = new PIC16Section(NewSection);
141 // Add this newly created IDATA section to the list of IDATASections.
142 IDATASections.push_back(FoundIDATA);
145 // Insert the GV into this IDATA.
146 FoundIDATA->Items.push_back(GV);
147 FoundIDATA->Size += ValSize;
149 // We can't do this here because GV is const .
150 // GV->setSection(FoundIDATA->S->getName());
152 return FoundIDATA->S_;
155 // Override default implementation to put the true globals into
156 // multiple data sections if required.
158 PIC16TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV1) const {
159 // We select the section based on the initializer here, so it really
160 // has to be a GlobalVariable.
161 if (!isa<GlobalVariable>(GV1))
162 return TargetAsmInfo::SelectSectionForGlobal(GV1);
164 const GlobalVariable *GV = dyn_cast<GlobalVariable>(GV1);
165 // We are only dealing with true globals here. So names with a "."
166 // are local globals. Also declarations are not entertained.
167 std::string name = GV->getName();
168 if (name.find(".auto.") != std::string::npos
169 || name.find(".arg.") != std::string::npos || !GV->hasInitializer())
170 return TargetAsmInfo::SelectSectionForGlobal(GV);
172 const Constant *C = GV->getInitializer();
173 // See if this is an uninitialized global.
174 if (C->isNullValue())
175 return getBSSSectionForGlobal(GV);
177 // This is initialized data. We only deal with initialized data in RAM.
178 if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE)
179 return getIDATASectionForGlobal(GV);
181 // Else let the default implementation take care of it.
182 return TargetAsmInfo::SelectSectionForGlobal(GV);
185 void PIC16TargetAsmInfo::SetSectionForGVs(Module &M) {
186 for (Module::global_iterator I = M.global_begin(), E = M.global_end();
188 if (!I->hasInitializer()) // External global require no code.
191 // Any variables reaching here with "." in its name is a local scope
192 // variable and should not be printed in global data section.
193 std::string name = I->getName();
194 if (name.find(".auto.") != std::string::npos
195 || name.find(".arg.") != std::string::npos)
197 int AddrSpace = I->getType()->getAddressSpace();
199 if (AddrSpace == PIC16ISD::RAM_SPACE)
200 I->setSection(SectionForGlobal(I)->getName());
206 // Func name starts after prefix and followed by a .
207 static std::string getFuncNameForSym(const std::string &Sym,
208 PIC16ABINames::IDs PrefixType) {
210 const char *prefix = getIDName (PIC16ABINames::PREFIX_SYMBOL);
212 // This name may or may not start with prefix;
213 // Func names start after prfix in that case.
214 size_t func_name_start = 0;
215 if (Sym.find(prefix, 0, strlen(prefix)) != std::string::npos)
216 func_name_start = strlen(prefix);
218 // Position of the . after func name.
219 size_t func_name_end = Sym.find ('.', func_name_start);
221 return Sym.substr (func_name_start, func_name_end);
224 // Helper routine to create a section name given the section prefix
227 getSectionNameForFunc (const std::string &Fname,
228 const PIC16ABINames::IDs sec_id) {
229 std::string sec_id_string = getIDName (sec_id);
230 return sec_id_string + "." + Fname + ".#";
234 // Get the section for the given external symbol names.
235 // This function is meant for only mangled external symbol names.
237 llvm::getSectionNameForSym(const std::string &Sym) {
238 std::string SectionName;
240 PIC16ABINames::IDs id = getID (Sym);
241 std::string Fname = getFuncNameForSym (Sym, id);
244 default : assert (0 && "Could not determine external symbol type");
245 case PIC16ABINames::FUNC_FRAME:
246 case PIC16ABINames::FUNC_RET:
247 case PIC16ABINames::FUNC_TEMPS:
248 case PIC16ABINames::FUNC_ARGS: {
249 return getSectionNameForFunc (Fname, PIC16ABINames::FRAME_SECTION);
251 case PIC16ABINames::FUNC_AUTOS: {
252 return getSectionNameForFunc (Fname, PIC16ABINames::AUTOS_SECTION);
257 PIC16TargetAsmInfo::~PIC16TargetAsmInfo() {
259 for (unsigned i = 0; i < BSSSections.size(); i++) {
260 delete BSSSections[i];
263 for (unsigned i = 0; i < IDATASections.size(); i++) {
264 delete IDATASections[i];