[llvm-commits] [llvm] r79032 - in /llvm/trunk/lib/Target/ARM: ARMISelLowering.cpp ARMISelLowering.h
Evan Cheng
evan.cheng at apple.com
Fri Aug 14 13:09:37 PDT 2009
Author: evancheng
Date: Fri Aug 14 15:09:37 2009
New Revision: 79032
URL: http://llvm.org/viewvc/llvm-project?rev=79032&view=rev
Log:
Add Thumb2 lsr hooks.
Modified:
llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
llvm/trunk/lib/Target/ARM/ARMISelLowering.h
Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=79032&r1=79031&r2=79032&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Aug 14 15:09:37 2009
@@ -3119,6 +3119,63 @@
return SDValue();
}
+static bool isLegalT1AddressImmediate(int64_t V, EVT VT) {
+ if (V < 0)
+ return false;
+
+ unsigned Scale = 1;
+ switch (VT.getSimpleVT().SimpleTy) {
+ 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));
+}
+
+static bool isLegalT2AddressImmediate(int64_t V, EVT VT,
+ const ARMSubtarget *Subtarget) {
+ bool isNeg = false;
+ if (V < 0) {
+ isNeg = true;
+ V = - V;
+ }
+
+ switch (VT.getSimpleVT().SimpleTy) {
+ default: return false;
+ case MVT::i1:
+ case MVT::i8:
+ case MVT::i16:
+ case MVT::i32:
+ // + 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));
+ }
+}
+
/// 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.
@@ -3130,33 +3187,12 @@
if (!VT.isSimple())
return false;
- if (Subtarget->isThumb()) { // FIXME for thumb2
- if (V < 0)
- return false;
-
- unsigned Scale = 1;
- switch (VT.getSimpleVT().SimpleTy) {
- 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 (Subtarget->isThumb1Only())
+ return isLegalT1AddressImmediate(V, VT);
+ else if (Subtarget->isThumb2())
+ return isLegalT2AddressImmediate(V, VT, Subtarget);
+ // ARM mode.
if (V < 0)
V = - V;
switch (VT.getSimpleVT().SimpleTy) {
@@ -3171,7 +3207,7 @@
return V == (V & ((1LL << 8) - 1));
case MVT::f32:
case MVT::f64:
- if (!Subtarget->hasVFP2())
+ if (!Subtarget->hasVFP2()) // FIXME: NEON?
return false;
if ((V & 3) != 0)
return false;
@@ -3180,6 +3216,39 @@
}
}
+bool ARMTargetLowering::isLegalT2ScaledAddressingMode(const AddrMode &AM,
+ EVT VT) const {
+ int Scale = AM.Scale;
+ if (Scale < 0)
+ return false;
+
+ switch (VT.getSimpleVT().SimpleTy) {
+ default: return false;
+ case MVT::i1:
+ case MVT::i8:
+ case MVT::i16:
+ case MVT::i32:
+ if (Scale == 1)
+ return true;
+ // r + r << imm
+ Scale = Scale & ~1;
+ return Scale == 2 || Scale == 4 || Scale == 8;
+ case MVT::i64:
+ // r + r
+ if (((unsigned)AM.HasBaseReg + Scale) <= 2)
+ return true;
+ return false;
+ case MVT::isVoid:
+ // Note, we allow "void" uses (basically, uses that aren't loads or
+ // stores), because arm allows folding a scale into many arithmetic
+ // operations. This should be made more precise and revisited later.
+
+ // Allow r << imm, but the imm has to be a multiple of two.
+ if (Scale & 1) return false;
+ return isPowerOf2_32(Scale);
+ }
+}
+
/// 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,
@@ -3196,7 +3265,7 @@
case 0: // no scale reg, must be "r+i" or "r", or "i".
break;
case 1:
- if (Subtarget->isThumb()) // FIXME for thumb2
+ if (Subtarget->isThumb1Only())
return false;
// FALL THROUGH.
default:
@@ -3207,22 +3276,22 @@
if (!VT.isSimple())
return false;
+ if (Subtarget->isThumb2())
+ return isLegalT2ScaledAddressingMode(AM, VT);
+
int Scale = AM.Scale;
switch (VT.getSimpleVT().SimpleTy) {
default: return false;
case MVT::i1:
case MVT::i8:
case MVT::i32:
- case MVT::i64:
- // This assumes i64 is legalized to a pair of i32. If not (i.e.
- // ldrd / strd are used, then its address mode is same as i16.
- // r + r
if (Scale < 0) Scale = -Scale;
if (Scale == 1)
return true;
// r + r << imm
return isPowerOf2_32(Scale & ~1);
case MVT::i16:
+ case MVT::i64:
// r + r
if (((unsigned)AM.HasBaseReg + Scale) <= 2)
return true;
@@ -3234,8 +3303,8 @@
// operations. This should be made more precise and revisited later.
// Allow r << imm, but the imm has to be a multiple of two.
- if (AM.Scale & 1) return false;
- return isPowerOf2_32(AM.Scale);
+ if (Scale & 1) return false;
+ return isPowerOf2_32(Scale);
}
break;
}
@@ -3351,7 +3420,7 @@
bool isInc;
bool isLegal = false;
- if (Subtarget->isThumb() && Subtarget->hasThumb2())
+ if (Subtarget->isThumb2())
isLegal = getT2IndexedAddressParts(Ptr.getNode(), VT, isSEXTLoad, Base,
Offset, isInc, DAG);
else
@@ -3388,7 +3457,7 @@
bool isInc;
bool isLegal = false;
- if (Subtarget->isThumb() && Subtarget->hasThumb2())
+ if (Subtarget->isThumb2())
isLegal = getT2IndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
isInc, DAG);
else
Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=79032&r1=79031&r2=79032&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Fri Aug 14 15:09:37 2009
@@ -169,6 +169,7 @@
/// 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;
+ bool isLegalT2ScaledAddressingMode(const AddrMode &AM, EVT VT) const;
/// getPreIndexedAddressParts - returns true by value, base pointer and
/// offset pointer and addressing mode by reference if the node's address
More information about the llvm-commits
mailing list