| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 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" | 
| Dan Gohman | 8f09225 | 2008-11-03 18:22:42 +0000 | [diff] [blame] | 15 | #include "PIC16TargetMachine.h" | 
| Sanjiv Gupta | 1b04694 | 2009-01-13 19:18:47 +0000 | [diff] [blame] | 16 | #include "llvm/GlobalValue.h" | 
| Sanjiv Gupta | d8d27f4 | 2009-05-06 08:02:01 +0000 | [diff] [blame] | 17 | #include "llvm/GlobalVariable.h" | 
|  | 18 | #include "llvm/DerivedTypes.h" | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 19 |  | 
|  | 20 | using namespace llvm; | 
|  | 21 |  | 
|  | 22 | PIC16TargetAsmInfo:: | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 23 | PIC16TargetAsmInfo(const PIC16TargetMachine &TM) | 
| Dan Gohman | 8f09225 | 2008-11-03 18:22:42 +0000 | [diff] [blame] | 24 | : TargetAsmInfo(TM) { | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 25 | CommentString = ";"; | 
| Sanjiv Gupta | 211f362 | 2009-05-10 05:23:47 +0000 | [diff] [blame] | 26 | GlobalPrefix = PAN::getTagName(PAN::PREFIX_SYMBOL); | 
|  | 27 | GlobalDirective = "\tglobal\t"; | 
|  | 28 | ExternDirective = "\textern\t"; | 
|  | 29 |  | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 30 | Data8bitsDirective = " db "; | 
| Sanjiv Gupta | c8d7bc8 | 2009-01-30 04:25:10 +0000 | [diff] [blame] | 31 | Data16bitsDirective = " dw "; | 
|  | 32 | Data32bitsDirective = " dl "; | 
| Sanjiv Gupta | 53cf829 | 2009-07-06 18:09:11 +0000 | [diff] [blame] | 33 | Data64bitsDirective = NULL; | 
| Sanjiv Gupta | c8d7bc8 | 2009-01-30 04:25:10 +0000 | [diff] [blame] | 34 | RomData8bitsDirective = " dw "; | 
|  | 35 | RomData16bitsDirective = " rom_di "; | 
| Sanjiv Gupta | 3b020fe | 2009-02-02 16:53:06 +0000 | [diff] [blame] | 36 | RomData32bitsDirective = " rom_dl "; | 
| Sanjiv Gupta | b1b5ffd | 2008-11-19 11:00:54 +0000 | [diff] [blame] | 37 | ZeroDirective = NULL; | 
| Sanjiv Gupta | 1b04694 | 2009-01-13 19:18:47 +0000 | [diff] [blame] | 38 | AsciiDirective = " dt "; | 
|  | 39 | AscizDirective = NULL; | 
|  | 40 | BSSSection_  = getNamedSection("udata.# UDATA", | 
|  | 41 | SectionFlags::Writeable | SectionFlags::BSS); | 
|  | 42 | ReadOnlySection = getNamedSection("romdata.# ROMDATA", SectionFlags::None); | 
|  | 43 | DataSection = getNamedSection("idata.# IDATA", SectionFlags::Writeable); | 
|  | 44 | SwitchToSectionDirective = ""; | 
| Sanjiv Gupta | c1fa70c | 2009-04-08 06:24:04 +0000 | [diff] [blame] | 45 | // Need because otherwise a .text symbol is emitted by DwarfWriter | 
|  | 46 | // in BeginModule, and gpasm cribbs for that .text symbol. | 
|  | 47 | TextSection = getUnnamedSection("", SectionFlags::Code); | 
| Sanjiv Gupta | 505996f | 2009-07-06 10:18:37 +0000 | [diff] [blame] | 48 | PIC16Section *ROSection = new PIC16Section(getReadOnlySection()); | 
|  | 49 | ROSections.push_back(ROSection); | 
| Sanjiv Gupta | ad6585b | 2009-05-13 15:13:17 +0000 | [diff] [blame] | 50 | ExternalVarDecls = new PIC16Section(getNamedSection("ExternalVarDecls")); | 
|  | 51 | ExternalVarDefs = new PIC16Section(getNamedSection("ExternalVarDefs")); | 
| Sanjiv Gupta | dd4694b | 2009-05-28 18:24:11 +0000 | [diff] [blame] | 52 | // Set it to false because we weed to generate c file name and not bc file | 
|  | 53 | // name. | 
|  | 54 | HasSingleParameterDotFile = false; | 
| Sanjiv Gupta | 0e68771 | 2008-05-13 09:02:57 +0000 | [diff] [blame] | 55 | } | 
| Sanjiv Gupta | c8d7bc8 | 2009-01-30 04:25:10 +0000 | [diff] [blame] | 56 |  | 
| Chris Lattner | 83757c7 | 2009-07-20 17:12:46 +0000 | [diff] [blame^] | 57 | const char *PIC16TargetAsmInfo::getRomDirective(unsigned Size) const { | 
|  | 58 | switch (Size) { | 
|  | 59 | case  8: return RomData8bitsDirective; | 
|  | 60 | case 16: return RomData16bitsDirective; | 
|  | 61 | case 32: return RomData32bitsDirective; | 
|  | 62 | default: return NULL; | 
|  | 63 | } | 
| Sanjiv Gupta | 3b020fe | 2009-02-02 16:53:06 +0000 | [diff] [blame] | 64 | } | 
| Sanjiv Gupta | c8d7bc8 | 2009-01-30 04:25:10 +0000 | [diff] [blame] | 65 |  | 
| Sanjiv Gupta | c8d7bc8 | 2009-01-30 04:25:10 +0000 | [diff] [blame] | 66 |  | 
| Chris Lattner | 83757c7 | 2009-07-20 17:12:46 +0000 | [diff] [blame^] | 67 | const char *PIC16TargetAsmInfo:: | 
|  | 68 | getDataASDirective(unsigned Size, unsigned AS) const { | 
| Sanjiv Gupta | 3b020fe | 2009-02-02 16:53:06 +0000 | [diff] [blame] | 69 | if (AS == PIC16ISD::ROM_SPACE) | 
| Chris Lattner | 83757c7 | 2009-07-20 17:12:46 +0000 | [diff] [blame^] | 70 | return getRomDirective(Size); | 
|  | 71 | return NULL; | 
| Sanjiv Gupta | 3b020fe | 2009-02-02 16:53:06 +0000 | [diff] [blame] | 72 | } | 
| Sanjiv Gupta | c8d7bc8 | 2009-01-30 04:25:10 +0000 | [diff] [blame] | 73 |  | 
| Sanjiv Gupta | d8d27f4 | 2009-05-06 08:02:01 +0000 | [diff] [blame] | 74 | const Section * | 
|  | 75 | PIC16TargetAsmInfo::getBSSSectionForGlobal(const GlobalVariable *GV) const { | 
|  | 76 | assert (GV->hasInitializer() && "This global doesn't need space"); | 
|  | 77 | Constant *C = GV->getInitializer(); | 
|  | 78 | assert (C->isNullValue() && "Unitialized globals has non-zero initializer"); | 
|  | 79 |  | 
|  | 80 | // Find how much space this global needs. | 
|  | 81 | const TargetData *TD = TM.getTargetData(); | 
|  | 82 | const Type *Ty = C->getType(); | 
| Duncan Sands | 777d230 | 2009-05-09 07:06:46 +0000 | [diff] [blame] | 83 | unsigned ValSize = TD->getTypeAllocSize(Ty); | 
| Sanjiv Gupta | d8d27f4 | 2009-05-06 08:02:01 +0000 | [diff] [blame] | 84 |  | 
|  | 85 | // Go through all BSS Sections and assign this variable | 
|  | 86 | // to the first available section having enough space. | 
|  | 87 | PIC16Section *FoundBSS = NULL; | 
|  | 88 | for (unsigned i = 0; i < BSSSections.size(); i++) { | 
|  | 89 | if (DataBankSize - BSSSections[i]->Size >= ValSize) { | 
|  | 90 | FoundBSS = BSSSections[i]; | 
|  | 91 | break; | 
|  | 92 | } | 
|  | 93 | } | 
|  | 94 |  | 
|  | 95 | // No BSS section spacious enough was found. Crate a new one. | 
|  | 96 | if (! FoundBSS) { | 
| Sanjiv Gupta | 211f362 | 2009-05-10 05:23:47 +0000 | [diff] [blame] | 97 | std::string name = PAN::getUdataSectionName(BSSSections.size()); | 
|  | 98 | const Section *NewSection = getNamedSection (name.c_str()); | 
| Sanjiv Gupta | d8d27f4 | 2009-05-06 08:02:01 +0000 | [diff] [blame] | 99 |  | 
|  | 100 | FoundBSS = new PIC16Section(NewSection); | 
|  | 101 |  | 
|  | 102 | // Add this newly created BSS section to the list of BSSSections. | 
|  | 103 | BSSSections.push_back(FoundBSS); | 
|  | 104 | } | 
|  | 105 |  | 
|  | 106 | // Insert the GV into this BSS. | 
|  | 107 | FoundBSS->Items.push_back(GV); | 
|  | 108 | FoundBSS->Size += ValSize; | 
|  | 109 |  | 
|  | 110 | // We can't do this here because GV is const . | 
|  | 111 | // const std::string SName = FoundBSS->S_->getName(); | 
|  | 112 | // GV->setSection(SName); | 
|  | 113 |  | 
|  | 114 | return FoundBSS->S_; | 
|  | 115 | } | 
|  | 116 |  | 
|  | 117 | const Section * | 
|  | 118 | PIC16TargetAsmInfo::getIDATASectionForGlobal(const GlobalVariable *GV) const { | 
|  | 119 | assert (GV->hasInitializer() && "This global doesn't need space"); | 
|  | 120 | Constant *C = GV->getInitializer(); | 
|  | 121 | assert (!C->isNullValue() && "initialized globals has zero initializer"); | 
|  | 122 | assert (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE && | 
|  | 123 | "can split initialized RAM data only"); | 
|  | 124 |  | 
|  | 125 | // Find how much space this global needs. | 
|  | 126 | const TargetData *TD = TM.getTargetData(); | 
|  | 127 | const Type *Ty = C->getType(); | 
| Duncan Sands | 777d230 | 2009-05-09 07:06:46 +0000 | [diff] [blame] | 128 | unsigned ValSize = TD->getTypeAllocSize(Ty); | 
| Sanjiv Gupta | d8d27f4 | 2009-05-06 08:02:01 +0000 | [diff] [blame] | 129 |  | 
|  | 130 | // Go through all IDATA Sections and assign this variable | 
|  | 131 | // to the first available section having enough space. | 
|  | 132 | PIC16Section *FoundIDATA = NULL; | 
|  | 133 | for (unsigned i = 0; i < IDATASections.size(); i++) { | 
|  | 134 | if ( DataBankSize - IDATASections[i]->Size >= ValSize) { | 
|  | 135 | FoundIDATA = IDATASections[i]; | 
|  | 136 | break; | 
|  | 137 | } | 
|  | 138 | } | 
|  | 139 |  | 
|  | 140 | // No IDATA section spacious enough was found. Crate a new one. | 
|  | 141 | if (! FoundIDATA) { | 
| Sanjiv Gupta | 211f362 | 2009-05-10 05:23:47 +0000 | [diff] [blame] | 142 | std::string name = PAN::getIdataSectionName(IDATASections.size()); | 
|  | 143 | const Section *NewSection = getNamedSection (name.c_str()); | 
| Sanjiv Gupta | d8d27f4 | 2009-05-06 08:02:01 +0000 | [diff] [blame] | 144 |  | 
|  | 145 | FoundIDATA = new PIC16Section(NewSection); | 
|  | 146 |  | 
|  | 147 | // Add this newly created IDATA section to the list of IDATASections. | 
|  | 148 | IDATASections.push_back(FoundIDATA); | 
|  | 149 | } | 
|  | 150 |  | 
|  | 151 | // Insert the GV into this IDATA. | 
|  | 152 | FoundIDATA->Items.push_back(GV); | 
|  | 153 | FoundIDATA->Size += ValSize; | 
|  | 154 |  | 
|  | 155 | // We can't do this here because GV is const . | 
|  | 156 | // GV->setSection(FoundIDATA->S->getName()); | 
|  | 157 |  | 
|  | 158 | return FoundIDATA->S_; | 
|  | 159 | } | 
|  | 160 |  | 
| Sanjiv Gupta | 2364cfe | 2009-05-12 17:07:27 +0000 | [diff] [blame] | 161 | // Get the section for an automatic variable of a function. | 
|  | 162 | // For PIC16 they are globals only with mangled names. | 
|  | 163 | const Section * | 
|  | 164 | PIC16TargetAsmInfo::getSectionForAuto(const GlobalVariable *GV) const { | 
|  | 165 |  | 
|  | 166 | const std::string name = PAN::getSectionNameForSym(GV->getName()); | 
|  | 167 |  | 
|  | 168 | // Go through all Auto Sections and assign this variable | 
|  | 169 | // to the appropriate section. | 
|  | 170 | PIC16Section *FoundAutoSec = NULL; | 
|  | 171 | for (unsigned i = 0; i < AutosSections.size(); i++) { | 
|  | 172 | if ( AutosSections[i]->S_->getName() == name) { | 
|  | 173 | FoundAutoSec = AutosSections[i]; | 
|  | 174 | break; | 
|  | 175 | } | 
|  | 176 | } | 
|  | 177 |  | 
|  | 178 | // No Auto section was found. Crate a new one. | 
|  | 179 | if (! FoundAutoSec) { | 
|  | 180 | const Section *NewSection = getNamedSection (name.c_str()); | 
|  | 181 |  | 
|  | 182 | FoundAutoSec = new PIC16Section(NewSection); | 
|  | 183 |  | 
|  | 184 | // Add this newly created autos section to the list of AutosSections. | 
|  | 185 | AutosSections.push_back(FoundAutoSec); | 
|  | 186 | } | 
|  | 187 |  | 
|  | 188 | // Insert the auto into this section. | 
|  | 189 | FoundAutoSec->Items.push_back(GV); | 
|  | 190 |  | 
|  | 191 | return FoundAutoSec->S_; | 
|  | 192 | } | 
|  | 193 |  | 
|  | 194 |  | 
| Sanjiv Gupta | d8d27f4 | 2009-05-06 08:02:01 +0000 | [diff] [blame] | 195 | // Override default implementation to put the true globals into | 
|  | 196 | // multiple data sections if required. | 
|  | 197 | const Section* | 
|  | 198 | PIC16TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV1) const { | 
|  | 199 | // We select the section based on the initializer here, so it really | 
|  | 200 | // has to be a GlobalVariable. | 
| Sanjiv Gupta | 211f362 | 2009-05-10 05:23:47 +0000 | [diff] [blame] | 201 | const GlobalVariable *GV = dyn_cast<GlobalVariable>(GV1); | 
| Sanjiv Gupta | ad6585b | 2009-05-13 15:13:17 +0000 | [diff] [blame] | 202 |  | 
|  | 203 | if (!GV) | 
| Sanjiv Gupta | d8d27f4 | 2009-05-06 08:02:01 +0000 | [diff] [blame] | 204 | return TargetAsmInfo::SelectSectionForGlobal(GV1); | 
|  | 205 |  | 
| Sanjiv Gupta | ad6585b | 2009-05-13 15:13:17 +0000 | [diff] [blame] | 206 | // Record Exteranl Var Decls. | 
|  | 207 | if (GV->isDeclaration()) { | 
|  | 208 | ExternalVarDecls->Items.push_back(GV); | 
|  | 209 | return ExternalVarDecls->S_; | 
|  | 210 | } | 
|  | 211 |  | 
|  | 212 | assert (GV->hasInitializer() && "A def without initializer?"); | 
|  | 213 |  | 
| Sanjiv Gupta | 211f362 | 2009-05-10 05:23:47 +0000 | [diff] [blame] | 214 | // First, if this is an automatic variable for a function, get the section | 
|  | 215 | // name for it and return. | 
|  | 216 | const std::string name = GV->getName(); | 
|  | 217 | if (PAN::isLocalName(name)) { | 
| Sanjiv Gupta | 2364cfe | 2009-05-12 17:07:27 +0000 | [diff] [blame] | 218 | return getSectionForAuto(GV); | 
| Sanjiv Gupta | 211f362 | 2009-05-10 05:23:47 +0000 | [diff] [blame] | 219 | } | 
| Sanjiv Gupta | d8d27f4 | 2009-05-06 08:02:01 +0000 | [diff] [blame] | 220 |  | 
| Sanjiv Gupta | ad6585b | 2009-05-13 15:13:17 +0000 | [diff] [blame] | 221 | // Record Exteranl Var Defs. | 
|  | 222 | if (GV->hasExternalLinkage() || GV->hasCommonLinkage()) { | 
|  | 223 | ExternalVarDefs->Items.push_back(GV); | 
|  | 224 | } | 
|  | 225 |  | 
| Sanjiv Gupta | d8d27f4 | 2009-05-06 08:02:01 +0000 | [diff] [blame] | 226 | // See if this is an uninitialized global. | 
| Sanjiv Gupta | 211f362 | 2009-05-10 05:23:47 +0000 | [diff] [blame] | 227 | const Constant *C = GV->getInitializer(); | 
| Sanjiv Gupta | d8d27f4 | 2009-05-06 08:02:01 +0000 | [diff] [blame] | 228 | if (C->isNullValue()) | 
|  | 229 | return getBSSSectionForGlobal(GV); | 
|  | 230 |  | 
| Sanjiv Gupta | 2364cfe | 2009-05-12 17:07:27 +0000 | [diff] [blame] | 231 | // If this is initialized data in RAM. Put it in the correct IDATA section. | 
| Sanjiv Gupta | d8d27f4 | 2009-05-06 08:02:01 +0000 | [diff] [blame] | 232 | if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) | 
|  | 233 | return getIDATASectionForGlobal(GV); | 
|  | 234 |  | 
| Sanjiv Gupta | 2364cfe | 2009-05-12 17:07:27 +0000 | [diff] [blame] | 235 | // This is initialized data in rom, put it in the readonly section. | 
| Sanjiv Gupta | 505996f | 2009-07-06 10:18:37 +0000 | [diff] [blame] | 236 | if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) | 
|  | 237 | return getROSectionForGlobal(GV); | 
| Sanjiv Gupta | 2364cfe | 2009-05-12 17:07:27 +0000 | [diff] [blame] | 238 |  | 
| Sanjiv Gupta | d8d27f4 | 2009-05-06 08:02:01 +0000 | [diff] [blame] | 239 | // Else let the default implementation take care of it. | 
|  | 240 | return TargetAsmInfo::SelectSectionForGlobal(GV); | 
|  | 241 | } | 
|  | 242 |  | 
| Sanjiv Gupta | d8d27f4 | 2009-05-06 08:02:01 +0000 | [diff] [blame] | 243 | PIC16TargetAsmInfo::~PIC16TargetAsmInfo() { | 
|  | 244 |  | 
|  | 245 | for (unsigned i = 0; i < BSSSections.size(); i++) { | 
|  | 246 | delete BSSSections[i]; | 
|  | 247 | } | 
|  | 248 |  | 
|  | 249 | for (unsigned i = 0; i < IDATASections.size(); i++) { | 
|  | 250 | delete IDATASections[i]; | 
|  | 251 | } | 
| Sanjiv Gupta | 2364cfe | 2009-05-12 17:07:27 +0000 | [diff] [blame] | 252 |  | 
|  | 253 | for (unsigned i = 0; i < AutosSections.size(); i++) { | 
|  | 254 | delete AutosSections[i]; | 
|  | 255 | } | 
|  | 256 |  | 
| Sanjiv Gupta | 505996f | 2009-07-06 10:18:37 +0000 | [diff] [blame] | 257 | for (unsigned i = 0; i < ROSections.size(); i++) { | 
|  | 258 | delete ROSections[i]; | 
|  | 259 | } | 
|  | 260 |  | 
| Sanjiv Gupta | ad6585b | 2009-05-13 15:13:17 +0000 | [diff] [blame] | 261 | delete ExternalVarDecls; | 
|  | 262 | delete ExternalVarDefs; | 
| Sanjiv Gupta | d8d27f4 | 2009-05-06 08:02:01 +0000 | [diff] [blame] | 263 | } | 
| Sanjiv Gupta | 505996f | 2009-07-06 10:18:37 +0000 | [diff] [blame] | 264 |  | 
|  | 265 | // Override the default implementation. Create PIC16sections for variables | 
|  | 266 | // which have a section name or address. | 
|  | 267 | const Section* | 
|  | 268 | PIC16TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const { | 
|  | 269 | const Section* S; | 
|  | 270 | // If GV has a sectin name or section address create that section now. | 
|  | 271 | if (GV->hasSection()) { | 
|  | 272 | std::string SectName = GV->getSection(); | 
|  | 273 | // If address for a variable is specified, get the address and create | 
|  | 274 | // section. | 
|  | 275 | std::string AddrStr = "Address="; | 
|  | 276 | if (SectName.compare(0, AddrStr.length(), AddrStr) == 0) { | 
|  | 277 | std::string SectAddr = SectName.substr(AddrStr.length()); | 
|  | 278 | S = CreateSectionForGlobal(GV, SectAddr); | 
|  | 279 | } | 
|  | 280 | else { | 
|  | 281 | S = CreateSectionForGlobal(GV); | 
|  | 282 | } | 
|  | 283 | } else { | 
|  | 284 | // Use section depending on the 'type' of variable | 
|  | 285 | S = SelectSectionForGlobal(GV); | 
|  | 286 | } | 
|  | 287 | return S; | 
|  | 288 | } | 
|  | 289 |  | 
|  | 290 | // Create a new section for global variable. If Addr is given then create | 
|  | 291 | // section at that address else create by name. | 
|  | 292 | const Section * | 
|  | 293 | PIC16TargetAsmInfo::CreateSectionForGlobal(const GlobalValue *GV1, | 
|  | 294 | std::string Addr) const { | 
|  | 295 | const GlobalVariable *GV = dyn_cast<GlobalVariable>(GV1); | 
|  | 296 |  | 
|  | 297 | if (!GV) | 
|  | 298 | return TargetAsmInfo::SectionForGlobal(GV1); | 
|  | 299 |  | 
|  | 300 | // See if this is an uninitialized global. | 
|  | 301 | const Constant *C = GV->getInitializer(); | 
|  | 302 | if (C->isNullValue()) | 
|  | 303 | return CreateBSSSectionForGlobal(GV, Addr); | 
|  | 304 |  | 
|  | 305 | // If this is initialized data in RAM. Put it in the correct IDATA section. | 
|  | 306 | if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) | 
|  | 307 | return CreateIDATASectionForGlobal(GV, Addr); | 
|  | 308 |  | 
|  | 309 | // This is initialized data in rom, put it in the readonly section. | 
|  | 310 | if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) | 
|  | 311 | return CreateROSectionForGlobal(GV, Addr); | 
|  | 312 |  | 
|  | 313 | // Else let the default implementation take care of it. | 
|  | 314 | return TargetAsmInfo::SectionForGlobal(GV); | 
|  | 315 | } | 
|  | 316 |  | 
|  | 317 | // Create uninitialized section for a variable. | 
|  | 318 | const Section * | 
|  | 319 | PIC16TargetAsmInfo::CreateBSSSectionForGlobal(const GlobalVariable *GV, | 
|  | 320 | std::string Addr) const { | 
|  | 321 | assert (GV->hasInitializer() && "This global doesn't need space"); | 
| Duncan Sands | 3ae2da6 | 2009-07-10 20:10:14 +0000 | [diff] [blame] | 322 | assert (GV->getInitializer()->isNullValue() && | 
|  | 323 | "Unitialized global has non-zero initializer"); | 
| Sanjiv Gupta | 505996f | 2009-07-06 10:18:37 +0000 | [diff] [blame] | 324 | std::string Name; | 
|  | 325 | // If address is given then create a section at that address else create a | 
|  | 326 | // section by section name specified in GV. | 
|  | 327 | PIC16Section *FoundBSS = NULL; | 
|  | 328 | if (Addr.empty()) { | 
|  | 329 | Name = GV->getSection() + " UDATA"; | 
|  | 330 | for (unsigned i = 0; i < BSSSections.size(); i++) { | 
|  | 331 | if (BSSSections[i]->S_->getName() == Name) { | 
|  | 332 | FoundBSS = BSSSections[i]; | 
|  | 333 | break; | 
|  | 334 | } | 
|  | 335 | } | 
|  | 336 | } | 
|  | 337 | else { | 
|  | 338 | std::string Prefix = GV->getName() + "." + Addr + "."; | 
|  | 339 | Name = PAN::getUdataSectionName(BSSSections.size(), Prefix) + " " + Addr; | 
|  | 340 | } | 
|  | 341 |  | 
|  | 342 | PIC16Section *NewBSS = FoundBSS; | 
|  | 343 | if (NewBSS == NULL) { | 
|  | 344 | const Section *NewSection = getNamedSection (Name.c_str()); | 
|  | 345 | NewBSS = new PIC16Section(NewSection); | 
|  | 346 | BSSSections.push_back(NewBSS); | 
|  | 347 | } | 
|  | 348 |  | 
|  | 349 | // Insert the GV into this BSS. | 
|  | 350 | NewBSS->Items.push_back(GV); | 
|  | 351 |  | 
|  | 352 | // We do not want to put any  GV without explicit section into this section | 
|  | 353 | // so set its size to DatabankSize. | 
|  | 354 | NewBSS->Size = DataBankSize; | 
|  | 355 | return NewBSS->S_; | 
|  | 356 | } | 
|  | 357 |  | 
|  | 358 | // Get rom section for a variable. Currently there can be only one rom section | 
|  | 359 | // unless a variable explicitly requests a section. | 
|  | 360 | const Section * | 
|  | 361 | PIC16TargetAsmInfo::getROSectionForGlobal(const GlobalVariable *GV) const { | 
|  | 362 | ROSections[0]->Items.push_back(GV); | 
|  | 363 | return ROSections[0]->S_; | 
|  | 364 | } | 
|  | 365 |  | 
|  | 366 | // Create initialized data section for a variable. | 
|  | 367 | const Section * | 
|  | 368 | PIC16TargetAsmInfo::CreateIDATASectionForGlobal(const GlobalVariable *GV, | 
|  | 369 | std::string Addr) const { | 
|  | 370 | assert (GV->hasInitializer() && "This global doesn't need space"); | 
| Duncan Sands | 3ae2da6 | 2009-07-10 20:10:14 +0000 | [diff] [blame] | 371 | assert (!GV->getInitializer()->isNullValue() && | 
|  | 372 | "initialized global has zero initializer"); | 
| Sanjiv Gupta | 505996f | 2009-07-06 10:18:37 +0000 | [diff] [blame] | 373 | assert (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE && | 
|  | 374 | "can be used for initialized RAM data only"); | 
|  | 375 |  | 
|  | 376 | std::string Name; | 
|  | 377 | // If address is given then create a section at that address else create a | 
|  | 378 | // section by section name specified in GV. | 
|  | 379 | PIC16Section *FoundIDATASec = NULL; | 
|  | 380 | if (Addr.empty()) { | 
|  | 381 | Name = GV->getSection() + " IDATA"; | 
|  | 382 | for (unsigned i = 0; i < IDATASections.size(); i++) { | 
|  | 383 | if (IDATASections[i]->S_->getName() == Name) { | 
|  | 384 | FoundIDATASec = IDATASections[i]; | 
|  | 385 | break; | 
|  | 386 | } | 
|  | 387 | } | 
|  | 388 | } | 
|  | 389 | else { | 
|  | 390 | std::string Prefix = GV->getName() + "." + Addr + "."; | 
|  | 391 | Name = PAN::getIdataSectionName(IDATASections.size(), Prefix) + " " + Addr; | 
|  | 392 | } | 
|  | 393 |  | 
|  | 394 | PIC16Section *NewIDATASec = FoundIDATASec; | 
|  | 395 | if (NewIDATASec == NULL) { | 
|  | 396 | const Section *NewSection = getNamedSection (Name.c_str()); | 
|  | 397 | NewIDATASec = new PIC16Section(NewSection); | 
|  | 398 | IDATASections.push_back(NewIDATASec); | 
|  | 399 | } | 
|  | 400 | // Insert the GV into this IDATA Section. | 
|  | 401 | NewIDATASec->Items.push_back(GV); | 
|  | 402 | // We do not want to put any  GV without explicit section into this section | 
|  | 403 | // so set its size to DatabankSize. | 
|  | 404 | NewIDATASec->Size = DataBankSize; | 
|  | 405 | return NewIDATASec->S_; | 
|  | 406 | } | 
|  | 407 |  | 
|  | 408 | // Create a section in rom for a variable. | 
|  | 409 | const Section * | 
|  | 410 | PIC16TargetAsmInfo::CreateROSectionForGlobal(const GlobalVariable *GV, | 
|  | 411 | std::string Addr) const { | 
|  | 412 | assert (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE && | 
|  | 413 | "can be used for ROM data only"); | 
|  | 414 |  | 
|  | 415 | std::string Name; | 
|  | 416 | // If address is given then create a section at that address else create a | 
|  | 417 | // section by section name specified in GV. | 
|  | 418 | PIC16Section *FoundROSec = NULL; | 
|  | 419 | if (Addr.empty()) { | 
|  | 420 | Name = GV->getSection() + " ROMDATA"; | 
|  | 421 | for (unsigned i = 1; i < ROSections.size(); i++) { | 
|  | 422 | if (ROSections[i]->S_->getName() == Name) { | 
|  | 423 | FoundROSec = ROSections[i]; | 
|  | 424 | break; | 
|  | 425 | } | 
|  | 426 | } | 
|  | 427 | } | 
|  | 428 | else { | 
|  | 429 | std::string Prefix = GV->getName() + "." + Addr + "."; | 
|  | 430 | Name = PAN::getRomdataSectionName(ROSections.size(), Prefix) + " " + Addr; | 
|  | 431 | } | 
|  | 432 |  | 
|  | 433 | PIC16Section *NewRomSec = FoundROSec; | 
|  | 434 | if (NewRomSec == NULL) { | 
|  | 435 | const Section *NewSection = getNamedSection (Name.c_str()); | 
|  | 436 | NewRomSec = new PIC16Section(NewSection); | 
|  | 437 | ROSections.push_back(NewRomSec); | 
|  | 438 | } | 
|  | 439 |  | 
|  | 440 | // Insert the GV into this ROM Section. | 
|  | 441 | NewRomSec->Items.push_back(GV); | 
|  | 442 | return NewRomSec->S_; | 
|  | 443 | } | 
|  | 444 |  |