summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMISelLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/ARM/ARMISelLowering.cpp')
-rw-r--r--llvm/lib/Target/ARM/ARMISelLowering.cpp22
1 files changed, 18 insertions, 4 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 03d0b7e2a74..8d04f59b95c 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -12383,6 +12383,21 @@ bool ARMTargetLowering::isLegalT2ScaledAddressingMode(const AddrMode &AM,
}
}
+bool ARMTargetLowering::isLegalT1ScaledAddressingMode(const AddrMode &AM,
+ EVT VT) const {
+ const int Scale = AM.Scale;
+
+ // Negative scales are not supported in Thumb1.
+ if (Scale < 0)
+ return false;
+
+ // Thumb1 addressing modes do not support register scaling excepting the
+ // following cases:
+ // 1. Scale == 1 means no scaling.
+ // 2. Scale == 2 this can be lowered to r + r if there is no base register.
+ return (Scale == 1) || (!AM.HasBaseReg && Scale == 2);
+}
+
/// 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 DataLayout &DL,
@@ -12399,10 +12414,6 @@ bool ARMTargetLowering::isLegalAddressingMode(const DataLayout &DL,
switch (AM.Scale) {
case 0: // no scale reg, must be "r+i" or "r", or "i".
break;
- case 1:
- if (Subtarget->isThumb1Only())
- return false;
- LLVM_FALLTHROUGH;
default:
// ARM doesn't support any R+R*scale+imm addr modes.
if (AM.BaseOffs)
@@ -12411,6 +12422,9 @@ bool ARMTargetLowering::isLegalAddressingMode(const DataLayout &DL,
if (!VT.isSimple())
return false;
+ if (Subtarget->isThumb1Only())
+ return isLegalT1ScaledAddressingMode(AM, VT);
+
if (Subtarget->isThumb2())
return isLegalT2ScaledAddressingMode(AM, VT);
OpenPOWER on IntegriCloud