Rename PaddedSize to AllocSize, in the hope that this
[oota-llvm.git] / lib / Target / PIC16 / PIC16TargetAsmInfo.cpp
1 //===-- PIC16TargetAsmInfo.cpp - PIC16 asm properties ---------------------===//
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 // This file contains the declarations of the PIC16TargetAsmInfo properties.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "PIC16TargetAsmInfo.h"
15 #include "PIC16TargetMachine.h"
16 #include "llvm/GlobalValue.h"
17 #include "llvm/GlobalVariable.h"
18 #include "llvm/DerivedTypes.h"
19
20 using namespace llvm;
21
22 PIC16TargetAsmInfo::
23 PIC16TargetAsmInfo(const PIC16TargetMachine &TM) 
24   : TargetAsmInfo(TM) {
25   CommentString = ";";
26   Data8bitsDirective = " db ";
27   Data16bitsDirective = " dw ";
28   Data32bitsDirective = " dl ";
29   RomData8bitsDirective = " dw ";
30   RomData16bitsDirective = " rom_di ";
31   RomData32bitsDirective = " rom_dl ";
32   ZeroDirective = NULL;
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);
43 }
44
45 const char *PIC16TargetAsmInfo::getRomDirective(unsigned size) const
46 {
47   if (size == 8)
48     return RomData8bitsDirective;
49   else if (size == 16)
50     return RomData16bitsDirective;
51   else if (size == 32)
52     return RomData32bitsDirective;
53   else
54     return NULL;
55 }
56
57
58 const char *PIC16TargetAsmInfo::getASDirective(unsigned size, 
59                                                unsigned AS) const {
60   if (AS == PIC16ISD::ROM_SPACE)
61     return getRomDirective(size);
62   else
63     return NULL;
64 }
65
66 const Section *
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");
71
72   // Find how much space this global needs.
73   const TargetData *TD = TM.getTargetData();
74   const Type *Ty = C->getType(); 
75   unsigned ValSize = TD->getTypeAllocSize(Ty);
76  
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];
83       break;
84     }
85   }
86
87   // No BSS section spacious enough was found. Crate a new one.
88   if (! FoundBSS) {
89     char *name = new char[32];
90     sprintf (name, "udata.%d.# UDATA", (int)BSSSections.size());
91     const Section *NewSection = getNamedSection (name);
92
93     FoundBSS = new PIC16Section(NewSection);
94
95     // Add this newly created BSS section to the list of BSSSections.
96     BSSSections.push_back(FoundBSS);
97   }
98   
99   // Insert the GV into this BSS.
100   FoundBSS->Items.push_back(GV);
101   FoundBSS->Size += ValSize;
102
103   // We can't do this here because GV is const .
104   // const std::string SName = FoundBSS->S_->getName();
105   // GV->setSection(SName);
106
107   return FoundBSS->S_;
108
109
110 const Section *
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");
117
118   // Find how much space this global needs.
119   const TargetData *TD = TM.getTargetData();
120   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     char *name = new char[32];
136     sprintf (name, "idata.%d.# IDATA", (int)IDATASections.size());
137     const Section *NewSection = getNamedSection (name);
138
139     FoundIDATA = new PIC16Section(NewSection);
140
141     // Add this newly created IDATA section to the list of IDATASections.
142     IDATASections.push_back(FoundIDATA);
143   }
144   
145   // Insert the GV into this IDATA.
146   FoundIDATA->Items.push_back(GV);
147   FoundIDATA->Size += ValSize;
148
149   // We can't do this here because GV is const .
150   // GV->setSection(FoundIDATA->S->getName());
151
152   return FoundIDATA->S_;
153
154
155 // Override default implementation to put the true globals into
156 // multiple data sections if required.
157 const Section*
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);
163
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);
171
172   const Constant *C = GV->getInitializer();
173   // See if this is an uninitialized global.
174   if (C->isNullValue()) 
175     return getBSSSectionForGlobal(GV); 
176
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);
180
181   // Else let the default implementation take care of it.
182   return TargetAsmInfo::SelectSectionForGlobal(GV);
183 }
184
185 void PIC16TargetAsmInfo::SetSectionForGVs(Module &M) {
186   for (Module::global_iterator I = M.global_begin(), E = M.global_end();
187        I != E; ++I) {
188     if (!I->hasInitializer())   // External global require no code.
189       continue;
190
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(".args.") != std::string::npos)
196       continue;
197     int AddrSpace = I->getType()->getAddressSpace();
198
199     if (AddrSpace == PIC16ISD::RAM_SPACE)
200       I->setSection(SectionForGlobal(I)->getName());
201   }
202 }
203
204
205 PIC16TargetAsmInfo::~PIC16TargetAsmInfo() {
206   
207   for (unsigned i = 0; i < BSSSections.size(); i++) {
208       delete BSSSections[i]; 
209   }
210
211   for (unsigned i = 0; i < IDATASections.size(); i++) {
212       delete IDATASections[i]; 
213   }
214 }