diff options
Diffstat (limited to 'llvm/lib/Target/ARM')
| -rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.cpp | 38 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.h | 4 |
2 files changed, 42 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index c646e54b580..bf6d22414e8 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -1281,6 +1281,44 @@ ARMTargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, // ARM Optimization Hooks //===----------------------------------------------------------------------===// +/// isLegalAddressingMode - Return true if the addressing mode represented +/// by AM is legal for this target, for a load/store of the specified type. +bool ARMTargetLowering::isLegalAddressingMode(const AddrMode &AM, + const Type *Ty) const { + if (!isLegalAddressImmediate(AM.BaseOffs, Ty)) + return false; + + // Can never fold addr of global into load/store. + if (AM.BaseGV) + return false; + + switch (AM.Scale) { + case 0: // no scale reg, must be "r+i" or "r", or "i". + break; + case 1: + if (Subtarget->isThumb()) + return false; + + default: + // FIXME: verify. + switch (getValueType(Ty)) { + default: return false; + case MVT::i1: + case MVT::i8: + // TODO: i16? i64 should be i32, no? + case MVT::i32: + // r + r + if (AM.Scale == 2) + return true; + // r + r << imm + if (!isPowerOf2_32(AM.Scale & ~1)) + return false; + } + break; + } + return true; +} + /// 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. diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h index 74790191d76..8846decd9bf 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.h +++ b/llvm/lib/Target/ARM/ARMISelLowering.h @@ -80,6 +80,10 @@ namespace llvm { virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI, MachineBasicBlock *MBB); + /// isLegalAddressingMode - Return true if the addressing mode represented + /// by AM is legal for this target, for a load/store of the specified type. + virtual bool isLegalAddressingMode(const AddrMode &AM, const Type *Ty)const; + /// 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. |

