summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp7
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp25
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.h1
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 {
OpenPOWER on IntegriCloud