mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
AMDGPU: Factor out large flat offset splitting
This commit is contained in:
parent
79a7d81750
commit
b3aa28b9d4
@ -1742,22 +1742,10 @@ bool AMDGPUDAGToDAGISel::SelectFlatOffset(SDNode *N,
|
|||||||
// into two pieces that are both >= 0 or both <= 0.
|
// into two pieces that are both >= 0 or both <= 0.
|
||||||
|
|
||||||
SDLoc DL(N);
|
SDLoc DL(N);
|
||||||
uint64_t RemainderOffset = COffsetVal;
|
uint64_t RemainderOffset;
|
||||||
uint64_t ImmField = 0;
|
|
||||||
const unsigned NumBits = TII->getNumFlatOffsetBits(IsSigned);
|
|
||||||
if (IsSigned) {
|
|
||||||
// Use signed division by a power of two to truncate towards 0.
|
|
||||||
int64_t D = 1LL << (NumBits - 1);
|
|
||||||
RemainderOffset = (static_cast<int64_t>(COffsetVal) / D) * D;
|
|
||||||
ImmField = COffsetVal - RemainderOffset;
|
|
||||||
} else if (static_cast<int64_t>(COffsetVal) >= 0) {
|
|
||||||
ImmField = COffsetVal & maskTrailingOnes<uint64_t>(NumBits);
|
|
||||||
RemainderOffset = COffsetVal - ImmField;
|
|
||||||
}
|
|
||||||
assert(TII->isLegalFLATOffset(ImmField, AS, IsSigned));
|
|
||||||
assert(RemainderOffset + ImmField == COffsetVal);
|
|
||||||
|
|
||||||
OffsetVal = ImmField;
|
std::tie(OffsetVal, RemainderOffset)
|
||||||
|
= TII->splitFlatOffset(COffsetVal, AS, IsSigned);
|
||||||
|
|
||||||
SDValue AddOffsetLo =
|
SDValue AddOffsetLo =
|
||||||
getMaterializedScalarImm32(Lo_32(RemainderOffset), DL);
|
getMaterializedScalarImm32(Lo_32(RemainderOffset), DL);
|
||||||
|
@ -6959,6 +6959,26 @@ bool SIInstrInfo::isLegalFLATOffset(int64_t Offset, unsigned AddrSpace,
|
|||||||
return Signed ? isInt<13>(Offset) :isUInt<12>(Offset);
|
return Signed ? isInt<13>(Offset) :isUInt<12>(Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<int64_t, int64_t> SIInstrInfo::splitFlatOffset(int64_t COffsetVal,
|
||||||
|
unsigned AddrSpace,
|
||||||
|
bool IsSigned) const {
|
||||||
|
int64_t RemainderOffset = COffsetVal;
|
||||||
|
int64_t ImmField = 0;
|
||||||
|
const unsigned NumBits = getNumFlatOffsetBits(IsSigned);
|
||||||
|
if (IsSigned) {
|
||||||
|
// Use signed division by a power of two to truncate towards 0.
|
||||||
|
int64_t D = 1LL << (NumBits - 1);
|
||||||
|
RemainderOffset = (COffsetVal / D) * D;
|
||||||
|
ImmField = COffsetVal - RemainderOffset;
|
||||||
|
} else if (COffsetVal >= 0) {
|
||||||
|
ImmField = COffsetVal & maskTrailingOnes<uint64_t>(NumBits);
|
||||||
|
RemainderOffset = COffsetVal - ImmField;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(isLegalFLATOffset(ImmField, AddrSpace, IsSigned));
|
||||||
|
assert(RemainderOffset + ImmField == COffsetVal);
|
||||||
|
return {ImmField, RemainderOffset};
|
||||||
|
}
|
||||||
|
|
||||||
// This must be kept in sync with the SIEncodingFamily class in SIInstrInfo.td
|
// This must be kept in sync with the SIEncodingFamily class in SIInstrInfo.td
|
||||||
enum SIEncodingFamily {
|
enum SIEncodingFamily {
|
||||||
|
@ -1039,6 +1039,12 @@ public:
|
|||||||
bool isLegalFLATOffset(int64_t Offset, unsigned AddrSpace,
|
bool isLegalFLATOffset(int64_t Offset, unsigned AddrSpace,
|
||||||
bool Signed) const;
|
bool Signed) const;
|
||||||
|
|
||||||
|
/// Split \p COffsetVal into {immediate offset field, remainder offset}
|
||||||
|
/// values.
|
||||||
|
std::pair<int64_t, int64_t> splitFlatOffset(int64_t COffsetVal,
|
||||||
|
unsigned AddrSpace,
|
||||||
|
bool IsSigned) const;
|
||||||
|
|
||||||
/// \brief Return a target-specific opcode if Opcode is a pseudo instruction.
|
/// \brief Return a target-specific opcode if Opcode is a pseudo instruction.
|
||||||
/// Return -1 if the target-specific opcode for the pseudo instruction does
|
/// Return -1 if the target-specific opcode for the pseudo instruction does
|
||||||
/// not exist. If Opcode is not a pseudo instruction, this is identity.
|
/// not exist. If Opcode is not a pseudo instruction, this is identity.
|
||||||
|
Loading…
Reference in New Issue
Block a user