mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
XCore target: fix const section handling
Xcore target ABI requires const data that is externally visible to be handled differently if it has C-language linkage rather than C++ language linkage. Clang now emits ".cp.rodata" section information. All other externally visible constant data will be placed in the DP section. llvm-svn: 201144
This commit is contained in:
parent
6ac9a5d013
commit
604b5e52e1
@ -275,7 +275,10 @@ getGlobalAddressWrapper(SDValue GA, const GlobalValue *GV,
|
||||
if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
|
||||
UnderlyingGV = GA->resolveAliasedGlobal();
|
||||
if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(UnderlyingGV)) {
|
||||
if (GVar->isConstant())
|
||||
if ( ( GVar->isConstant() &&
|
||||
UnderlyingGV->isLocalLinkage(GV->getLinkage()) )
|
||||
|| ( GVar->hasSection() &&
|
||||
StringRef(GVar->getSection()).startswith(".cp.") ) )
|
||||
return DAG.getNode(XCoreISD::CPRelativeWrapper, dl, MVT::i32, GA);
|
||||
return DAG.getNode(XCoreISD::DPRelativeWrapper, dl, MVT::i32, GA);
|
||||
}
|
||||
|
@ -41,10 +41,16 @@ void XCoreTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){
|
||||
ELF::SHF_ALLOC | ELF::SHF_WRITE |
|
||||
ELF::XCORE_SHF_DP_SECTION,
|
||||
SectionKind::getDataRel());
|
||||
// This is the wrong place to decide if const data should be placed
|
||||
// in the .cp or .dp section.
|
||||
// Ideally we should set up DataRelROSection to use the '.dp.'' and use this
|
||||
// for const data, unless the front end explicitly states a '.cp.'' section.
|
||||
DataRelROSection =
|
||||
Ctx.getELFSection(".dp.rodata", ELF::SHT_PROGBITS,
|
||||
ELF::SHF_ALLOC | ELF::SHF_WRITE |
|
||||
ELF::XCORE_SHF_DP_SECTION,
|
||||
SectionKind::getReadOnlyWithRel());
|
||||
DataRelROSectionLarge =
|
||||
Ctx.getELFSection(".dp.rodata.large", ELF::SHT_PROGBITS,
|
||||
ELF::SHF_ALLOC | ELF::SHF_WRITE |
|
||||
ELF::XCORE_SHF_DP_SECTION,
|
||||
SectionKind::getReadOnlyWithRel());
|
||||
ReadOnlySection =
|
||||
Ctx.getELFSection(".cp.rodata", ELF::SHT_PROGBITS,
|
||||
ELF::SHF_ALLOC |
|
||||
@ -80,19 +86,13 @@ void XCoreTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){
|
||||
// StaticDtorSection - see MObjectFileInfo.cpp
|
||||
}
|
||||
|
||||
static SectionKind getXCoreKindForNamedSection(StringRef Name, SectionKind K) {
|
||||
if (Name.startswith(".cp."))
|
||||
return SectionKind::getReadOnly();
|
||||
return K;
|
||||
}
|
||||
|
||||
static unsigned getXCoreSectionType(SectionKind K) {
|
||||
if (K.isBSS())
|
||||
return ELF::SHT_NOBITS;
|
||||
return ELF::SHT_PROGBITS;
|
||||
}
|
||||
|
||||
static unsigned getXCoreSectionFlags(SectionKind K) {
|
||||
static unsigned getXCoreSectionFlags(SectionKind K, bool IsCPRel) {
|
||||
unsigned Flags = 0;
|
||||
|
||||
if (!K.isMetadata())
|
||||
@ -100,7 +100,7 @@ static unsigned getXCoreSectionFlags(SectionKind K) {
|
||||
|
||||
if (K.isText())
|
||||
Flags |= ELF::SHF_EXECINSTR;
|
||||
else if (K.isReadOnly())
|
||||
else if (IsCPRel)
|
||||
Flags |= ELF::XCORE_SHF_CP_SECTION;
|
||||
else
|
||||
Flags |= ELF::XCORE_SHF_DP_SECTION;
|
||||
@ -123,33 +123,41 @@ getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind,
|
||||
Mangler &Mang, const TargetMachine &TM) const {
|
||||
StringRef SectionName = GV->getSection();
|
||||
// Infer section flags from the section name if we can.
|
||||
Kind = getXCoreKindForNamedSection(SectionName, Kind);
|
||||
bool IsCPRel = SectionName.startswith(".cp.");
|
||||
if (IsCPRel && !Kind.isReadOnly())
|
||||
report_fatal_error("Using .cp. section for writeable object.");
|
||||
return getContext().getELFSection(SectionName, getXCoreSectionType(Kind),
|
||||
getXCoreSectionFlags(Kind), Kind);
|
||||
getXCoreSectionFlags(Kind, IsCPRel), Kind);
|
||||
}
|
||||
|
||||
const MCSection *XCoreTargetObjectFile::
|
||||
SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler &Mang,
|
||||
const TargetMachine &TM) const{
|
||||
if (Kind.isText()) return TextSection;
|
||||
if (Kind.isMergeable1ByteCString()) return CStringSection;
|
||||
if (Kind.isMergeableConst4()) return MergeableConst4Section;
|
||||
if (Kind.isMergeableConst8()) return MergeableConst8Section;
|
||||
if (Kind.isMergeableConst16()) return MergeableConst16Section;
|
||||
|
||||
bool UseCPRel = GV->isLocalLinkage(GV->getLinkage());
|
||||
|
||||
if (Kind.isText()) return TextSection;
|
||||
if (UseCPRel) {
|
||||
if (Kind.isMergeable1ByteCString()) return CStringSection;
|
||||
if (Kind.isMergeableConst4()) return MergeableConst4Section;
|
||||
if (Kind.isMergeableConst8()) return MergeableConst8Section;
|
||||
if (Kind.isMergeableConst16()) return MergeableConst16Section;
|
||||
}
|
||||
Type *ObjType = GV->getType()->getPointerElementType();
|
||||
if (TM.getCodeModel() == CodeModel::Small ||
|
||||
!ObjType->isSized() ||
|
||||
TM.getDataLayout()->getTypeAllocSize(ObjType) < CodeModelLargeSize) {
|
||||
if (Kind.isReadOnly()) return ReadOnlySection;
|
||||
if (Kind.isBSS()) return BSSSection;
|
||||
if (Kind.isDataRel()) return DataSection;
|
||||
if (Kind.isReadOnlyWithRel()) return ReadOnlySection;
|
||||
if (Kind.isReadOnly()) return UseCPRel? ReadOnlySection
|
||||
: DataRelROSection;
|
||||
if (Kind.isBSS()) return BSSSection;
|
||||
if (Kind.isDataRel()) return DataSection;
|
||||
if (Kind.isReadOnlyWithRel()) return DataRelROSection;
|
||||
} else {
|
||||
if (Kind.isReadOnly()) return ReadOnlySectionLarge;
|
||||
if (Kind.isBSS()) return BSSSectionLarge;
|
||||
if (Kind.isDataRel()) return DataSectionLarge;
|
||||
if (Kind.isReadOnlyWithRel()) return ReadOnlySectionLarge;
|
||||
if (Kind.isReadOnly()) return UseCPRel? ReadOnlySectionLarge
|
||||
: DataRelROSectionLarge;
|
||||
if (Kind.isBSS()) return BSSSectionLarge;
|
||||
if (Kind.isDataRel()) return DataSectionLarge;
|
||||
if (Kind.isReadOnlyWithRel()) return DataRelROSectionLarge;
|
||||
}
|
||||
|
||||
assert((Kind.isThreadLocal() || Kind.isCommon()) && "Unknown section kind");
|
||||
|
@ -20,6 +20,7 @@ static const unsigned CodeModelLargeSize = 256;
|
||||
const MCSection *BSSSectionLarge;
|
||||
const MCSection *DataSectionLarge;
|
||||
const MCSection *ReadOnlySectionLarge;
|
||||
const MCSection *DataRelROSectionLarge;
|
||||
public:
|
||||
void Initialize(MCContext &Ctx, const TargetMachine &TM);
|
||||
|
||||
|
@ -171,27 +171,43 @@ entry:
|
||||
; LARGE: .space 40
|
||||
@s = global [10 x i32] zeroinitializer
|
||||
|
||||
; CHECK: .section .cp.rodata,"ac",@progbits
|
||||
; CHECK: .section .dp.rodata,"awd",@progbits
|
||||
; CHECK-LABEL: cl:
|
||||
; CHECK: .space 400
|
||||
; LARGE: .section .cp.rodata.large,"ac",@progbits
|
||||
; LARGE: .section .dp.rodata.large,"awd",@progbits
|
||||
; LARGE-LABEL: cl:
|
||||
; LARGE: .space 400
|
||||
@cl = constant [100 x i32] zeroinitializer
|
||||
|
||||
; CHECK-LABEL: cs:
|
||||
; CHECK: .space 40
|
||||
; LARGE: .section .cp.rodata,"ac",@progbits
|
||||
; LARGE: .section .dp.rodata,"awd",@progbits
|
||||
; LARGE-LABEL: cs:
|
||||
; LARGE: .space 40
|
||||
@cs = constant [10 x i32] zeroinitializer
|
||||
|
||||
; CHECK: .section .cp.rodata,"ac",@progbits
|
||||
; CHECK-LABEL: icl:
|
||||
; CHECK: .space 400
|
||||
; LARGE: .section .cp.rodata.large,"ac",@progbits
|
||||
; LARGE-LABEL: icl:
|
||||
; LARGE: .space 400
|
||||
@icl = internal constant [100 x i32] zeroinitializer
|
||||
|
||||
; CHECK-LABEL: cs:
|
||||
; CHECK: .space 40
|
||||
; LARGE: .section .cp.rodata,"ac",@progbits
|
||||
; LARGE-LABEL: cs:
|
||||
; LARGE: .space 40
|
||||
@ics = internal constant [10 x i32] zeroinitializer
|
||||
|
||||
; CHECK: .section .cp.namedsection,"ac",@progbits
|
||||
; CHECK-LABEL: cpsec:
|
||||
; CHECK: .long 0
|
||||
@cpsec = global i32 0, section ".cp.namedsection"
|
||||
@cpsec = constant i32 0, section ".cp.namedsection"
|
||||
|
||||
; CHECK: .section .dp.namedsection,"awd",@progbits
|
||||
; CHECK-LABEL: dpsec:
|
||||
; CHECK: .long 0
|
||||
@dpsec = global i32 0, section ".dp.namedsection"
|
||||
|
||||
|
@ -29,9 +29,8 @@ entry:
|
||||
; CHECK: .cfi_offset 15, 0
|
||||
; CHECK: ldc r0, 4
|
||||
; CHECK: bl __cxa_allocate_exception
|
||||
; CHECK: ldaw r11, cp[_ZTIi]
|
||||
; CHECK: ldaw r1, dp[_ZTIi]
|
||||
; CHECK: ldc r2, 0
|
||||
; CHECK: mov r1, r11
|
||||
; CHECK: bl __cxa_throw
|
||||
define void @fn_throw() {
|
||||
entry:
|
||||
|
@ -17,11 +17,18 @@ entry:
|
||||
define i32 *@addr_G3() {
|
||||
entry:
|
||||
; CHECK-LABEL: addr_G3:
|
||||
; CHECK: ldaw r11, cp[G3]
|
||||
; CHECK: mov r0, r11
|
||||
; CHECK: ldaw r0, dp[G3]
|
||||
ret i32* @G3
|
||||
}
|
||||
|
||||
define i32 *@addr_iG3() {
|
||||
entry:
|
||||
; CHECK-LABEL: addr_iG3:
|
||||
; CHECK: ldaw r11, cp[iG3]
|
||||
; CHECK: mov r0, r11
|
||||
ret i32* @iG3
|
||||
}
|
||||
|
||||
define i32 **@addr_G4() {
|
||||
entry:
|
||||
; CHECK-LABEL: addr_G4:
|
||||
@ -32,11 +39,18 @@ entry:
|
||||
define i32 **@addr_G5() {
|
||||
entry:
|
||||
; CHECK-LABEL: addr_G5:
|
||||
; CHECK: ldaw r11, cp[G5]
|
||||
; CHECK: mov r0, r11
|
||||
; CHECK: ldaw r0, dp[G5]
|
||||
ret i32** @G5
|
||||
}
|
||||
|
||||
define i32 **@addr_iG5() {
|
||||
entry:
|
||||
; CHECK-LABEL: addr_iG5:
|
||||
; CHECK: ldaw r11, cp[iG5]
|
||||
; CHECK: mov r0, r11
|
||||
ret i32** @iG5
|
||||
}
|
||||
|
||||
define i32 **@addr_G6() {
|
||||
entry:
|
||||
; CHECK-LABEL: addr_G6:
|
||||
@ -47,11 +61,18 @@ entry:
|
||||
define i32 **@addr_G7() {
|
||||
entry:
|
||||
; CHECK-LABEL: addr_G7:
|
||||
; CHECK: ldaw r11, cp[G7]
|
||||
; CHECK: mov r0, r11
|
||||
; CHECK: ldaw r0, dp[G7]
|
||||
ret i32** @G7
|
||||
}
|
||||
|
||||
define i32 **@addr_iG7() {
|
||||
entry:
|
||||
; CHECK-LABEL: addr_iG7:
|
||||
; CHECK: ldaw r11, cp[iG7]
|
||||
; CHECK: mov r0, r11
|
||||
ret i32** @iG7
|
||||
}
|
||||
|
||||
define i32 *@addr_G8() {
|
||||
entry:
|
||||
; CHECK-LABEL: addr_G8:
|
||||
@ -68,26 +89,38 @@ entry:
|
||||
; CHECK: G2:
|
||||
|
||||
@G3 = unnamed_addr constant i32 9401
|
||||
; CHECK: .section .cp.rodata.cst4,"aMc",@progbits,4
|
||||
; CHECK: .section .dp.rodata,"awd",@progbits
|
||||
; CHECK: G3:
|
||||
|
||||
@iG3 = internal constant i32 9401
|
||||
; CHECK: .section .cp.rodata,"ac",@progbits
|
||||
; CHECK: iG3:
|
||||
|
||||
@G4 = global i32* @G1
|
||||
; CHECK: .section .dp.data,"awd",@progbits
|
||||
; CHECK: G4:
|
||||
|
||||
@G5 = unnamed_addr constant i32* @G1
|
||||
; CHECK: .section .cp.rodata,"ac",@progbits
|
||||
; CHECK: .section .dp.rodata,"awd",@progbits
|
||||
; CHECK: G5:
|
||||
|
||||
@iG5 = internal unnamed_addr constant i32* @G1
|
||||
; CHECK: .section .cp.rodata,"ac",@progbits
|
||||
; CHECK: iG5:
|
||||
|
||||
@G6 = global i32* @G8
|
||||
; CHECK: .section .dp.data,"awd",@progbits
|
||||
; CHECK: G6:
|
||||
|
||||
@G7 = unnamed_addr constant i32* @G8
|
||||
; CHECK: .section .cp.rodata,"ac",@progbits
|
||||
; CHECK: .section .dp.rodata,"awd",@progbits
|
||||
; CHECK: G7:
|
||||
|
||||
@G8 = internal global i32 9312
|
||||
@iG7 = internal unnamed_addr constant i32* @G8
|
||||
; CHECK: .section .cp.rodata,"ac",@progbits
|
||||
; CHECK: iG7:
|
||||
|
||||
@G8 = global i32 9312
|
||||
; CHECK: .section .dp.data,"awd",@progbits
|
||||
; CHECK: G8:
|
||||
|
||||
|
@ -119,13 +119,12 @@ entry:
|
||||
; CHECK-LABEL: EH2
|
||||
; CHECK: entsp 1
|
||||
; CHECK: bl foo
|
||||
; CHECK-NEXT: ldw r0, cp[offset]
|
||||
; CHECK-NEXT: ldw r0, dp[offset]
|
||||
; CHECK-NEXT: ldc r1, 4
|
||||
; CHECK-NEXT: ldaw r2, sp[0]
|
||||
; CHECK-NEXT: add r1, r2, r1
|
||||
; CHECK-NEXT: add r2, r1, r0
|
||||
; CHECK-NEXT: ldaw r11, cp[handler]
|
||||
; CHECK-NEXT: mov r3, r11
|
||||
; CHECK-NEXT: ldaw r3, dp[handler]
|
||||
; CHECK-NEXT: set sp, r2
|
||||
; CHECK-NEXT: bau r3
|
||||
call void (...)* @foo()
|
||||
|
@ -40,7 +40,7 @@ entry:
|
||||
ret i32 %2
|
||||
}
|
||||
|
||||
@GConst = external constant i32
|
||||
@GConst = internal constant i32 42
|
||||
define i32 @load_cp() nounwind {
|
||||
entry:
|
||||
; CHECK-LABEL: load_cp:
|
||||
|
Loading…
Reference in New Issue
Block a user