Use MVN for ~t2_so_imm immediates.
[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   ROSection = new PIC16Section(getReadOnlySection());
48   ExternalVarDecls = new PIC16Section(getNamedSection("ExternalVarDecls"));
49   ExternalVarDefs = new PIC16Section(getNamedSection("ExternalVarDefs"));
50   // Set it to false because we weed to generate c file name and not bc file
51   // name.
52   HasSingleParameterDotFile = false;
53 }
54
55 const char *PIC16TargetAsmInfo::getRomDirective(unsigned size) const
56 {
57   if (size == 8)
58     return RomData8bitsDirective;
59   else if (size == 16)
60     return RomData16bitsDirective;
61   else if (size == 32)
62     return RomData32bitsDirective;
63   else
64     return NULL;
65 }
66
67
68 const char *PIC16TargetAsmInfo::getASDirective(unsigned size, 
69                                                unsigned AS) const {
70   if (AS == PIC16ISD::ROM_SPACE)
71     return getRomDirective(size);
72   else
73     return NULL;
74 }
75
76 const Section *
77 PIC16TargetAsmInfo::getBSSSectionForGlobal(const GlobalVariable *GV) const {
78   assert (GV->hasInitializer() && "This global doesn't need space");
79   Constant *C = GV->getInitializer();
80   assert (C->isNullValue() && "Unitialized globals has non-zero initializer");
81
82   // Find how much space this global needs.
83   const TargetData *TD = TM.getTargetData();
84   const Type *Ty = C->getType(); 
85   unsigned ValSize = TD->getTypeAllocSize(Ty);
86  
87   // Go through all BSS Sections and assign this variable
88   // to the first available section having enough space.
89   PIC16Section *FoundBSS = NULL;
90   for (unsigned i = 0; i < BSSSections.size(); i++) {
91     if (DataBankSize - BSSSections[i]->Size >= ValSize) {
92       FoundBSS = BSSSections[i];
93       break;
94     }
95   }
96
97   // No BSS section spacious enough was found. Crate a new one.
98   if (! FoundBSS) {
99     std::string name = PAN::getUdataSectionName(BSSSections.size());
100     const Section *NewSection = getNamedSection (name.c_str());
101
102     FoundBSS = new PIC16Section(NewSection);
103
104     // Add this newly created BSS section to the list of BSSSections.
105     BSSSections.push_back(FoundBSS);
106   }
107   
108   // Insert the GV into this BSS.
109   FoundBSS->Items.push_back(GV);
110   FoundBSS->Size += ValSize;
111
112   // We can't do this here because GV is const .
113   // const std::string SName = FoundBSS->S_->getName();
114   // GV->setSection(SName);
115
116   return FoundBSS->S_;
117
118
119 const Section *
120 PIC16TargetAsmInfo::getIDATASectionForGlobal(const GlobalVariable *GV) const {
121   assert (GV->hasInitializer() && "This global doesn't need space");
122   Constant *C = GV->getInitializer();
123   assert (!C->isNullValue() && "initialized globals has zero initializer");
124   assert (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
125           "can split initialized RAM data only");
126
127   // Find how much space this global needs.
128   const TargetData *TD = TM.getTargetData();
129   const Type *Ty = C->getType(); 
130   unsigned ValSize = TD->getTypeAllocSize(Ty);
131  
132   // Go through all IDATA Sections and assign this variable
133   // to the first available section having enough space.
134   PIC16Section *FoundIDATA = NULL;
135   for (unsigned i = 0; i < IDATASections.size(); i++) {
136     if ( DataBankSize - IDATASections[i]->Size >= ValSize) {
137       FoundIDATA = IDATASections[i]; 
138       break;
139     }
140   }
141
142   // No IDATA section spacious enough was found. Crate a new one.
143   if (! FoundIDATA) {
144     std::string name = PAN::getIdataSectionName(IDATASections.size());
145     const Section *NewSection = getNamedSection (name.c_str());
146
147     FoundIDATA = new PIC16Section(NewSection);
148
149     // Add this newly created IDATA section to the list of IDATASections.
150     IDATASections.push_back(FoundIDATA);
151   }
152   
153   // Insert the GV into this IDATA.
154   FoundIDATA->Items.push_back(GV);
155   FoundIDATA->Size += ValSize;
156
157   // We can't do this here because GV is const .
158   // GV->setSection(FoundIDATA->S->getName());
159
160   return FoundIDATA->S_;
161
162
163 // Get the section for an automatic variable of a function.
164 // For PIC16 they are globals only with mangled names.
165 const Section *
166 PIC16TargetAsmInfo::getSectionForAuto(const GlobalVariable *GV) const {
167
168   const std::string name = PAN::getSectionNameForSym(GV->getName());
169
170   // Go through all Auto Sections and assign this variable
171   // to the appropriate section.
172   PIC16Section *FoundAutoSec = NULL;
173   for (unsigned i = 0; i < AutosSections.size(); i++) {
174     if ( AutosSections[i]->S_->getName() == name) {
175       FoundAutoSec = AutosSections[i];
176       break;
177     }
178   }
179
180   // No Auto section was found. Crate a new one.
181   if (! FoundAutoSec) {
182     const Section *NewSection = getNamedSection (name.c_str());
183
184     FoundAutoSec = new PIC16Section(NewSection);
185
186     // Add this newly created autos section to the list of AutosSections.
187     AutosSections.push_back(FoundAutoSec);
188   }
189
190   // Insert the auto into this section.
191   FoundAutoSec->Items.push_back(GV);
192
193   return FoundAutoSec->S_;
194 }
195
196
197 // Override default implementation to put the true globals into
198 // multiple data sections if required.
199 const Section*
200 PIC16TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV1) const {
201   // We select the section based on the initializer here, so it really
202   // has to be a GlobalVariable.
203   const GlobalVariable *GV = dyn_cast<GlobalVariable>(GV1); 
204
205   if (!GV)
206     return TargetAsmInfo::SelectSectionForGlobal(GV1);
207
208   // Record Exteranl Var Decls.
209   if (GV->isDeclaration()) {
210     ExternalVarDecls->Items.push_back(GV);
211     return ExternalVarDecls->S_;
212   }
213     
214   assert (GV->hasInitializer() && "A def without initializer?");
215
216   // First, if this is an automatic variable for a function, get the section
217   // name for it and return.
218   const std::string name = GV->getName();
219   if (PAN::isLocalName(name)) {
220     return getSectionForAuto(GV);
221   }
222
223   // Record Exteranl Var Defs.
224   if (GV->hasExternalLinkage() || GV->hasCommonLinkage()) {
225     ExternalVarDefs->Items.push_back(GV);
226   }
227
228   // See if this is an uninitialized global.
229   const Constant *C = GV->getInitializer();
230   if (C->isNullValue()) 
231     return getBSSSectionForGlobal(GV); 
232
233   // If this is initialized data in RAM. Put it in the correct IDATA section.
234   if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) 
235     return getIDATASectionForGlobal(GV);
236
237   // This is initialized data in rom, put it in the readonly section.
238   if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) {
239     ROSection->Items.push_back(GV);
240     return ROSection->S_;
241   }
242
243   // Else let the default implementation take care of it.
244   return TargetAsmInfo::SelectSectionForGlobal(GV);
245 }
246
247 PIC16TargetAsmInfo::~PIC16TargetAsmInfo() {
248   
249   for (unsigned i = 0; i < BSSSections.size(); i++) {
250       delete BSSSections[i]; 
251   }
252
253   for (unsigned i = 0; i < IDATASections.size(); i++) {
254       delete IDATASections[i]; 
255   }
256
257   for (unsigned i = 0; i < AutosSections.size(); i++) {
258       delete AutosSections[i]; 
259   }
260
261   delete ROSection;
262   delete ExternalVarDecls;
263   delete ExternalVarDefs;
264 }