mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-19 06:31:18 +00:00
Add Thumb2 lsr hooks.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79032 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e44313e0ca
commit
e6c835f424
@ -3119,6 +3119,63 @@ SDValue ARMTargetLowering::PerformDAGCombine(SDNode *N,
|
||||
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 @@ static bool isLegalAddressImmediate(int64_t V, EVT VT,
|
||||
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 @@ static bool isLegalAddressImmediate(int64_t V, EVT VT,
|
||||
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 @@ static bool isLegalAddressImmediate(int64_t V, EVT VT,
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ bool ARMTargetLowering::isLegalAddressingMode(const AddrMode &AM,
|
||||
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 @@ bool ARMTargetLowering::isLegalAddressingMode(const AddrMode &AM,
|
||||
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 @@ bool ARMTargetLowering::isLegalAddressingMode(const AddrMode &AM,
|
||||
// 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 @@ ARMTargetLowering::getPreIndexedAddressParts(SDNode *N, SDValue &Base,
|
||||
|
||||
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 ARMTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
|
||||
|
||||
bool isInc;
|
||||
bool isLegal = false;
|
||||
if (Subtarget->isThumb() && Subtarget->hasThumb2())
|
||||
if (Subtarget->isThumb2())
|
||||
isLegal = getT2IndexedAddressParts(Op, VT, isSEXTLoad, Base, Offset,
|
||||
isInc, DAG);
|
||||
else
|
||||
|
@ -169,6 +169,7 @@ namespace llvm {
|
||||
/// 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user