aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/X86
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2005-12-12 21:49:40 +0000
committerEvan Cheng <evan.cheng@apple.com>2005-12-12 21:49:40 +0000
commite5280536a3b9f7169b3a5ef3460c8ee4bd324709 (patch)
treec3bc56c2d027e855516d166b1551883faa9e424e /lib/Target/X86
parentcbd6ed4d6bd4b48a4344691ad60d441382f85b37 (diff)
downloadexternal_llvm-e5280536a3b9f7169b3a5ef3460c8ee4bd324709.zip
external_llvm-e5280536a3b9f7169b3a5ef3460c8ee4bd324709.tar.gz
external_llvm-e5280536a3b9f7169b3a5ef3460c8ee4bd324709.tar.bz2
When SelectLEAAddr() fails, it shouldn't cause the side effect of having the
base or index operands being selected. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24674 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/X86')
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp65
1 files changed, 48 insertions, 17 deletions
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index 03f56eb..33dc159 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -101,6 +101,17 @@ namespace {
bool SelectLEAAddr(SDOperand N, SDOperand &Base, SDOperand &Scale,
SDOperand &Index, SDOperand &Disp);
+ inline void getAddressOperands(X86ISelAddressMode &AM, SDOperand &Base,
+ SDOperand &Scale, SDOperand &Index,
+ SDOperand &Disp) {
+ Base = (AM.BaseType == X86ISelAddressMode::FrameIndexBase) ?
+ CurDAG->getTargetFrameIndex(AM.Base.FrameIndex, MVT::i32) : AM.Base.Reg;
+ Scale = getI8Imm (AM.Scale);
+ Index = AM.IndexReg;
+ Disp = AM.GV ? CurDAG->getTargetGlobalAddress(AM.GV, MVT::i32, AM.Disp)
+ : getI32Imm(AM.Disp);
+ }
+
/// getI8Imm - Return a target constant with the specified value, of type
/// i8.
inline SDOperand getI8Imm(unsigned Imm) {
@@ -285,12 +296,7 @@ bool X86DAGToDAGISel::SelectAddr(SDOperand N, SDOperand &Base, SDOperand &Scale,
else
AM.IndexReg = CurDAG->getRegister(0, MVT::i32);
- Base = (AM.BaseType == X86ISelAddressMode::FrameIndexBase) ?
- CurDAG->getTargetFrameIndex(AM.Base.FrameIndex, MVT::i32) : AM.Base.Reg;
- Scale = getI8Imm (AM.Scale);
- Index = AM.IndexReg;
- Disp = AM.GV ? CurDAG->getTargetGlobalAddress(AM.GV, MVT::i32, AM.Disp)
- : getI32Imm(AM.Disp);
+ getAddressOperands(AM, Base, Scale, Index, Disp);
return true;
}
return false;
@@ -308,24 +314,49 @@ static bool isRegister0(SDOperand Op)
/// For X86, it always is unless it's just a (Reg + const).
bool X86DAGToDAGISel::SelectLEAAddr(SDOperand N, SDOperand &Base, SDOperand &Scale,
SDOperand &Index, SDOperand &Disp) {
- if (SelectAddr(N, Base, Scale, Index, Disp)) {
- if (!isRegister0(Base)) {
+ X86ISelAddressMode AM;
+ if (!MatchAddress(N, AM)) {
+ bool SelectBase = false;
+ bool SelectIndex = false;
+ bool Check = false;
+ if (AM.BaseType == X86ISelAddressMode::RegBase) {
+ if (AM.Base.Reg.Val) {
+ Check = true;
+ SelectBase = true;
+ } else {
+ AM.Base.Reg = CurDAG->getRegister(0, MVT::i32);
+ }
+ }
+
+ if (AM.IndexReg.Val) {
+ SelectIndex = true;
+ } else {
+ AM.IndexReg = CurDAG->getRegister(0, MVT::i32);
+ }
+
+ if (Check) {
unsigned Complexity = 0;
- if ((unsigned)cast<ConstantSDNode>(Scale)->getValue() > 1)
+ if (AM.Scale > 1)
Complexity++;
- if (!isRegister0(Index))
+ if (SelectIndex)
Complexity++;
- if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Disp)) {
- if (!CN->isNullValue()) Complexity++;
- } else {
+ if (AM.GV)
Complexity++;
- }
- return (Complexity > 1);
+ else if (AM.Disp > 1)
+ Complexity++;
+ if (Complexity <= 1)
+ return false;
}
+
+ if (SelectBase)
+ AM.Base.Reg = Select(AM.Base.Reg);
+ if (SelectIndex)
+ AM.IndexReg = Select(AM.IndexReg);
+
+ getAddressOperands(AM, Base, Scale, Index, Disp);
return true;
- } else {
- return false;
}
+ return false;
}
SDOperand X86DAGToDAGISel::Select(SDOperand Op) {