summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorDavid Green <david.green@arm.com>2019-04-21 09:54:29 +0000
committerDavid Green <david.green@arm.com>2019-04-21 09:54:29 +0000
commit0d741507f7ec1cb8925ed2c37408a1b0db079332 (patch)
tree145db7fababda9e25bb8e344e61716937aebbe0d /llvm/lib/Target
parentdf02beb4165d3c07842878c6ed104622925be35b (diff)
downloadbcm5719-llvm-0d741507f7ec1cb8925ed2c37408a1b0db079332.tar.gz
bcm5719-llvm-0d741507f7ec1cb8925ed2c37408a1b0db079332.zip
[ARM] Rewrite isLegalT2AddressImmediate
This does two main things, firstly adding some at least basic addressing modes for i64 types, and secondly treats floats and doubles sensibly when there is no fpu. The floating point change can help codesize in some cases, especially with D60294. Most backends seems to not consider the exact VT in isLegalAddressingMode, instead switching on type size. That is now what this does when the target does not have an fpu (as the float data will be loaded using LDR's). i64's currently use the address range of an LDRD (even though they may be legalised and loaded with an LDR). This is at least better than marking them all as illegal addressing modes. I have not attempted to do much with vectors yet. That will need changing once MVE is added. Differential Revision: https://reviews.llvm.org/D60677 llvm-svn: 358845
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/ARM/ARMISelLowering.cpp53
1 files changed, 24 insertions, 29 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 0281d68fcfd..8a9792c8ee1 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -13289,38 +13289,36 @@ static bool isLegalT1AddressImmediate(int64_t V, EVT VT) {
if ((V & (Scale - 1)) != 0)
return false;
- V /= Scale;
- return V == (V & ((1LL << 5) - 1));
+ return isUInt<5>(V / Scale);
}
static bool isLegalT2AddressImmediate(int64_t V, EVT VT,
const ARMSubtarget *Subtarget) {
- bool isNeg = false;
+ if (!VT.isInteger() && !VT.isFloatingPoint())
+ return false;
+ if (Subtarget->hasNEON() && VT.isVector())
+ return false;
+
+ bool IsNeg = false;
if (V < 0) {
- isNeg = true;
- V = - V;
+ IsNeg = true;
+ V = -V;
}
- switch (VT.getSimpleVT().SimpleTy) {
- default: return false;
- case MVT::i1:
- case MVT::i8:
- case MVT::i16:
- case MVT::i32:
+ unsigned NumBytes = std::max(VT.getSizeInBits() / 8, 1U);
+
+ // VLDR and LDRD: 4 * imm8
+ if ((VT.isFloatingPoint() && Subtarget->hasVFP2()) || NumBytes == 8)
+ return isShiftedUInt<8, 2>(V);
+
+ if (NumBytes == 1 || NumBytes == 2 || NumBytes == 4) {
// + imm12 or - imm8
- if (isNeg)
- return V == (V & ((1LL << 8) - 1));
- return V == (V & ((1LL << 12) - 1));
- case MVT::f32:
- case MVT::f64:
- // Same as ARM mode. FIXME: NEON?
- if (!Subtarget->hasVFP2())
- return false;
- if ((V & 3) != 0)
- return false;
- V >>= 2;
- return V == (V & ((1LL << 8) - 1));
+ if (IsNeg)
+ return isUInt<8>(V);
+ return isUInt<12>(V);
}
+
+ return false;
}
/// isLegalAddressImmediate - Return true if the integer value can be used
@@ -13348,18 +13346,15 @@ static bool isLegalAddressImmediate(int64_t V, EVT VT,
case MVT::i8:
case MVT::i32:
// +- imm12
- return V == (V & ((1LL << 12) - 1));
+ return isUInt<12>(V);
case MVT::i16:
// +- imm8
- return V == (V & ((1LL << 8) - 1));
+ return isUInt<8>(V);
case MVT::f32:
case MVT::f64:
if (!Subtarget->hasVFP2()) // FIXME: NEON?
return false;
- if ((V & 3) != 0)
- return false;
- V >>= 2;
- return V == (V & ((1LL << 8) - 1));
+ return isShiftedUInt<8, 2>(V);
}
}
OpenPOWER on IntegriCloud