Changed lowering and asmprinter to use ABI Names class called PAN.
[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   GlobalPrefix = PAN::getTagName(PAN::PREFIX_SYMBOL);
27   GlobalDirective = "\tglobal\t";
28   ExternDirective = "\textern\t";
29
30   Data8bitsDirective = " db ";
31   Data16bitsDirective = " dw ";
32   Data32bitsDirective = " dl ";
33   RomData8bitsDirective = " dw ";
34   RomData16bitsDirective = " rom_di ";
35   RomData32bitsDirective = " rom_dl ";
36   ZeroDirective = NULL;
37   AsciiDirective = " dt ";
38   AscizDirective = NULL;
39   BSSSection_  = getNamedSection("udata.# UDATA",
40                               SectionFlags::Writeable | SectionFlags::BSS);
41   ReadOnlySection = getNamedSection("romdata.# ROMDATA", SectionFlags::None);
42   DataSection = getNamedSection("idata.# IDATA", SectionFlags::Writeable);
43   SwitchToSectionDirective = "";
44   // Need because otherwise a .text symbol is emitted by DwarfWriter
45   // in BeginModule, and gpasm cribbs for that .text symbol.
46   TextSection = getUnnamedSection("", SectionFlags::Code);
47 }
48
49 const char *PIC16TargetAsmInfo::getRomDirective(unsigned size) const
50 {
51   if (size == 8)
52     return RomData8bitsDirective;
53   else if (size == 16)
54     return RomData16bitsDirective;
55   else if (size == 32)
56     return RomData32bitsDirective;
57   else
58     return NULL;
59 }
60
61
62 const char *PIC16TargetAsmInfo::getASDirective(unsigned size, 
63                                                unsigned AS) const {
64   if (AS == PIC16ISD::ROM_SPACE)
65     return getRomDirective(size);
66   else
67     return NULL;
68 }
69
70 const Section *
71 PIC16TargetAsmInfo::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.
77   const TargetData *TD = TM.getTargetData();
78   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());
94     const Section *NewSection = getNamedSection (name.c_str());
95
96     FoundBSS = new PIC16Section(NewSection);
97
98     // Add this newly created BSS section to the list of BSSSections.
99     BSSSections.push_back(FoundBSS);
100   }
101   
102   // Insert the GV into this BSS.
103   FoundBSS->Items.push_back(GV);
104   FoundBSS->Size += ValSize;
105
106   // We can't do this here because GV is const .
107   // const std::string SName = FoundBSS->S_->getName();
108   // GV->setSection(SName);
109
110   return FoundBSS->S_;
111
112
113 const Section *
114 PIC16TargetAsmInfo::getIDATASectionForGlobal(const GlobalVariable *GV) const {
115   assert (GV->hasInitializer() && "This global doesn't need space");
116   Constant *C = GV->getInitializer();
117   assert (!C->isNullValue() && "initialized globals has zero initializer");
118   assert (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
119           "can split initialized RAM data only");
120
121   // Find how much space this global needs.
122   const TargetData *TD = TM.getTargetData();
123   const Type *Ty = C->getType(); 
124   unsigned ValSize = TD->getTypeAllocSize(Ty);
125  
126   // Go through all IDATA Sections and assign this variable
127   // to the first available section having enough space.
128   PIC16Section *FoundIDATA = NULL;
129   for (unsigned i = 0; i < IDATASections.size(); i++) {
130     if ( DataBankSize - IDATASections[i]->Size >= ValSize) {
131       FoundIDATA = IDATASections[i]; 
132       break;
133     }
134   }
135
136   // No IDATA section spacious enough was found. Crate a new one.
137   if (! FoundIDATA) {
138     std::string name = PAN::getIdataSectionName(IDATASections.size());
139     const Section *NewSection = getNamedSection (name.c_str());
140
141     FoundIDATA = new PIC16Section(NewSection);
142
143     // Add this newly created IDATA section to the list of IDATASections.
144     IDATASections.push_back(FoundIDATA);
145   }
146   
147   // Insert the GV into this IDATA.
148   FoundIDATA->Items.push_back(GV);
149   FoundIDATA->Size += ValSize;
150
151   // We can't do this here because GV is const .
152   // GV->setSection(FoundIDATA->S->getName());
153
154   return FoundIDATA->S_;
155
156
157 // Override default implementation to put the true globals into
158 // multiple data sections if required.
159 const Section*
160 PIC16TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV1) const {
161   // We select the section based on the initializer here, so it really
162   // has to be a GlobalVariable.
163   const GlobalVariable *GV = dyn_cast<GlobalVariable>(GV1); 
164   if (!GV1 || ! GV->hasInitializer())
165     return TargetAsmInfo::SelectSectionForGlobal(GV1);
166
167   // First, if this is an automatic variable for a function, get the section
168   // name for it and return.
169   const std::string name = GV->getName();
170   if (PAN::isLocalName(name)) {
171     const std::string Sec_Name = PAN::getSectionNameForSym(name);
172     return getNamedSection(Sec_Name.c_str());
173   }
174
175   // See if this is an uninitialized global.
176   const Constant *C = GV->getInitializer();
177   if (C->isNullValue()) 
178     return getBSSSectionForGlobal(GV); 
179
180   // This is initialized data. We only deal with initialized data in RAM.
181   if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) 
182     return getIDATASectionForGlobal(GV);
183
184     
185   // Else let the default implementation take care of it.
186   return TargetAsmInfo::SelectSectionForGlobal(GV);
187 }
188
189 PIC16TargetAsmInfo::~PIC16TargetAsmInfo() {
190   
191   for (unsigned i = 0; i < BSSSections.size(); i++) {
192       delete BSSSections[i]; 
193   }
194
195   for (unsigned i = 0; i < IDATASections.size(); i++) {
196       delete IDATASections[i]; 
197   }
198 }