diff options
| author | Chris Lattner <sabre@nondot.org> | 2005-01-11 19:37:02 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2005-01-11 19:37:02 +0000 |
| commit | 8cf9cdae3d3b1deb8e297b6efb9bfc718b0e3cd6 (patch) | |
| tree | b714e838a9eea646177de46ef0eb137b5a5984ac /llvm/lib | |
| parent | 870b872bfaa4778bd4ab7c86e7da3b3a22611340 (diff) | |
| download | bcm5719-llvm-8cf9cdae3d3b1deb8e297b6efb9bfc718b0e3cd6.tar.gz bcm5719-llvm-8cf9cdae3d3b1deb8e297b6efb9bfc718b0e3cd6.zip | |
Fold multiplies by 3,5,9 into addressing modes when possible.
llvm-svn: 19480
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelPattern.cpp | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86ISelPattern.cpp b/llvm/lib/Target/X86/X86ISelPattern.cpp index 40e4c414ff9..5d072ba301b 100644 --- a/llvm/lib/Target/X86/X86ISelPattern.cpp +++ b/llvm/lib/Target/X86/X86ISelPattern.cpp @@ -447,6 +447,34 @@ bool ISel::SelectAddress(SDOperand N, X86AddressMode &AM) { } } break; + case ISD::MUL: + // X*[3,5,9] -> X+X*[2,4,8] + if (AM.IndexReg == 0 && AM.BaseType == X86AddressMode::RegBase && + AM.Base.Reg == 0) + if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.Val->getOperand(1))) + if (CN->getValue() == 3 || CN->getValue() == 5 || CN->getValue() == 9) { + AM.Scale = unsigned(CN->getValue())-1; + + SDOperand MulVal = N.Val->getOperand(0); + unsigned Reg; + + // Okay, we know that we have a scale by now. However, if the scaled + // value is an add of something and a constant, we can fold the + // constant into the disp field here. + if (MulVal.Val->getOpcode() == ISD::ADD && + isa<ConstantSDNode>(MulVal.Val->getOperand(1))) { + Reg = SelectExpr(MulVal.Val->getOperand(0)); + ConstantSDNode *AddVal = + cast<ConstantSDNode>(MulVal.Val->getOperand(1)); + AM.Disp += AddVal->getValue() * CN->getValue(); + } else { + Reg = SelectExpr(N.Val->getOperand(0)); + } + + AM.IndexReg = AM.Base.Reg = Reg; + return false; + } + break; case ISD::ADD: { X86AddressMode Backup = AM; |

