diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 25 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.h | 1 |
3 files changed, 33 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index eb2a28f574a..d19ca47ec1a 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1055,6 +1055,13 @@ MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable( COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); } +bool TargetLoweringObjectFileCOFF::shouldPutJumpTableInFunctionSection( + bool UsesLabelDifference, const Function &F) const { + // We can always create relative relocations, so use another section + // that can be marked non-executable. + return false; +} + void TargetLoweringObjectFileCOFF::emitModuleFlags( MCStreamer &Streamer, ArrayRef<Module::ModuleFlagEntry> ModuleFlags, const TargetMachine &TM) const { diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index b293dfa98f8..d0c77030acd 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -1926,10 +1926,20 @@ unsigned X86TargetLowering::getJumpTableEncoding() const { if (isPositionIndependent() && Subtarget.isPICStyleGOT()) return MachineJumpTableInfo::EK_Custom32; + // On Win64, we want to use both label differences and a separate section. + if (Subtarget.isTargetWin64()) + return MachineJumpTableInfo::EK_LabelDifference32; + // Otherwise, use the normal jump table encoding heuristics. return TargetLowering::getJumpTableEncoding(); } +bool X86TargetLowering::isJumpTableRelative() const { + if (Subtarget.isTargetWin64()) + return true; + return TargetLowering::isJumpTableRelative(); +} + bool X86TargetLowering::useSoftFloat() const { return Subtarget.useSoftFloat(); } @@ -1948,11 +1958,19 @@ X86TargetLowering::LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI, /// Returns relocation base for the given PIC jumptable. SDValue X86TargetLowering::getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) const { + // COFF doesn't have relocations to take the difference between two arbitrary + // symbols. The assembler, however, can resolve a fixup between the function + // entry and a basic block label, so use the function entry as the base. + if (Subtarget.isTargetWin64()) + return DAG.getGlobalAddress(DAG.getMachineFunction().getFunction(), SDLoc(), + getPointerTy(DAG.getDataLayout())); + if (!Subtarget.is64Bit()) // This doesn't have SDLoc associated with it, but is not really the // same as a Register. return DAG.getNode(X86ISD::GlobalBaseReg, SDLoc(), getPointerTy(DAG.getDataLayout())); + return Table; } @@ -1961,6 +1979,13 @@ SDValue X86TargetLowering::getPICJumpTableRelocBase(SDValue Table, const MCExpr *X86TargetLowering:: getPICJumpTableRelocBaseExpr(const MachineFunction *MF, unsigned JTI, MCContext &Ctx) const { + // COFF doesn't have relocations to take the difference between two arbitrary + // symbols. The assembler, however, can resolve a fixup between the function + // entry and a basic block label, so use the function entry as the base. + if (Subtarget.isTargetWin64()) + return MCSymbolRefExpr::create( + getTargetMachine().getSymbol(MF->getFunction()), Ctx); + // X86-64 uses RIP relative addressing based on the jump table label. if (Subtarget.isPICStyleRIPRel()) return TargetLowering::getPICJumpTableRelocBaseExpr(MF, JTI, Ctx); diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h index 37f9353042b..643727d7aed 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -684,6 +684,7 @@ namespace llvm { const X86Subtarget &STI); unsigned getJumpTableEncoding() const override; + bool isJumpTableRelative() const override; bool useSoftFloat() const override; MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override { |