aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2006-11-30 21:55:46 +0000
committerEvan Cheng <evan.cheng@apple.com>2006-11-30 21:55:46 +0000
commit0085a28d13f86b09ba0c83e8dce81de3ba15ca2d (patch)
treed363295ef89d8a6718e907c7763fc4cebcca4cd8 /lib/Target
parent2bbff6d17350edae5d9ae48b3f0735386d69cccf (diff)
downloadexternal_llvm-0085a28d13f86b09ba0c83e8dce81de3ba15ca2d.zip
external_llvm-0085a28d13f86b09ba0c83e8dce81de3ba15ca2d.tar.gz
external_llvm-0085a28d13f86b09ba0c83e8dce81de3ba15ca2d.tar.bz2
- Use a different wrapper node for RIP-relative GV, etc.
- Proper support for both small static and PIC modes under X86-64 - Some (non-optimal) support for medium modes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32046 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp64
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp43
-rw-r--r--lib/Target/X86/X86ISelLowering.h4
-rw-r--r--lib/Target/X86/X86InstrInfo.td5
-rw-r--r--lib/Target/X86/X86InstrX86-64.td27
5 files changed, 81 insertions, 62 deletions
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index 09f07d0..19df6e9 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -590,63 +590,19 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
break;
}
- case ISD::TargetConstantPool:
- if (AM.BaseType == X86ISelAddressMode::RegBase &&
- AM.Base.Reg.Val == 0 &&
- AM.CP == 0) {
- ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(N);
- AM.CP = CP->getConstVal();
- AM.Align = CP->getAlignment();
- AM.Disp += CP->getOffset();
- return false;
- }
- break;
-
- case ISD::TargetGlobalAddress:
- if (AM.BaseType == X86ISelAddressMode::RegBase &&
- AM.Base.Reg.Val == 0 &&
- AM.GV == 0) {
- GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(N);
- AM.GV = G->getGlobal();
- AM.Disp += G->getOffset();
- return false;
- }
- break;
-
- case ISD::TargetExternalSymbol:
- if (isRoot &&
- AM.BaseType == X86ISelAddressMode::RegBase &&
- AM.Base.Reg.Val == 0) {
- ExternalSymbolSDNode *S = cast<ExternalSymbolSDNode>(N.getOperand(0));
- AM.ES = S->getSymbol();
- return false;
- }
- break;
-
- case ISD::TargetJumpTable:
- if (isRoot &&
- AM.BaseType == X86ISelAddressMode::RegBase &&
- AM.Base.Reg.Val == 0) {
- JumpTableSDNode *J = cast<JumpTableSDNode>(N.getOperand(0));
- AM.JT = J->getIndex();
- return false;
- }
- break;
-
case X86ISD::Wrapper:
+ case X86ISD::WrapperRIP: {
+ bool isRIP = N.getOpcode() == X86ISD::WrapperRIP;
+ // Under X86-64 non-small code model, GV (and friends) are 64-bits.
+ if (!isRIP && Subtarget->is64Bit() && TM.getCodeModel() != CodeModel::Small)
+ break;
+
// If value is available in a register both base and index components have
// been picked, we can't fit the result available in the register in the
// addressing mode. Duplicate GlobalAddress or ConstantPool as displacement.
-
- // Can't fit GV or CP in addressing mode for X86-64 medium or large code
- // model since the displacement field is 32-bit. Ok for small code model.
-
- // For X86-64 PIC code, only allow GV / CP + displacement so we can use RIP
- // relative addressing mode.
- if (Subtarget->is64Bit() && TM.getCodeModel() != CodeModel::Small)
- break;
if (!Available || (AM.Base.Reg.Val && AM.IndexReg.Val)) {
- bool isRIP = Subtarget->is64Bit();
+ // For X86-64 PIC code, only allow GV / CP + displacement so we can use
+ // RIP relative addressing mode.
if (isRIP &&
(AM.Base.Reg.Val || AM.Scale > 1 || AM.IndexReg.Val ||
AM.BaseType == X86ISelAddressMode::FrameIndexBase))
@@ -683,6 +639,7 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
}
}
break;
+ }
case ISD::FrameIndex:
if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base.Reg.Val == 0) {
@@ -1040,7 +997,8 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
SDOperand N0 = N.getOperand(0);
SDOperand N1 = N.getOperand(1);
if (N.Val->getValueType(0) == PtrVT &&
- N0.getOpcode() == X86ISD::Wrapper &&
+ (N0.getOpcode() == X86ISD::Wrapper
+ || N0.getOpcode() == X86ISD::WrapperRIP) &&
N1.getOpcode() == ISD::Constant) {
unsigned Offset = (unsigned)cast<ConstantSDNode>(N1)->getValue();
SDOperand C(0, 0);
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 1e3530f..375777a 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -3832,8 +3832,15 @@ X86TargetLowering::LowerConstantPool(SDOperand Op, SelectionDAG &DAG) {
SDOperand Result = DAG.getTargetConstantPool(CP->getConstVal(),
getPointerTy(),
CP->getAlignment());
+ // Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode.
+ TargetMachine &tm = getTargetMachine();
+ unsigned WrapperOpcode = (Subtarget->is64Bit() &&
+ (tm.getCodeModel() == CodeModel::Small ||
+ tm.getCodeModel() == CodeModel::Medium) &&
+ tm.getRelocationModel() == Reloc::PIC_)
+ ? X86ISD::WrapperRIP : X86ISD::Wrapper;
+ Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result);
if (Subtarget->isTargetDarwin()) {
- Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
// With PIC, the address is actually $g + Offset.
if (!Subtarget->is64Bit() &&
getTargetMachine().getRelocationModel() == Reloc::PIC_)
@@ -3848,8 +3855,15 @@ SDOperand
X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
SDOperand Result = DAG.getTargetGlobalAddress(GV, getPointerTy());
+ // Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode.
+ TargetMachine &tm = getTargetMachine();
+ unsigned WrapperOpcode = (Subtarget->is64Bit() &&
+ (tm.getCodeModel() == CodeModel::Small ||
+ tm.getCodeModel() == CodeModel::Medium) &&
+ tm.getRelocationModel() == Reloc::PIC_)
+ ? X86ISD::WrapperRIP : X86ISD::Wrapper;
+ Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result);
if (Subtarget->isTargetDarwin()) {
- Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
// With PIC, the address is actually $g + Offset.
if (!Subtarget->is64Bit() &&
getTargetMachine().getRelocationModel() == Reloc::PIC_)
@@ -3865,7 +3879,6 @@ X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
Subtarget->GVRequiresExtraLoad(GV, false))
Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0);
} else if (Subtarget->GVRequiresExtraLoad(GV, false)) {
- Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0);
}
@@ -3876,8 +3889,15 @@ SDOperand
X86TargetLowering::LowerExternalSymbol(SDOperand Op, SelectionDAG &DAG) {
const char *Sym = cast<ExternalSymbolSDNode>(Op)->getSymbol();
SDOperand Result = DAG.getTargetExternalSymbol(Sym, getPointerTy());
+ // Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode.
+ TargetMachine &tm = getTargetMachine();
+ unsigned WrapperOpcode = (Subtarget->is64Bit() &&
+ (tm.getCodeModel() == CodeModel::Small ||
+ tm.getCodeModel() == CodeModel::Medium) &&
+ tm.getRelocationModel() == Reloc::PIC_)
+ ? X86ISD::WrapperRIP : X86ISD::Wrapper;
+ Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result);
if (Subtarget->isTargetDarwin()) {
- Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
// With PIC, the address is actually $g + Offset.
if (!Subtarget->is64Bit() &&
getTargetMachine().getRelocationModel() == Reloc::PIC_)
@@ -4244,8 +4264,15 @@ SDOperand X86TargetLowering::LowerBRCOND(SDOperand Op, SelectionDAG &DAG) {
SDOperand X86TargetLowering::LowerJumpTable(SDOperand Op, SelectionDAG &DAG) {
JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
SDOperand Result = DAG.getTargetJumpTable(JT->getIndex(), getPointerTy());
+ // Use X86ISD::WrapperRIP if we are in X86-64 small / medium PIC mode.
+ TargetMachine &tm = getTargetMachine();
+ unsigned WrapperOpcode = (Subtarget->is64Bit() &&
+ (tm.getCodeModel() == CodeModel::Small ||
+ tm.getCodeModel() == CodeModel::Medium) &&
+ tm.getRelocationModel() == Reloc::PIC_)
+ ? X86ISD::WrapperRIP : X86ISD::Wrapper;
+ Result = DAG.getNode(WrapperOpcode, getPointerTy(), Result);
if (Subtarget->isTargetDarwin()) {
- Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
// With PIC, the address is actually $g + Offset.
if (!Subtarget->is64Bit() &&
getTargetMachine().getRelocationModel() == Reloc::PIC_)
@@ -4978,6 +5005,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
case X86ISD::LOAD_UA: return "X86ISD::LOAD_UA";
case X86ISD::GlobalBaseReg: return "X86ISD::GlobalBaseReg";
case X86ISD::Wrapper: return "X86ISD::Wrapper";
+ case X86ISD::WrapperRIP: return "X86ISD::WrapperRIP";
case X86ISD::S2VEC: return "X86ISD::S2VEC";
case X86ISD::PEXTRW: return "X86ISD::PEXTRW";
case X86ISD::PINSRW: return "X86ISD::PINSRW";
@@ -5220,12 +5248,13 @@ static SDOperand getShuffleScalarElt(SDNode *N, unsigned i, SelectionDAG &DAG) {
/// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the
/// node is a GlobalAddress + an offset.
static bool isGAPlusOffset(SDNode *N, GlobalValue* &GA, int64_t &Offset) {
- if (N->getOpcode() == X86ISD::Wrapper) {
+ unsigned Opc = N->getOpcode();
+ if (Opc == X86ISD::Wrapper || Opc == X86ISD::WrapperRIP) {
if (dyn_cast<GlobalAddressSDNode>(N->getOperand(0))) {
GA = cast<GlobalAddressSDNode>(N->getOperand(0))->getGlobal();
return true;
}
- } else if (N->getOpcode() == ISD::ADD) {
+ } else if (Opc == ISD::ADD) {
SDOperand N1 = N->getOperand(0);
SDOperand N2 = N->getOperand(1);
if (isGAPlusOffset(N1.Val, GA, Offset)) {
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index f28b951..26c8f33 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -150,6 +150,10 @@ namespace llvm {
/// TargetExternalSymbol, and TargetGlobalAddress.
Wrapper,
+ /// WrapperRIP - Special wrapper used under X86-64 PIC mode for RIP
+ /// relative displacements.
+ WrapperRIP,
+
/// S2VEC - X86 version of SCALAR_TO_VECTOR. The destination base does not
/// have to match the operand type.
S2VEC,
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index f50553c..cb07abe 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -84,7 +84,8 @@ def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr,
def X86rdtsc : SDNode<"X86ISD::RDTSC_DAG",SDTX86RdTsc,
[SDNPHasChain, SDNPOutFlag]>;
-def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
+def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
+def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>;
//===----------------------------------------------------------------------===//
// X86 Operand Definitions.
@@ -169,6 +170,8 @@ def HasSSE3 : Predicate<"Subtarget->hasSSE3()">;
def FPStack : Predicate<"!Subtarget->hasSSE2()">;
def In32BitMode : Predicate<"!Subtarget->is64Bit()">;
def In64BitMode : Predicate<"Subtarget->is64Bit()">;
+def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;
+def NotSmallCode :Predicate<"TM.getCodeModel() != CodeModel::Small">;
//===----------------------------------------------------------------------===//
// X86 specific pattern fragments.
diff --git a/lib/Target/X86/X86InstrX86-64.td b/lib/Target/X86/X86InstrX86-64.td
index 0e024d1..0c49e94 100644
--- a/lib/Target/X86/X86InstrX86-64.td
+++ b/lib/Target/X86/X86InstrX86-64.td
@@ -36,7 +36,8 @@ def lea64_32mem : Operand<i32> {
// Complex Pattern Definitions...
//
def lea64addr : ComplexPattern<i64, 4, "SelectLEAAddr",
- [add, mul, shl, or, frameindex, X86Wrapper], []>;
+ [add, mul, shl, or, frameindex, X86WrapperRIP],
+ []>;
//===----------------------------------------------------------------------===//
// Instruction templates...
@@ -1020,6 +1021,30 @@ def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (ops GR64:$dst, i64i32imm:$src),
// Non-Instruction Patterns
//===----------------------------------------------------------------------===//
+// ConstantPool GlobalAddress, ExternalSymbol, and JumpTable
+def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
+ (MOV64ri32 tconstpool :$dst)>, Requires<[SmallCode]>;
+def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
+ (MOV64ri32 tjumptable :$dst)>, Requires<[SmallCode]>;
+def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
+ (MOV64ri32 tglobaladdr :$dst)>, Requires<[SmallCode]>;
+def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
+ (MOV64ri32 texternalsym:$dst)>, Requires<[SmallCode]>;
+
+def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
+ (MOV64ri tconstpool :$dst)>, Requires<[NotSmallCode]>;
+def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
+ (MOV64ri tjumptable :$dst)>, Requires<[NotSmallCode]>;
+def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
+ (MOV64ri tglobaladdr :$dst)>, Requires<[NotSmallCode]>;
+def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
+ (MOV64ri texternalsym:$dst)>, Requires<[NotSmallCode]>;
+
+def : Pat<(store (i64 (X86Wrapper tglobaladdr:$src)), addr:$dst),
+ (MOV64mi32 addr:$dst, tglobaladdr:$src)>, Requires<[SmallCode]>;
+def : Pat<(store (i64 (X86Wrapper texternalsym:$src)), addr:$dst),
+ (MOV64mi32 addr:$dst, texternalsym:$src)>, Requires<[SmallCode]>;
+
// Calls
// Direct PC relative function call for small code model. 32-bit displacement
// sign extended to 64-bit.