//===-- XCoreTargetAsmInfo.cpp - XCore asm properties -----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file contains the declarations of the XCoreTargetAsmInfo properties. // We use the small section flag for the CP relative and DP relative // flags. If a section is small and writable then it is DP relative. If a // section is small and not writable then it is CP relative. // //===----------------------------------------------------------------------===// #include "XCoreTargetAsmInfo.h" #include "XCoreTargetMachine.h" #include "llvm/GlobalVariable.h" #include "llvm/ADT/StringExtras.h" using namespace llvm; XCoreTargetAsmInfo::XCoreTargetAsmInfo(const XCoreTargetMachine &TM) : ELFTargetAsmInfo(TM), Subtarget(TM.getSubtargetImpl()) { TextSection = getUnnamedSection("\t.text", SectionFlags::Code); DataSection = getNamedSection("\t.dp.data", SectionFlags::Writeable | SectionFlags::Small); BSSSection_ = getNamedSection("\t.dp.bss", SectionFlags::Writeable | SectionFlags::BSS | SectionFlags::Small); if (Subtarget->isXS1A()) { ReadOnlySection = getNamedSection("\t.dp.rodata", SectionFlags::None | SectionFlags::Writeable | SectionFlags::Small); } else { ReadOnlySection = getNamedSection("\t.cp.rodata", SectionFlags::None | SectionFlags::Small); } Data16bitsDirective = "\t.short\t"; Data32bitsDirective = "\t.long\t"; Data64bitsDirective = 0; ZeroDirective = "\t.space\t"; CommentString = "#"; ConstantPoolSection = "\t.section\t.cp.rodata,\"ac\",@progbits"; JumpTableDataSection = "\t.section\t.dp.data,\"awd\",@progbits"; PrivateGlobalPrefix = ".L"; AscizDirective = ".asciiz"; WeakDefDirective = "\t.weak\t"; WeakRefDirective = "\t.weak\t"; SetDirective = "\t.set\t"; // Debug HasLEB128 = true; AbsoluteDebugSectionOffsets = true; DwarfAbbrevSection = "\t.section\t.debug_abbrev,\"\",@progbits"; DwarfInfoSection = "\t.section\t.debug_info,\"\",@progbits"; DwarfLineSection = "\t.section\t.debug_line,\"\",@progbits"; DwarfFrameSection = "\t.section\t.debug_frame,\"\",@progbits"; DwarfPubNamesSection = "\t.section\t.debug_pubnames,\"\",@progbits"; DwarfPubTypesSection = "\t.section\t.debug_pubtypes,\"\",@progbits"; DwarfStrSection = "\t.section\t.debug_str,\"\",@progbits"; DwarfLocSection = "\t.section\t.debug_loc,\"\",@progbits"; DwarfARangesSection = "\t.section\t.debug_aranges,\"\",@progbits"; DwarfRangesSection = "\t.section\t.debug_ranges,\"\",@progbits"; DwarfMacInfoSection = "\t.section\t.debug_macinfo,\"\",@progbits"; } const Section* XCoreTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { SectionKind::Kind Kind = SectionKindForGlobal(GV); if (const GlobalVariable *GVar = dyn_cast(GV)) { if (!GVar->isWeakForLinker()) { switch (Kind) { case SectionKind::RODataMergeStr: return MergeableStringSection(GVar); case SectionKind::RODataMergeConst: return getReadOnlySection(); case SectionKind::ThreadData: return DataSection; case SectionKind::ThreadBSS: return getBSSSection_(); default: break; } } } return ELFTargetAsmInfo::SelectSectionForGlobal(GV); } const Section* XCoreTargetAsmInfo::SelectSectionForMachineConst(const Type *Ty) const { return MergeableConstSection(Ty); } const Section* XCoreTargetAsmInfo::MergeableConstSection(const GlobalVariable *GV) const { Constant *C = GV->getInitializer(); return MergeableConstSection(C->getType()); } inline const Section* XCoreTargetAsmInfo::MergeableConstSection(const Type *Ty) const { const TargetData *TD = TM.getTargetData(); unsigned Size = TD->getTypeAllocSize(Ty); if (Size == 4 || Size == 8 || Size == 16) { std::string Name = ".cp.const" + utostr(Size); return getNamedSection(Name.c_str(), SectionFlags::setEntitySize(SectionFlags::Mergeable | SectionFlags::Small, Size)); } return getReadOnlySection(); } const Section* XCoreTargetAsmInfo:: MergeableStringSection(const GlobalVariable *GV) const { // FIXME insert in correct mergable section return getReadOnlySection(); } unsigned XCoreTargetAsmInfo:: SectionFlagsForGlobal(const GlobalValue *GV, const char* Name) const { unsigned Flags = ELFTargetAsmInfo::SectionFlagsForGlobal(GV, Name); // Mask out unsupported flags Flags &= ~(SectionFlags::Small | SectionFlags::TLS); // Set CP / DP relative flags if (GV) { SectionKind::Kind Kind = SectionKindForGlobal(GV); switch (Kind) { case SectionKind::ThreadData: case SectionKind::ThreadBSS: case SectionKind::Data: case SectionKind::BSS: case SectionKind::SmallData: case SectionKind::SmallBSS: Flags |= SectionFlags::Small; break; case SectionKind::ROData: case SectionKind::RODataMergeStr: case SectionKind::SmallROData: if (Subtarget->isXS1A()) { Flags |= SectionFlags::Writeable; } Flags |=SectionFlags::Small; break; case SectionKind::RODataMergeConst: Flags |=SectionFlags::Small; default: break; } } return Flags; } std::string XCoreTargetAsmInfo:: printSectionFlags(unsigned flags) const { std::string Flags = ",\""; if (!(flags & SectionFlags::Debug)) Flags += 'a'; if (flags & SectionFlags::Code) Flags += 'x'; if (flags & SectionFlags::Writeable) Flags += 'w'; if (flags & SectionFlags::Mergeable) Flags += 'M'; if (flags & SectionFlags::Strings) Flags += 'S'; if (flags & SectionFlags::TLS) Flags += 'T'; if (flags & SectionFlags::Small) { if (flags & SectionFlags::Writeable) Flags += 'd'; // DP relative else Flags += 'c'; // CP relative } Flags += "\","; Flags += '@'; if (flags & SectionFlags::BSS) Flags += "nobits"; else Flags += "progbits"; if (unsigned entitySize = SectionFlags::getEntitySize(flags)) Flags += "," + utostr(entitySize); return Flags; }