diff --git a/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.cpp b/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.cpp
index 5a4387a..9912543 100644
--- a/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.cpp
+++ b/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.cpp
@@ -31,36 +31,26 @@
   Data16bitsDirective = " dw ";
   Data32bitsDirective = " dl ";
   Data64bitsDirective = NULL;
-  RomData8bitsDirective = " dw ";
-  RomData16bitsDirective = " rom_di ";
-  RomData32bitsDirective = " rom_dl ";
   ZeroDirective = NULL;
   AsciiDirective = " dt ";
   AscizDirective = NULL;
-  BSSSection_  = getOrCreateSection("udata.# UDATA", false, SectionKind::BSS);
-  ReadOnlySection = getOrCreateSection("romdata.# ROMDATA", false,
-                                       SectionKind::ReadOnly);
-  DataSection = getOrCreateSection("idata.# IDATA", false,SectionKind::DataRel);
   SwitchToSectionDirective = "";
-  // Need because otherwise a .text symbol is emitted by DwarfWriter
-  // in BeginModule, and gpasm cribbs for that .text symbol.
-  TextSection = getOrCreateSection("", true, SectionKind::Text);
-  PIC16Section *ROSection = new PIC16Section(getReadOnlySection());
-  ROSections.push_back(ROSection);
     
-  // FIXME: I don't know what the classification of these sections really is.
-  ExternalVarDecls = new PIC16Section(getOrCreateSection("ExternalVarDecls",
-                                                         false,
-                                                         SectionKind::Metadata));
-  ExternalVarDefs = new PIC16Section(getOrCreateSection("ExternalVarDefs",
-                                                        false,
-                                                        SectionKind::Metadata));
+  RomData8bitsDirective = " dw ";
+  RomData16bitsDirective = " rom_di ";
+  RomData32bitsDirective = " rom_dl ";
+    
+    
   // Set it to false because we weed to generate c file name and not bc file
   // name.
   HasSingleParameterDotFile = false;
 }
 
-const char *PIC16TargetAsmInfo::getRomDirective(unsigned Size) const {
+const char *PIC16TargetAsmInfo::
+getDataASDirective(unsigned Size, unsigned AS) const {
+  if (AS != PIC16ISD::ROM_SPACE)
+    return 0;
+  
   switch (Size) {
   case  8: return RomData8bitsDirective;
   case 16: return RomData16bitsDirective;
@@ -69,369 +59,3 @@
   }
 }
 
-
-const char *PIC16TargetAsmInfo::
-getDataASDirective(unsigned Size, unsigned AS) const {
-  if (AS == PIC16ISD::ROM_SPACE)
-    return getRomDirective(Size);
-  return NULL;
-}
-
-const Section *
-PIC16TargetAsmInfo::getBSSSectionForGlobal(const GlobalVariable *GV) const {
-  assert(GV->hasInitializer() && "This global doesn't need space");
-  Constant *C = GV->getInitializer();
-  assert(C->isNullValue() && "Unitialized globals has non-zero initializer");
-
-  // Find how much space this global needs.
-  const TargetData *TD = TM.getTargetData();
-  const Type *Ty = C->getType(); 
-  unsigned ValSize = TD->getTypeAllocSize(Ty);
- 
-  // Go through all BSS Sections and assign this variable
-  // to the first available section having enough space.
-  PIC16Section *FoundBSS = NULL;
-  for (unsigned i = 0; i < BSSSections.size(); i++) {
-    if (DataBankSize - BSSSections[i]->Size >= ValSize) {
-      FoundBSS = BSSSections[i];
-      break;
-    }
-  }
-
-  // No BSS section spacious enough was found. Crate a new one.
-  if (!FoundBSS) {
-    std::string name = PAN::getUdataSectionName(BSSSections.size());
-    const Section *NewSection = getOrCreateSection(name.c_str(), false,
-                                                   // FIXME.
-                                                   SectionKind::Metadata);
-
-    FoundBSS = new PIC16Section(NewSection);
-
-    // Add this newly created BSS section to the list of BSSSections.
-    BSSSections.push_back(FoundBSS);
-  }
-  
-  // Insert the GV into this BSS.
-  FoundBSS->Items.push_back(GV);
-  FoundBSS->Size += ValSize;
-  return FoundBSS->S_;
-} 
-
-const Section *
-PIC16TargetAsmInfo::getIDATASectionForGlobal(const GlobalVariable *GV) const {
-  assert(GV->hasInitializer() && "This global doesn't need space");
-  Constant *C = GV->getInitializer();
-  assert(!C->isNullValue() && "initialized globals has zero initializer");
-  assert(GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
-         "can split initialized RAM data only");
-
-  // Find how much space this global needs.
-  const TargetData *TD = TM.getTargetData();
-  const Type *Ty = C->getType(); 
-  unsigned ValSize = TD->getTypeAllocSize(Ty);
- 
-  // Go through all IDATA Sections and assign this variable
-  // to the first available section having enough space.
-  PIC16Section *FoundIDATA = NULL;
-  for (unsigned i = 0; i < IDATASections.size(); i++) {
-    if (DataBankSize - IDATASections[i]->Size >= ValSize) {
-      FoundIDATA = IDATASections[i]; 
-      break;
-    }
-  }
-
-  // No IDATA section spacious enough was found. Crate a new one.
-  if (!FoundIDATA) {
-    std::string name = PAN::getIdataSectionName(IDATASections.size());
-    const Section *NewSection = getOrCreateSection(name.c_str(),
-                                                   false,
-                                                   // FIXME.
-                                                   SectionKind::Metadata);
-
-    FoundIDATA = new PIC16Section(NewSection);
-
-    // Add this newly created IDATA section to the list of IDATASections.
-    IDATASections.push_back(FoundIDATA);
-  }
-  
-  // Insert the GV into this IDATA.
-  FoundIDATA->Items.push_back(GV);
-  FoundIDATA->Size += ValSize;
-  return FoundIDATA->S_;
-} 
-
-// Get the section for an automatic variable of a function.
-// For PIC16 they are globals only with mangled names.
-const Section *
-PIC16TargetAsmInfo::getSectionForAuto(const GlobalVariable *GV) const {
-
-  const std::string name = PAN::getSectionNameForSym(GV->getName());
-
-  // Go through all Auto Sections and assign this variable
-  // to the appropriate section.
-  PIC16Section *FoundAutoSec = NULL;
-  for (unsigned i = 0; i < AutosSections.size(); i++) {
-    if (AutosSections[i]->S_->getName() == name) {
-      FoundAutoSec = AutosSections[i];
-      break;
-    }
-  }
-
-  // No Auto section was found. Crate a new one.
-  if (!FoundAutoSec) {
-    const Section *NewSection = getOrCreateSection(name.c_str(),
-                                                   // FIXME.
-                                                   false,
-                                                   SectionKind::Metadata);
-
-    FoundAutoSec = new PIC16Section(NewSection);
-
-    // Add this newly created autos section to the list of AutosSections.
-    AutosSections.push_back(FoundAutoSec);
-  }
-
-  // Insert the auto into this section.
-  FoundAutoSec->Items.push_back(GV);
-
-  return FoundAutoSec->S_;
-}
-
-
-// Override default implementation to put the true globals into
-// multiple data sections if required.
-const Section*
-PIC16TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV1,
-                                           SectionKind Kind) const {
-  // We select the section based on the initializer here, so it really
-  // has to be a GlobalVariable.
-  const GlobalVariable *GV = dyn_cast<GlobalVariable>(GV1); 
-  if (!GV)
-    return TargetAsmInfo::SelectSectionForGlobal(GV1, Kind);
-
-  // Record External Var Decls.
-  if (GV->isDeclaration()) {
-    ExternalVarDecls->Items.push_back(GV);
-    return ExternalVarDecls->S_;
-  }
-    
-  assert(GV->hasInitializer() && "A def without initializer?");
-
-  // First, if this is an automatic variable for a function, get the section
-  // name for it and return.
-  std::string name = GV->getName();
-  if (PAN::isLocalName(name))
-    return getSectionForAuto(GV);
-
-  // Record Exteranl Var Defs.
-  if (GV->hasExternalLinkage() || GV->hasCommonLinkage())
-    ExternalVarDefs->Items.push_back(GV);
-
-  // See if this is an uninitialized global.
-  const Constant *C = GV->getInitializer();
-  if (C->isNullValue()) 
-    return getBSSSectionForGlobal(GV); 
-
-  // If this is initialized data in RAM. Put it in the correct IDATA section.
-  if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) 
-    return getIDATASectionForGlobal(GV);
-
-  // This is initialized data in rom, put it in the readonly section.
-  if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) 
-    return getROSectionForGlobal(GV);
-
-  // Else let the default implementation take care of it.
-  return TargetAsmInfo::SelectSectionForGlobal(GV, Kind);
-}
-
-PIC16TargetAsmInfo::~PIC16TargetAsmInfo() {
-  for (unsigned i = 0; i < BSSSections.size(); i++)
-    delete BSSSections[i]; 
-  for (unsigned i = 0; i < IDATASections.size(); i++)
-    delete IDATASections[i]; 
-  for (unsigned i = 0; i < AutosSections.size(); i++)
-    delete AutosSections[i]; 
-  for (unsigned i = 0; i < ROSections.size(); i++)
-    delete ROSections[i];
-  delete ExternalVarDecls;
-  delete ExternalVarDefs;
-}
-
-
-/// getSpecialCasedSectionGlobals - Allow the target to completely override
-/// section assignment of a global.
-const Section *
-PIC16TargetAsmInfo::getSpecialCasedSectionGlobals(const GlobalValue *GV,
-                                                  SectionKind Kind) const {
-  // If GV has a sectin name or section address create that section now.
-  if (GV->hasSection()) {
-    if (const GlobalVariable *GVar = cast<GlobalVariable>(GV)) {
-      std::string SectName = GVar->getSection();
-      // If address for a variable is specified, get the address and create
-      // section.
-      std::string AddrStr = "Address=";
-      if (SectName.compare(0, AddrStr.length(), AddrStr) == 0) {
-        std::string SectAddr = SectName.substr(AddrStr.length());
-        return CreateSectionForGlobal(GVar, SectAddr);
-      }
-       
-      // Create the section specified with section attribute. 
-      return CreateSectionForGlobal(GVar);
-    }
-  }
-
-  return 0;
-}
-
-// Create a new section for global variable. If Addr is given then create
-// section at that address else create by name.
-const Section *
-PIC16TargetAsmInfo::CreateSectionForGlobal(const GlobalVariable *GV,
-                                           const std::string &Addr) const {
-  // See if this is an uninitialized global.
-  const Constant *C = GV->getInitializer();
-  if (C->isNullValue())
-    return CreateBSSSectionForGlobal(GV, Addr);
-
-  // If this is initialized data in RAM. Put it in the correct IDATA section.
-  if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE)
-    return CreateIDATASectionForGlobal(GV, Addr);
-
-  // This is initialized data in rom, put it in the readonly section.
-  if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) 
-    return CreateROSectionForGlobal(GV, Addr);
-
-  // Else let the default implementation take care of it.
-  return TargetAsmInfo::SectionForGlobal(GV);
-}
-
-// Create uninitialized section for a variable.
-const Section *
-PIC16TargetAsmInfo::CreateBSSSectionForGlobal(const GlobalVariable *GV,
-                                              std::string Addr) const {
-  assert(GV->hasInitializer() && "This global doesn't need space");
-  assert(GV->getInitializer()->isNullValue() &&
-         "Unitialized global has non-zero initializer");
-  std::string Name;
-  // If address is given then create a section at that address else create a
-  // section by section name specified in GV.
-  PIC16Section *FoundBSS = NULL;
-  if (Addr.empty()) { 
-    Name = GV->getSection() + " UDATA";
-    for (unsigned i = 0; i < BSSSections.size(); i++) {
-      if (BSSSections[i]->S_->getName() == Name) {
-        FoundBSS = BSSSections[i];
-        break;
-      }
-    }
-  } else {
-    std::string Prefix = GV->getNameStr() + "." + Addr + ".";
-    Name = PAN::getUdataSectionName(BSSSections.size(), Prefix) + " " + Addr;
-  }
-  
-  PIC16Section *NewBSS = FoundBSS;
-  if (NewBSS == NULL) {
-    const Section *NewSection = getOrCreateSection(Name.c_str(),
-                                                   false, SectionKind::BSS);
-    NewBSS = new PIC16Section(NewSection);
-    BSSSections.push_back(NewBSS);
-  }
-
-  // Insert the GV into this BSS.
-  NewBSS->Items.push_back(GV);
-
-  // We do not want to put any  GV without explicit section into this section
-  // so set its size to DatabankSize.
-  NewBSS->Size = DataBankSize;
-  return NewBSS->S_;
-}
-
-// Get rom section for a variable. Currently there can be only one rom section
-// unless a variable explicitly requests a section.
-const Section *
-PIC16TargetAsmInfo::getROSectionForGlobal(const GlobalVariable *GV) const {
-  ROSections[0]->Items.push_back(GV);
-  return ROSections[0]->S_;
-}
-
-// Create initialized data section for a variable.
-const Section *
-PIC16TargetAsmInfo::CreateIDATASectionForGlobal(const GlobalVariable *GV,
-                                                std::string Addr) const {
-  assert(GV->hasInitializer() && "This global doesn't need space");
-  assert(!GV->getInitializer()->isNullValue() &&
-         "initialized global has zero initializer");
-  assert(GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE &&
-         "can be used for initialized RAM data only");
-
-  std::string Name;
-  // If address is given then create a section at that address else create a
-  // section by section name specified in GV.
-  PIC16Section *FoundIDATASec = NULL;
-  if (Addr.empty()) {
-    Name = GV->getSection() + " IDATA";
-    for (unsigned i = 0; i < IDATASections.size(); i++) {
-      if (IDATASections[i]->S_->getName() == Name) {
-        FoundIDATASec = IDATASections[i];
-        break;
-      }
-    }
-  } else {
-    std::string Prefix = GV->getNameStr() + "." + Addr + ".";
-    Name = PAN::getIdataSectionName(IDATASections.size(), Prefix) + " " + Addr;
-  }
-
-  PIC16Section *NewIDATASec = FoundIDATASec;
-  if (NewIDATASec == NULL) {
-    const Section *NewSection = getOrCreateSection(Name.c_str(),
-                                                   false,
-                                                   // FIXME:
-                                                   SectionKind::Metadata);
-    NewIDATASec = new PIC16Section(NewSection);
-    IDATASections.push_back(NewIDATASec);
-  }
-  // Insert the GV into this IDATA Section.
-  NewIDATASec->Items.push_back(GV);
-  // We do not want to put any  GV without explicit section into this section 
-  // so set its size to DatabankSize.
-  NewIDATASec->Size = DataBankSize;
-  return NewIDATASec->S_;
-}
-
-// Create a section in rom for a variable.
-const Section *
-PIC16TargetAsmInfo::CreateROSectionForGlobal(const GlobalVariable *GV,
-                                             std::string Addr) const {
-  assert(GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE &&
-         "can be used for ROM data only");
-
-  std::string Name;
-  // If address is given then create a section at that address else create a
-  // section by section name specified in GV.
-  PIC16Section *FoundROSec = NULL;
-  if (Addr.empty()) {
-    Name = GV->getSection() + " ROMDATA";
-    for (unsigned i = 1; i < ROSections.size(); i++) {
-      if (ROSections[i]->S_->getName() == Name) {
-        FoundROSec = ROSections[i];
-        break;
-      }
-    }
-  } else {
-    std::string Prefix = GV->getNameStr() + "." + Addr + ".";
-    Name = PAN::getRomdataSectionName(ROSections.size(), Prefix) + " " + Addr;
-  }
-
-  PIC16Section *NewRomSec = FoundROSec;
-  if (NewRomSec == NULL) {
-    const Section *NewSection = getOrCreateSection(Name.c_str(),
-                                                   false,
-                                                   SectionKind::ReadOnly);
-    NewRomSec = new PIC16Section(NewSection);
-    ROSections.push_back(NewRomSec);
-  }
-
-  // Insert the GV into this ROM Section.
-  NewRomSec->Items.push_back(GV);
-  return NewRomSec->S_;
-}
-
