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),
CommentString("#"),
GlobalPrefix(""),
PrivateGlobalPrefix("."),
+ LessPrivateGlobalPrefix(""),
JumpTableSpecialLabelPrefix(0),
GlobalVarAddrPrefix(""),
GlobalVarAddrSuffix(""),
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),
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() {
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!");
}
// 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 ||
return Flags;
}
-std::string
+const Section*
TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
const Section* S;
// Select section name
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.
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
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:
}
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;
}
}
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;
+}