aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/X86/X86ISelDAGToDAG.cpp24
-rw-r--r--lib/Target/X86/X86InstrInfo.td2
2 files changed, 25 insertions, 1 deletions
diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp
index f58ca60ed9..422b195915 100644
--- a/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -392,6 +392,30 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
}
break;
}
+
+ case ISD::OR: {
+ if (!Available) {
+ X86ISelAddressMode Backup = AM;
+ // Look for (x << c1) | c2 where (c2 < c1)
+ ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.Val->getOperand(0));
+ if (CN && !MatchAddress(N.Val->getOperand(1), AM, false)) {
+ if (AM.GV == NULL && AM.Disp == 0 && CN->getValue() < AM.Scale) {
+ AM.Disp = CN->getValue();
+ return false;
+ }
+ }
+ AM = Backup;
+ CN = dyn_cast<ConstantSDNode>(N.Val->getOperand(1));
+ if (CN && !MatchAddress(N.Val->getOperand(0), AM, false)) {
+ if (AM.GV == NULL && AM.Disp == 0 && CN->getValue() < AM.Scale) {
+ AM.Disp = CN->getValue();
+ return false;
+ }
+ }
+ AM = Backup;
+ }
+ break;
+ }
}
// Is the base register already occupied?
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index de1c3a1ff4..d222bead62 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -133,7 +133,7 @@ def brtarget : Operand<OtherVT>;
// Define X86 specific addressing mode.
def addr : ComplexPattern<iPTR, 4, "SelectAddr", []>;
def leaaddr : ComplexPattern<iPTR, 4, "SelectLEAAddr",
- [add, mul, shl, frameindex]>;
+ [add, mul, shl, or, frameindex]>;
//===----------------------------------------------------------------------===//
// X86 Instruction Format Definitions.