1f22ef01cSRoman Divacky //===-- XCoreTargetObjectFile.cpp - XCore object files --------------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky 
10f22ef01cSRoman Divacky #include "XCoreTargetObjectFile.h"
11f22ef01cSRoman Divacky #include "XCoreSubtarget.h"
12*db17bf38SDimitry Andric #include "llvm/BinaryFormat/ELF.h"
1391bc56edSDimitry Andric #include "llvm/IR/DataLayout.h"
14f22ef01cSRoman Divacky #include "llvm/MC/MCContext.h"
15f22ef01cSRoman Divacky #include "llvm/MC/MCSectionELF.h"
16139f7f9bSDimitry Andric #include "llvm/Target/TargetMachine.h"
1791bc56edSDimitry Andric 
18f22ef01cSRoman Divacky using namespace llvm;
19f22ef01cSRoman Divacky 
20f22ef01cSRoman Divacky 
Initialize(MCContext & Ctx,const TargetMachine & TM)21f22ef01cSRoman Divacky void XCoreTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){
22f22ef01cSRoman Divacky   TargetLoweringObjectFileELF::Initialize(Ctx, TM);
23f22ef01cSRoman Divacky 
24ff0cc061SDimitry Andric   BSSSection = Ctx.getELFSection(".dp.bss", ELF::SHT_NOBITS,
252754fe60SDimitry Andric                                  ELF::SHF_ALLOC | ELF::SHF_WRITE |
26ff0cc061SDimitry Andric                                      ELF::XCORE_SHF_DP_SECTION);
27ff0cc061SDimitry Andric   BSSSectionLarge = Ctx.getELFSection(".dp.bss.large", ELF::SHT_NOBITS,
2891bc56edSDimitry Andric                                       ELF::SHF_ALLOC | ELF::SHF_WRITE |
29ff0cc061SDimitry Andric                                           ELF::XCORE_SHF_DP_SECTION);
30ff0cc061SDimitry Andric   DataSection = Ctx.getELFSection(".dp.data", ELF::SHT_PROGBITS,
3191bc56edSDimitry Andric                                   ELF::SHF_ALLOC | ELF::SHF_WRITE |
32ff0cc061SDimitry Andric                                       ELF::XCORE_SHF_DP_SECTION);
33ff0cc061SDimitry Andric   DataSectionLarge = Ctx.getELFSection(".dp.data.large", ELF::SHT_PROGBITS,
3491bc56edSDimitry Andric                                        ELF::SHF_ALLOC | ELF::SHF_WRITE |
35ff0cc061SDimitry Andric                                            ELF::XCORE_SHF_DP_SECTION);
36ff0cc061SDimitry Andric   DataRelROSection = Ctx.getELFSection(".dp.rodata", ELF::SHT_PROGBITS,
3791bc56edSDimitry Andric                                        ELF::SHF_ALLOC | ELF::SHF_WRITE |
38ff0cc061SDimitry Andric                                            ELF::XCORE_SHF_DP_SECTION);
39ff0cc061SDimitry Andric   DataRelROSectionLarge = Ctx.getELFSection(
40ff0cc061SDimitry Andric       ".dp.rodata.large", ELF::SHT_PROGBITS,
41ff0cc061SDimitry Andric       ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::XCORE_SHF_DP_SECTION);
4291bc56edSDimitry Andric   ReadOnlySection =
4391bc56edSDimitry Andric       Ctx.getELFSection(".cp.rodata", ELF::SHT_PROGBITS,
44ff0cc061SDimitry Andric                         ELF::SHF_ALLOC | ELF::XCORE_SHF_CP_SECTION);
4591bc56edSDimitry Andric   ReadOnlySectionLarge =
4691bc56edSDimitry Andric       Ctx.getELFSection(".cp.rodata.large", ELF::SHT_PROGBITS,
47ff0cc061SDimitry Andric                         ELF::SHF_ALLOC | ELF::XCORE_SHF_CP_SECTION);
48ff0cc061SDimitry Andric   MergeableConst4Section = Ctx.getELFSection(
49ff0cc061SDimitry Andric       ".cp.rodata.cst4", ELF::SHT_PROGBITS,
50ff0cc061SDimitry Andric       ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, 4, "");
51ff0cc061SDimitry Andric   MergeableConst8Section = Ctx.getELFSection(
52ff0cc061SDimitry Andric       ".cp.rodata.cst8", ELF::SHT_PROGBITS,
53ff0cc061SDimitry Andric       ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, 8, "");
54ff0cc061SDimitry Andric   MergeableConst16Section = Ctx.getELFSection(
55ff0cc061SDimitry Andric       ".cp.rodata.cst16", ELF::SHT_PROGBITS,
56ff0cc061SDimitry Andric       ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, 16, "");
5791bc56edSDimitry Andric   CStringSection =
5891bc56edSDimitry Andric       Ctx.getELFSection(".cp.rodata.string", ELF::SHT_PROGBITS,
5991bc56edSDimitry Andric                         ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS |
60ff0cc061SDimitry Andric                             ELF::XCORE_SHF_CP_SECTION);
6191bc56edSDimitry Andric   // TextSection       - see MObjectFileInfo.cpp
6291bc56edSDimitry Andric   // StaticCtorSection - see MObjectFileInfo.cpp
6391bc56edSDimitry Andric   // StaticDtorSection - see MObjectFileInfo.cpp
6491bc56edSDimitry Andric  }
6591bc56edSDimitry Andric 
getXCoreSectionType(SectionKind K)6691bc56edSDimitry Andric static unsigned getXCoreSectionType(SectionKind K) {
6791bc56edSDimitry Andric   if (K.isBSS())
6891bc56edSDimitry Andric     return ELF::SHT_NOBITS;
6991bc56edSDimitry Andric   return ELF::SHT_PROGBITS;
7091bc56edSDimitry Andric }
7191bc56edSDimitry Andric 
getXCoreSectionFlags(SectionKind K,bool IsCPRel)7291bc56edSDimitry Andric static unsigned getXCoreSectionFlags(SectionKind K, bool IsCPRel) {
7391bc56edSDimitry Andric   unsigned Flags = 0;
7491bc56edSDimitry Andric 
7591bc56edSDimitry Andric   if (!K.isMetadata())
7691bc56edSDimitry Andric     Flags |= ELF::SHF_ALLOC;
7791bc56edSDimitry Andric 
7891bc56edSDimitry Andric   if (K.isText())
7991bc56edSDimitry Andric     Flags |= ELF::SHF_EXECINSTR;
8091bc56edSDimitry Andric   else if (IsCPRel)
8191bc56edSDimitry Andric     Flags |= ELF::XCORE_SHF_CP_SECTION;
8291bc56edSDimitry Andric   else
8391bc56edSDimitry Andric     Flags |= ELF::XCORE_SHF_DP_SECTION;
8491bc56edSDimitry Andric 
8591bc56edSDimitry Andric   if (K.isWriteable())
8691bc56edSDimitry Andric     Flags |= ELF::SHF_WRITE;
8791bc56edSDimitry Andric 
8891bc56edSDimitry Andric   if (K.isMergeableCString() || K.isMergeableConst4() ||
8991bc56edSDimitry Andric       K.isMergeableConst8() || K.isMergeableConst16())
9091bc56edSDimitry Andric     Flags |= ELF::SHF_MERGE;
9191bc56edSDimitry Andric 
9291bc56edSDimitry Andric   if (K.isMergeableCString())
9391bc56edSDimitry Andric     Flags |= ELF::SHF_STRINGS;
9491bc56edSDimitry Andric 
9591bc56edSDimitry Andric   return Flags;
9691bc56edSDimitry Andric }
9791bc56edSDimitry Andric 
getExplicitSectionGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const98d88c1a5aSDimitry Andric MCSection *XCoreTargetObjectFile::getExplicitSectionGlobal(
99d88c1a5aSDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
100d88c1a5aSDimitry Andric   StringRef SectionName = GO->getSection();
10191bc56edSDimitry Andric   // Infer section flags from the section name if we can.
10291bc56edSDimitry Andric   bool IsCPRel = SectionName.startswith(".cp.");
10391bc56edSDimitry Andric   if (IsCPRel && !Kind.isReadOnly())
10491bc56edSDimitry Andric     report_fatal_error("Using .cp. section for writeable object.");
10591bc56edSDimitry Andric   return getContext().getELFSection(SectionName, getXCoreSectionType(Kind),
106ff0cc061SDimitry Andric                                     getXCoreSectionFlags(Kind, IsCPRel));
10791bc56edSDimitry Andric }
10891bc56edSDimitry Andric 
SelectSectionForGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const109d88c1a5aSDimitry Andric MCSection *XCoreTargetObjectFile::SelectSectionForGlobal(
110d88c1a5aSDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
11191bc56edSDimitry Andric 
112d88c1a5aSDimitry Andric   bool UseCPRel = GO->hasLocalLinkage();
11391bc56edSDimitry Andric 
11491bc56edSDimitry Andric   if (Kind.isText())                    return TextSection;
11591bc56edSDimitry Andric   if (UseCPRel) {
11691bc56edSDimitry Andric     if (Kind.isMergeable1ByteCString()) return CStringSection;
11791bc56edSDimitry Andric     if (Kind.isMergeableConst4())       return MergeableConst4Section;
11891bc56edSDimitry Andric     if (Kind.isMergeableConst8())       return MergeableConst8Section;
11991bc56edSDimitry Andric     if (Kind.isMergeableConst16())      return MergeableConst16Section;
12091bc56edSDimitry Andric   }
121d88c1a5aSDimitry Andric   Type *ObjType = GO->getValueType();
122d88c1a5aSDimitry Andric   auto &DL = GO->getParent()->getDataLayout();
12339d628a0SDimitry Andric   if (TM.getCodeModel() == CodeModel::Small || !ObjType->isSized() ||
1247d523365SDimitry Andric       DL.getTypeAllocSize(ObjType) < CodeModelLargeSize) {
12591bc56edSDimitry Andric     if (Kind.isReadOnly())              return UseCPRel? ReadOnlySection
12691bc56edSDimitry Andric                                                        : DataRelROSection;
12791bc56edSDimitry Andric     if (Kind.isBSS() || Kind.isCommon())return BSSSection;
1287d523365SDimitry Andric     if (Kind.isData())
1297d523365SDimitry Andric       return DataSection;
13091bc56edSDimitry Andric     if (Kind.isReadOnlyWithRel())       return DataRelROSection;
13191bc56edSDimitry Andric   } else {
13291bc56edSDimitry Andric     if (Kind.isReadOnly())              return UseCPRel? ReadOnlySectionLarge
13391bc56edSDimitry Andric                                                        : DataRelROSectionLarge;
13491bc56edSDimitry Andric     if (Kind.isBSS() || Kind.isCommon())return BSSSectionLarge;
1357d523365SDimitry Andric     if (Kind.isData())
1367d523365SDimitry Andric       return DataSectionLarge;
13791bc56edSDimitry Andric     if (Kind.isReadOnlyWithRel())       return DataRelROSectionLarge;
13891bc56edSDimitry Andric   }
13991bc56edSDimitry Andric 
14091bc56edSDimitry Andric   assert((Kind.isThreadLocal() || Kind.isCommon()) && "Unknown section kind");
14191bc56edSDimitry Andric   report_fatal_error("Target does not support TLS or Common sections");
14291bc56edSDimitry Andric }
14391bc56edSDimitry Andric 
getSectionForConstant(const DataLayout & DL,SectionKind Kind,const Constant * C,unsigned & Align) const1443ca95b02SDimitry Andric MCSection *XCoreTargetObjectFile::getSectionForConstant(const DataLayout &DL,
1453ca95b02SDimitry Andric                                                         SectionKind Kind,
1463ca95b02SDimitry Andric                                                         const Constant *C,
1473ca95b02SDimitry Andric                                                         unsigned &Align) const {
14891bc56edSDimitry Andric   if (Kind.isMergeableConst4())           return MergeableConst4Section;
14991bc56edSDimitry Andric   if (Kind.isMergeableConst8())           return MergeableConst8Section;
15091bc56edSDimitry Andric   if (Kind.isMergeableConst16())          return MergeableConst16Section;
15191bc56edSDimitry Andric   assert((Kind.isReadOnly() || Kind.isReadOnlyWithRel()) &&
15291bc56edSDimitry Andric          "Unknown section kind");
15391bc56edSDimitry Andric   // We assume the size of the object is never greater than CodeModelLargeSize.
15491bc56edSDimitry Andric   // To handle CodeModelLargeSize changes to AsmPrinter would be required.
15591bc56edSDimitry Andric   return ReadOnlySection;
156f22ef01cSRoman Divacky }
157