aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-11-20 23:18:13 +0000
committerDan Gohman <gohman@apple.com>2009-11-20 23:18:13 +0000
commit29cbade25aa094ca9a149a96a8614cf6f3247480 (patch)
treeabb27ef9149ed31fa94e92ccb065a36bf61c4257 /lib/Target
parentb9e6b34e1e6141b4eeb2d2a7ca00652923575795 (diff)
downloadexternal_llvm-29cbade25aa094ca9a149a96a8614cf6f3247480.zip
external_llvm-29cbade25aa094ca9a149a96a8614cf6f3247480.tar.gz
external_llvm-29cbade25aa094ca9a149a96a8614cf6f3247480.tar.bz2
Target-independent support for TargetFlags on BlockAddress operands,
and support for blockaddresses in x86-32 PIC mode. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89506 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp2
-rw-r--r--lib/Target/X86/AsmPrinter/X86MCInstLower.cpp17
-rw-r--r--lib/Target/X86/AsmPrinter/X86MCInstLower.h1
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp8
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp25
-rw-r--r--lib/Target/X86/X86Subtarget.cpp15
-rw-r--r--lib/Target/X86/X86Subtarget.h5
-rw-r--r--lib/Target/XCore/XCoreISelLowering.cpp2
8 files changed, 58 insertions, 17 deletions
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index 099fcb5..d24f483 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -1174,7 +1174,7 @@ SDValue PPCTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) {
DebugLoc DL = Op.getDebugLoc();
BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
- SDValue TgtBA = DAG.getBlockAddress(BA, DL, /*isTarget=*/true);
+ SDValue TgtBA = DAG.getBlockAddress(BA, PtrVT, /*isTarget=*/true);
SDValue Zero = DAG.getConstant(0, PtrVT);
SDValue Hi = DAG.getNode(PPCISD::Hi, DL, PtrVT, TgtBA, Zero);
SDValue Lo = DAG.getNode(PPCISD::Lo, DL, PtrVT, TgtBA, Zero);
diff --git a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
index be9f4b2..49fbd46 100644
--- a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
+++ b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp
@@ -43,7 +43,6 @@ MCSymbol *X86MCInstLower::GetPICBaseSymbol() const {
Twine(AsmPrinter.getFunctionNumber())+"$pb");
}
-
/// LowerGlobalAddressOperand - Lower an MO_GlobalAddress operand to an
/// MCOperand.
MCSymbol *X86MCInstLower::
@@ -231,6 +230,19 @@ GetConstantPoolIndexSymbol(const MachineOperand &MO) const {
return Ctx.GetOrCreateSymbol(Name.str());
}
+MCSymbol *X86MCInstLower::
+GetBlockAddressSymbol(const MachineOperand &MO) const {
+ const char *Suffix = "";
+ switch (MO.getTargetFlags()) {
+ default: llvm_unreachable("Unknown target flag on BA operand");
+ case X86II::MO_NO_FLAG: // No flag.
+ case X86II::MO_PIC_BASE_OFFSET: // Doesn't modify symbol name.
+ case X86II::MO_GOTOFF: Suffix = "@GOTOFF"; break;
+ }
+
+ return AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress(), Suffix);
+}
+
MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
MCSymbol *Sym) const {
// FIXME: We would like an efficient form for this, so we don't have to do a
@@ -331,8 +343,7 @@ void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO));
break;
case MachineOperand::MO_BlockAddress:
- MCOp = LowerSymbolOperand(MO, AsmPrinter.GetBlockAddressSymbol(
- MO.getBlockAddress()));
+ MCOp = LowerSymbolOperand(MO, GetBlockAddressSymbol(MO));
break;
}
diff --git a/lib/Target/X86/AsmPrinter/X86MCInstLower.h b/lib/Target/X86/AsmPrinter/X86MCInstLower.h
index fa25b90..94f8bfc 100644
--- a/lib/Target/X86/AsmPrinter/X86MCInstLower.h
+++ b/lib/Target/X86/AsmPrinter/X86MCInstLower.h
@@ -43,6 +43,7 @@ public:
MCSymbol *GetExternalSymbolSymbol(const MachineOperand &MO) const;
MCSymbol *GetJumpTableSymbol(const MachineOperand &MO) const;
MCSymbol *GetConstantPoolIndexSymbol(const MachineOperand &MO) const;
+ MCSymbol *GetBlockAddressSymbol(const MachineOperand &MO) const;
MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const;
private:
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index 6a3577a..a9a78be 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -252,8 +252,8 @@ namespace {
else if (AM.JT != -1)
Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags);
else if (AM.BlockAddr)
- Disp = CurDAG->getBlockAddress(AM.BlockAddr, DebugLoc()/*MVT::i32*/,
- true /*AM.SymbolFlags*/);
+ Disp = CurDAG->getBlockAddress(AM.BlockAddr, MVT::i32,
+ true, AM.SymbolFlags);
else
Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i32);
@@ -777,7 +777,7 @@ bool X86DAGToDAGISel::MatchWrapper(SDValue N, X86ISelAddressMode &AM) {
AM.SymbolFlags = J->getTargetFlags();
} else {
AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress();
- //AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags();
+ AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags();
}
if (N.getOpcode() == X86ISD::WrapperRIP)
@@ -808,7 +808,7 @@ bool X86DAGToDAGISel::MatchWrapper(SDValue N, X86ISelAddressMode &AM) {
AM.SymbolFlags = J->getTargetFlags();
} else {
AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress();
- //AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags();
+ AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags();
}
return false;
}
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 6018cf5..a149ca4 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -4722,18 +4722,27 @@ X86TargetLowering::LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) {
SDValue
X86TargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) {
- unsigned WrapperKind = X86ISD::Wrapper;
+ // Create the TargetBlockAddressAddress node.
+ unsigned char OpFlags =
+ Subtarget->ClassifyBlockAddressReference();
CodeModel::Model M = getTargetMachine().getCodeModel();
+ BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
+ DebugLoc dl = Op.getDebugLoc();
+ SDValue Result = DAG.getBlockAddress(BA, getPointerTy(),
+ /*isTarget=*/true, OpFlags);
+
if (Subtarget->isPICStyleRIPRel() &&
(M == CodeModel::Small || M == CodeModel::Kernel))
- WrapperKind = X86ISD::WrapperRIP;
-
- DebugLoc DL = Op.getDebugLoc();
-
- BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
- SDValue Result = DAG.getBlockAddress(BA, DL, /*isTarget=*/true);
+ Result = DAG.getNode(X86ISD::WrapperRIP, dl, getPointerTy(), Result);
+ else
+ Result = DAG.getNode(X86ISD::Wrapper, dl, getPointerTy(), Result);
- Result = DAG.getNode(WrapperKind, DL, getPointerTy(), Result);
+ // With PIC, the address is actually $g + Offset.
+ if (isGlobalRelativeToPICBase(OpFlags)) {
+ Result = DAG.getNode(ISD::ADD, dl, getPointerTy(),
+ DAG.getNode(X86ISD::GlobalBaseReg, dl, getPointerTy()),
+ Result);
+ }
return Result;
}
diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp
index b901c14..661f560 100644
--- a/lib/Target/X86/X86Subtarget.cpp
+++ b/lib/Target/X86/X86Subtarget.cpp
@@ -28,6 +28,21 @@ using namespace llvm;
#include <intrin.h>
#endif
+/// ClassifyBlockAddressReference - Classify a blockaddress reference for the
+/// current subtarget according to how we should reference it in a non-pcrel
+/// context.
+unsigned char X86Subtarget::
+ClassifyBlockAddressReference() const {
+ if (isPICStyleGOT()) // 32-bit ELF targets.
+ return X86II::MO_GOTOFF;
+
+ if (isPICStyleStubPIC()) // Darwin/32 in PIC mode.
+ return X86II::MO_PIC_BASE_OFFSET;
+
+ // Direct static reference to label.
+ return X86II::MO_NO_FLAG;
+}
+
/// ClassifyGlobalReference - Classify a global variable reference for the
/// current subtarget according to how we should reference it in a non-pcrel
/// context.
diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h
index 23f2841..fb457dd 100644
--- a/lib/Target/X86/X86Subtarget.h
+++ b/lib/Target/X86/X86Subtarget.h
@@ -199,6 +199,11 @@ public:
unsigned char ClassifyGlobalReference(const GlobalValue *GV,
const TargetMachine &TM)const;
+ /// ClassifyBlockAddressReference - Classify a blockaddress reference for the
+ /// current subtarget according to how we should reference it in a non-pcrel
+ /// context.
+ unsigned char ClassifyBlockAddressReference() const;
+
/// IsLegalToCallImmediateAddr - Return true if the subtarget allows calls
/// to immediate address.
bool IsLegalToCallImmediateAddr(const TargetMachine &TM) const;
diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp
index 00dcce6..8f4886c 100644
--- a/lib/Target/XCore/XCoreISelLowering.cpp
+++ b/lib/Target/XCore/XCoreISelLowering.cpp
@@ -295,7 +295,7 @@ LowerBlockAddress(SDValue Op, SelectionDAG &DAG)
DebugLoc DL = Op.getDebugLoc();
BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
- SDValue Result = DAG.getBlockAddress(BA, DL, /*isTarget=*/true);
+ SDValue Result = DAG.getBlockAddress(BA, getPointerTy(), /*isTarget=*/true);
return DAG.getNode(XCoreISD::PCRelativeWrapper, DL, getPointerTy(), Result);
}