diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/XCore/MCTargetDesc/XCoreMCTargetDesc.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Target/XCore/XCoreISelLowering.cpp | 40 | ||||
-rw-r--r-- | llvm/lib/Target/XCore/XCoreInstrInfo.td | 3 | ||||
-rw-r--r-- | llvm/lib/Target/XCore/XCoreTargetObjectFile.cpp | 139 | ||||
-rw-r--r-- | llvm/lib/Target/XCore/XCoreTargetObjectFile.h | 15 |
5 files changed, 175 insertions, 28 deletions
diff --git a/llvm/lib/Target/XCore/MCTargetDesc/XCoreMCTargetDesc.cpp b/llvm/lib/Target/XCore/MCTargetDesc/XCoreMCTargetDesc.cpp index 10bb6dfa928..c4347357d51 100644 --- a/llvm/lib/Target/XCore/MCTargetDesc/XCoreMCTargetDesc.cpp +++ b/llvm/lib/Target/XCore/MCTargetDesc/XCoreMCTargetDesc.cpp @@ -69,6 +69,12 @@ static MCCodeGenInfo *createXCoreMCCodeGenInfo(StringRef TT, Reloc::Model RM, if (RM == Reloc::Default) { RM = Reloc::Static; } + if (CM == CodeModel::Default) { + CM = CodeModel::Small; + } + if (CM != CodeModel::Small && CM != CodeModel::Large) + report_fatal_error("Target only supports CodeModel Small or Large"); + X->InitMCCodeGenInfo(RM, CM, OL); return X; } diff --git a/llvm/lib/Target/XCore/XCoreISelLowering.cpp b/llvm/lib/Target/XCore/XCoreISelLowering.cpp index 89ad27daec1..6b0a2d0835e 100644 --- a/llvm/lib/Target/XCore/XCoreISelLowering.cpp +++ b/llvm/lib/Target/XCore/XCoreISelLowering.cpp @@ -28,6 +28,7 @@ #include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/IR/CallingConv.h" +#include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalAlias.h" @@ -270,20 +271,35 @@ getGlobalAddressWrapper(SDValue GA, const GlobalValue *GV, SDValue XCoreTargetLowering:: LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const { - SDLoc DL(Op); const GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(Op); const GlobalValue *GV = GN->getGlobal(); + SDLoc DL(GN); int64_t Offset = GN->getOffset(); - // We can only fold positive offsets that are a multiple of the word size. - int64_t FoldedOffset = std::max(Offset & ~3, (int64_t)0); - SDValue GA = DAG.getTargetGlobalAddress(GV, DL, MVT::i32, FoldedOffset); - GA = getGlobalAddressWrapper(GA, GV, DAG); - // Handle the rest of the offset. - if (Offset != FoldedOffset) { - SDValue Remaining = DAG.getConstant(Offset - FoldedOffset, MVT::i32); - GA = DAG.getNode(ISD::ADD, DL, MVT::i32, GA, Remaining); + Type *ObjType = GV->getType()->getPointerElementType(); + if (getTargetMachine().getCodeModel() == CodeModel::Small || + !ObjType->isSized() || + getDataLayout()->getTypeAllocSize(ObjType) < CodeModelLargeSize) { + // We can only fold positive offsets that are a multiple of the word size. + int64_t FoldedOffset = std::max(Offset & ~3, (int64_t)0); + SDValue GA = DAG.getTargetGlobalAddress(GV, DL, MVT::i32, FoldedOffset); + GA = getGlobalAddressWrapper(GA, GV, DAG); + // Handle the rest of the offset. + if (Offset != FoldedOffset) { + SDValue Remaining = DAG.getConstant(Offset - FoldedOffset, MVT::i32); + GA = DAG.getNode(ISD::ADD, DL, MVT::i32, GA, Remaining); + } + return GA; + } else { + // Ideally we would not fold in offset with an index <= 11. + Type *Ty = Type::getInt8PtrTy(*DAG.getContext()); + Constant *GA = ConstantExpr::getBitCast(const_cast<GlobalValue*>(GV), Ty); + Ty = Type::getInt32Ty(*DAG.getContext()); + Constant *Idx = ConstantInt::get(Ty, Offset); + Constant *GAI = ConstantExpr::getGetElementPtr(GA, Idx); + SDValue CP = DAG.getConstantPool(GAI, MVT::i32); + return DAG.getLoad(getPointerTy(), DL, DAG.getEntryNode(), CP, + MachinePointerInfo(), false, false, false, 0); } - return GA; } SDValue XCoreTargetLowering:: @@ -307,10 +323,10 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG) const SDValue Res; if (CP->isMachineConstantPoolEntry()) { Res = DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT, - CP->getAlignment()); + CP->getAlignment(), CP->getOffset()); } else { Res = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, - CP->getAlignment()); + CP->getAlignment(), CP->getOffset()); } return DAG.getNode(XCoreISD::CPRelativeWrapper, dl, MVT::i32, Res); } diff --git a/llvm/lib/Target/XCore/XCoreInstrInfo.td b/llvm/lib/Target/XCore/XCoreInstrInfo.td index 934a707e785..3f0d08c17a7 100644 --- a/llvm/lib/Target/XCore/XCoreInstrInfo.td +++ b/llvm/lib/Target/XCore/XCoreInstrInfo.td @@ -1286,3 +1286,6 @@ def : Pat<(setgt GRRegs:$lhs, -1), def : Pat<(sra (shl GRRegs:$src, immBpwSubBitp:$imm), immBpwSubBitp:$imm), (SEXT_rus GRRegs:$src, (bpwsub_xform immBpwSubBitp:$imm))>; + +def : Pat<(load (cprelwrapper tconstpool:$b)), + (LDWCP_lru6 tconstpool:$b)>; diff --git a/llvm/lib/Target/XCore/XCoreTargetObjectFile.cpp b/llvm/lib/Target/XCore/XCoreTargetObjectFile.cpp index 88e3bfd7b81..61eb2b51f3e 100644 --- a/llvm/lib/Target/XCore/XCoreTargetObjectFile.cpp +++ b/llvm/lib/Target/XCore/XCoreTargetObjectFile.cpp @@ -9,27 +9,52 @@ #include "XCoreTargetObjectFile.h" #include "XCoreSubtarget.h" +#include "llvm/IR/DataLayout.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/Support/ELF.h" #include "llvm/Target/TargetMachine.h" + using namespace llvm; void XCoreTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){ TargetLoweringObjectFileELF::Initialize(Ctx, TM); + BSSSection = + Ctx.getELFSection(".dp.bss", ELF::SHT_NOBITS, + ELF::SHF_ALLOC | ELF::SHF_WRITE | + ELF::XCORE_SHF_DP_SECTION, + SectionKind::getBSS()); + BSSSectionLarge = + Ctx.getELFSection(".dp.bss.large", ELF::SHT_NOBITS, + ELF::SHF_ALLOC | ELF::SHF_WRITE | + ELF::XCORE_SHF_DP_SECTION, + SectionKind::getBSS()); DataSection = - Ctx.getELFSection(".dp.data", ELF::SHT_PROGBITS, + Ctx.getELFSection(".dp.data", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::XCORE_SHF_DP_SECTION, SectionKind::getDataRel()); - BSSSection = - Ctx.getELFSection(".dp.bss", ELF::SHT_NOBITS, + DataSectionLarge = + Ctx.getELFSection(".dp.data.large", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::XCORE_SHF_DP_SECTION, - SectionKind::getBSS()); - + 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. + ReadOnlySection = + Ctx.getELFSection(".cp.rodata", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | + ELF::XCORE_SHF_CP_SECTION, + SectionKind::getReadOnlyWithRel()); + ReadOnlySectionLarge = + Ctx.getELFSection(".cp.rodata.large", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | + ELF::XCORE_SHF_CP_SECTION, + SectionKind::getReadOnlyWithRel()); MergeableConst4Section = Ctx.getELFSection(".cp.rodata.cst4", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_MERGE | @@ -45,16 +70,100 @@ void XCoreTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){ ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::XCORE_SHF_CP_SECTION, SectionKind::getMergeableConst16()); - - // TLS globals are lowered in the backend to arrays indexed by the current - // thread id. After lowering they require no special handling by the linker - // and can be placed in the standard data / bss sections. - TLSDataSection = DataSection; - TLSBSSSection = BSSSection; - - ReadOnlySection = - Ctx.getELFSection(".cp.rodata", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC | + CStringSection = + Ctx.getELFSection(".cp.rodata.string", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS | ELF::XCORE_SHF_CP_SECTION, SectionKind::getReadOnlyWithRel()); + // TextSection - see MObjectFileInfo.cpp + // StaticCtorSection - see MObjectFileInfo.cpp + // 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) { + unsigned Flags = 0; + + if (!K.isMetadata()) + Flags |= ELF::SHF_ALLOC; + + if (K.isText()) + Flags |= ELF::SHF_EXECINSTR; + else if (K.isReadOnly()) + Flags |= ELF::XCORE_SHF_CP_SECTION; + else + Flags |= ELF::XCORE_SHF_DP_SECTION; + + if (K.isWriteable()) + Flags |= ELF::SHF_WRITE; + + if (K.isMergeableCString() || K.isMergeableConst4() || + K.isMergeableConst8() || K.isMergeableConst16()) + Flags |= ELF::SHF_MERGE; + + if (K.isMergeableCString()) + Flags |= ELF::SHF_STRINGS; + + return Flags; +} + +const MCSection *XCoreTargetObjectFile:: +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); + return getContext().getELFSection(SectionName, getXCoreSectionType(Kind), + getXCoreSectionFlags(Kind), 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; + + 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; + } else { + if (Kind.isReadOnly()) return ReadOnlySectionLarge; + if (Kind.isBSS()) return BSSSectionLarge; + if (Kind.isDataRel()) return DataSectionLarge; + if (Kind.isReadOnlyWithRel()) return ReadOnlySectionLarge; + } + + assert((Kind.isThreadLocal() || Kind.isCommon()) && "Unknown section kind"); + report_fatal_error("Target does not support TLS or Common sections"); +} + +const MCSection *XCoreTargetObjectFile:: +getSectionForConstant(SectionKind Kind) const { + if (Kind.isMergeableConst4()) return MergeableConst4Section; + if (Kind.isMergeableConst8()) return MergeableConst8Section; + if (Kind.isMergeableConst16()) return MergeableConst16Section; + assert((Kind.isReadOnly() || Kind.isReadOnlyWithRel()) && + "Unknown section kind"); + // We assume the size of the object is never greater than CodeModelLargeSize. + // To handle CodeModelLargeSize changes to AsmPrinter would be required. + return ReadOnlySection; } diff --git a/llvm/lib/Target/XCore/XCoreTargetObjectFile.h b/llvm/lib/Target/XCore/XCoreTargetObjectFile.h index 27875e783b3..bf9798d5085 100644 --- a/llvm/lib/Target/XCore/XCoreTargetObjectFile.h +++ b/llvm/lib/Target/XCore/XCoreTargetObjectFile.h @@ -14,11 +14,24 @@ namespace llvm { +static const unsigned CodeModelLargeSize = 256; + class XCoreTargetObjectFile : public TargetLoweringObjectFileELF { + const MCSection *BSSSectionLarge; + const MCSection *DataSectionLarge; + const MCSection *ReadOnlySectionLarge; public: void Initialize(MCContext &Ctx, const TargetMachine &TM); - // TODO: Classify globals as xcore wishes. + virtual const MCSection * + getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + virtual const MCSection * + SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, + Mangler *Mang, const TargetMachine &TM) const; + + virtual const MCSection *getSectionForConstant(SectionKind Kind) const; }; } // end namespace llvm |