Get rid of ReadOnlySection duplicate
[oota-llvm.git] / lib / Target / TargetAsmInfo.cpp
index 237b96de1ad4b77661f119018cfafd960e69eed4..1c883ada90ca055559e5a66a29d659089eb8c842 100644 (file)
 using namespace llvm;
 
 TargetAsmInfo::TargetAsmInfo() :
-  TextSection("\t.text"),
-  TextSection_(0),
-  DataSection("\t.data"),
-  DataSection_(0),
+  TextSection(0),
+  DataSection(0),
   BSSSection("\t.bss"),
   BSSSection_(0),
   ReadOnlySection(0),
-  ReadOnlySection_(0),
-  TLSDataSection("\t.section .tdata,\"awT\",@progbits"),
-  TLSDataSection_(0),
-  TLSBSSSection("\t.section .tbss,\"awT\",@nobits"),
-  TLSBSSSection_(0),
+  SmallDataSection(0),
+  SmallBSSSection(0),
+  SmallRODataSection(0),
+  TLSDataSection(0),
+  TLSBSSSection(0),
   ZeroFillDirective(0),
   NonexecutableStackDirective(0),
   NeedsSet(false),
@@ -47,6 +45,7 @@ TargetAsmInfo::TargetAsmInfo() :
   CommentString("#"),
   GlobalPrefix(""),
   PrivateGlobalPrefix("."),
+  LessPrivateGlobalPrefix(""),
   JumpTableSpecialLabelPrefix(0),
   GlobalVarAddrPrefix(""),
   GlobalVarAddrSuffix(""),
@@ -81,12 +80,6 @@ TargetAsmInfo::TargetAsmInfo() :
   CStringSection_(0),
   StaticCtorsSection("\t.section .ctors,\"aw\",@progbits"),
   StaticDtorsSection("\t.section .dtors,\"aw\",@progbits"),
-  FourByteConstantSection(0),
-  FourByteConstantSection_(0),
-  EightByteConstantSection(0),
-  EightByteConstantSection_(0),
-  SixteenByteConstantSection(0),
-  SixteenByteConstantSection_(0),
   GlobalDirective("\t.globl\t"),
   SetDirective(0),
   LCOMMDirective(0),
@@ -122,8 +115,8 @@ TargetAsmInfo::TargetAsmInfo() :
   DwarfEHFrameSection(".eh_frame"),
   DwarfExceptionSection(".gcc_except_table"),
   AsmTransCBE(0) {
-  TextSection_ = getUnnamedSection(TextSection);
-  DataSection_ = getUnnamedSection(DataSection);
+  TextSection = getUnnamedSection("\t.text", SectionFlags::Code);
+  DataSection = getUnnamedSection("\t.data", SectionFlags::Writeable);
 }
 
 TargetAsmInfo::~TargetAsmInfo() {
@@ -228,6 +221,13 @@ TargetAsmInfo::SectionFlagsForGlobal(const GlobalValue *GV,
      case SectionKind::RODataMergeConst:
       // No additional flags here
       break;
+     case SectionKind::SmallData:
+     case SectionKind::SmallBSS:
+      Flags |= SectionFlags::Writeable;
+      // FALLS THROUGH
+     case SectionKind::SmallROData:
+      Flags |= SectionFlags::Small;
+      break;
      default:
       assert(0 && "Unexpected section kind!");
     }
@@ -242,7 +242,9 @@ TargetAsmInfo::SectionFlagsForGlobal(const GlobalValue *GV,
 
     // Some lame default implementation based on some magic section names.
     if (strncmp(Name, ".gnu.linkonce.b.", 16) == 0 ||
-        strncmp(Name, ".llvm.linkonce.b.", 17) == 0)
+        strncmp(Name, ".llvm.linkonce.b.", 17) == 0 ||
+        strncmp(Name, ".gnu.linkonce.sb.", 17) == 0 ||
+        strncmp(Name, ".llvm.linkonce.sb.", 18) == 0)
       Flags |= SectionFlags::BSS;
     else if (strcmp(Name, ".tdata") == 0 ||
              strncmp(Name, ".tdata.", 7) == 0 ||
@@ -259,7 +261,7 @@ TargetAsmInfo::SectionFlagsForGlobal(const GlobalValue *GV,
   return Flags;
 }
 
-std::string
+const Section*
 TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
   const Section* S;
   // Select section name
@@ -273,15 +275,7 @@ TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
     S = SelectSectionForGlobal(GV);
   }
 
-  std::string Name = S->Name;
-
-  // If section is named we need to switch into it via special '.section'
-  // directive and also append funky flags. Otherwise - section name is just
-  // some magic assembler directive.
-  if (S->isNamed())
-    Name = getSwitchToSectionDirective() + Name + PrintSectionFlags(S->Flags);
-
-  return Name;
+  return S;
 }
 
 // Lame default implementation. Calculate the section name for global.
@@ -295,17 +289,21 @@ TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
     return getNamedSection(Name.c_str(), Flags);
   } else {
     if (Kind == SectionKind::Text)
-      return getTextSection_();
-    else if (Kind == SectionKind::BSS && getBSSSection_())
+      return getTextSection();
+    else if (isBSS(Kind) && getBSSSection_())
       return getBSSSection_();
-    else if (getReadOnlySection_() &&
-             (Kind == SectionKind::ROData ||
-              Kind == SectionKind::RODataMergeConst ||
-              Kind == SectionKind::RODataMergeStr))
-      return getReadOnlySection_();
+    else if (getReadOnlySection() && SectionKind::isReadOnly(Kind))
+      return getReadOnlySection();
   }
 
-  return getDataSection_();
+  return getDataSection();
+}
+
+// Lame default implementation. Calculate the section name for machine const.
+const Section*
+TargetAsmInfo::SelectSectionForMachineConst(const Type *Ty) const {
+  // FIXME: Support data.rel stuff someday
+  return getDataSection();
 }
 
 std::string
@@ -316,12 +314,18 @@ TargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV,
     return ".gnu.linkonce.t." + GV->getName();
    case SectionKind::Data:
     return ".gnu.linkonce.d." + GV->getName();
+   case SectionKind::SmallData:
+    return ".gnu.linkonce.s." + GV->getName();
    case SectionKind::BSS:
     return ".gnu.linkonce.b." + GV->getName();
+   case SectionKind::SmallBSS:
+    return ".gnu.linkonce.sb." + GV->getName();
    case SectionKind::ROData:
    case SectionKind::RODataMergeConst:
    case SectionKind::RODataMergeStr:
     return ".gnu.linkonce.r." + GV->getName();
+   case SectionKind::SmallROData:
+    return ".gnu.linkonce.s2." + GV->getName();
    case SectionKind::ThreadData:
     return ".gnu.linkonce.td." + GV->getName();
    case SectionKind::ThreadBSS:
@@ -332,11 +336,12 @@ TargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV,
 }
 
 const Section*
-TargetAsmInfo::getNamedSection(const char *Name, unsigned Flags) const {
+TargetAsmInfo::getNamedSection(const char *Name, unsigned Flags,
+                               bool Override) const {
   Section& S = Sections[Name];
 
   // This is newly-created section, set it up properly.
-  if (S.Flags == SectionFlags::Invalid) {
+  if (S.Flags == SectionFlags::Invalid || Override) {
     S.Flags = Flags | SectionFlags::Named;
     S.Name = Name;
   }
@@ -345,14 +350,51 @@ TargetAsmInfo::getNamedSection(const char *Name, unsigned Flags) const {
 }
 
 const Section*
-TargetAsmInfo::getUnnamedSection(const char *Directive, unsigned Flags) const {
+TargetAsmInfo::getUnnamedSection(const char *Directive, unsigned Flags,
+                                 bool Override) const {
   Section& S = Sections[Directive];
 
   // This is newly-created section, set it up properly.
-  if (S.Flags == SectionFlags::Invalid) {
+  if (S.Flags == SectionFlags::Invalid || Override) {
     S.Flags = Flags & ~SectionFlags::Named;
     S.Name = Directive;
   }
 
   return &S;
 }
+
+const std::string&
+TargetAsmInfo::getSectionFlags(unsigned Flags) const {
+  SectionFlags::FlagsStringsMapType::iterator I = FlagsStrings.find(Flags);
+
+  // We didn't print these flags yet, print and save them to map. This reduces
+  // amount of heap trashing due to std::string construction / concatenation.
+  if (I == FlagsStrings.end())
+    I = FlagsStrings.insert(std::make_pair(Flags,
+                                           printSectionFlags(Flags))).first;
+
+  return I->second;
+}
+
+unsigned TargetAsmInfo::getULEB128Size(unsigned Value) {
+  unsigned Size = 0;
+  do {
+    Value >>= 7;
+    Size += sizeof(int8_t);
+  } while (Value);
+  return Size;
+}
+
+unsigned TargetAsmInfo::getSLEB128Size(int Value) {
+  unsigned Size = 0;
+  int Sign = Value >> (8 * sizeof(Value) - 1);
+  bool IsMore;
+
+  do {
+    unsigned Byte = Value & 0x7f;
+    Value >>= 7;
+    IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
+    Size += sizeof(int8_t);
+  } while (IsMore);
+  return Size;
+}