diff options
author | Evan Cheng <evan.cheng@apple.com> | 2007-03-12 23:30:29 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2007-03-12 23:30:29 +0000 |
commit | b01fad6d19ac83f9c97eee16af438507383f36d8 (patch) | |
tree | 276ac645144d5dc2a7d23a2a42ae1805f626fb3b /lib/Target/ARM/ARMISelLowering.cpp | |
parent | 861939152debbaa15a55a196a4321837c7bc379d (diff) | |
download | llvm-b01fad6d19ac83f9c97eee16af438507383f36d8.tar.gz llvm-b01fad6d19ac83f9c97eee16af438507383f36d8.tar.bz2 llvm-b01fad6d19ac83f9c97eee16af438507383f36d8.tar.xz |
Updated TargetLowering LSR addressing mode hooks for ARM and Thumb.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35075 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/ARMISelLowering.cpp')
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 81 |
1 files changed, 76 insertions, 5 deletions
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 55f5c976ce..2038a3e3ae 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -30,6 +30,7 @@ #include "llvm/CodeGen/SSARegMap.h" #include "llvm/Target/TargetOptions.h" #include "llvm/ADT/VectorExtras.h" +#include "llvm/Support/MathExtras.h" using namespace llvm; ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) @@ -1268,17 +1269,87 @@ ARMTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, // ARM Optimization Hooks //===----------------------------------------------------------------------===// -/// isLegalAddressImmediate - Return true if the integer value or -/// GlobalValue can be used as the offset of the target addressing mode. -bool ARMTargetLowering::isLegalAddressImmediate(int64_t V) const { - // ARM allows a 12-bit immediate field. - return V == V & ((1LL << 12) - 1); +/// isLegalAddressImmediate - Return true if the integer value can be used +/// as the offset of the target addressing mode for load / store of the +/// given type. +bool ARMTargetLowering::isLegalAddressImmediate(int64_t V,const Type *Ty) const{ + MVT::ValueType VT = getValueType(Ty); + if (Subtarget->isThumb()) { + if (V < 0) + return false; + + unsigned Scale = 1; + switch (VT) { + default: return false; + case MVT::i1: + case MVT::i8: + // Scale == 1; + break; + case MVT::i16: + // Scale == 2; + Scale = 2; + break; + case MVT::i32: + // Scale == 4; + Scale = 4; + break; + } + + if ((V & (Scale - 1)) != 0) + return false; + V /= Scale; + return V == V & ((1LL << 5) - 1); + } + + if (V < 0) + V = - V; + switch (VT) { + default: return false; + case MVT::i1: + case MVT::i8: + case MVT::i32: + // +- imm12 + return V == V & ((1LL << 12) - 1); + case MVT::i16: + // +- imm8 + return V == V & ((1LL << 8) - 1); + case MVT::f32: + case MVT::f64: + if (!Subtarget->hasVFP2()) + return false; + if ((V % 3) != 0) + return false; + V >>= 2; + return V == V & ((1LL << 8) - 1); + } } bool ARMTargetLowering::isLegalAddressImmediate(GlobalValue *GV) const { return false; } +/// isLegalAddressScale - Return true if the integer value can be used as +/// the scale of the target addressing mode for load / store of the given +/// type. +bool ARMTargetLowering::isLegalAddressScale(int64_t S, const Type *Ty) const { + if (Subtarget->isThumb()) + return false; + + MVT::ValueType VT = getValueType(Ty); + switch (VT) { + default: return false; + case MVT::i1: + case MVT::i8: + case MVT::i32: + // r + r + if (S == 2) + return true; + // r + r << imm + S &= ~1; + return isPowerOf2_32(S); + } +} + static bool getIndexedAddressParts(SDNode *Ptr, MVT::ValueType VT, bool isSEXTLoad, SDOperand &Base, SDOperand &Offset, bool &isInc, |