mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-03 14:21:30 +00:00
R600/SI: Set 20-bit immediate byte offset for SMRD on VI
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223614 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -971,15 +971,19 @@ bool SIInstrInfo::isImmOperandLegal(const MachineInstr *MI, unsigned OpNo,
|
||||
return RI.regClassCanUseInlineConstant(OpInfo.RegClass);
|
||||
}
|
||||
|
||||
bool SIInstrInfo::canFoldOffset(unsigned OffsetSize, unsigned AS) {
|
||||
bool SIInstrInfo::canFoldOffset(unsigned OffsetSize, unsigned AS) const {
|
||||
switch (AS) {
|
||||
case AMDGPUAS::GLOBAL_ADDRESS: {
|
||||
// MUBUF instructions a 12-bit offset in bytes.
|
||||
return isUInt<12>(OffsetSize);
|
||||
}
|
||||
case AMDGPUAS::CONSTANT_ADDRESS: {
|
||||
// SMRD instructions have an 8-bit offset in dwords.
|
||||
return (OffsetSize % 4 == 0) && isUInt<8>(OffsetSize / 4);
|
||||
// SMRD instructions have an 8-bit offset in dwords on SI and
|
||||
// a 20-bit offset in bytes on VI.
|
||||
if (RI.ST.getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS)
|
||||
return isUInt<20>(OffsetSize);
|
||||
else
|
||||
return (OffsetSize % 4 == 0) && isUInt<8>(OffsetSize / 4);
|
||||
}
|
||||
case AMDGPUAS::LOCAL_ADDRESS:
|
||||
case AMDGPUAS::REGION_ADDRESS: {
|
||||
@@ -1701,27 +1705,30 @@ void SIInstrInfo::splitSMRD(MachineInstr *MI,
|
||||
getNamedOperand(*MI, AMDGPU::OpName::offset);
|
||||
const MachineOperand *SBase = getNamedOperand(*MI, AMDGPU::OpName::sbase);
|
||||
|
||||
// The SMRD has an 8-bit offset in dwords on SI and a 20-bit offset in bytes
|
||||
// on VI.
|
||||
if (OffOp) {
|
||||
bool isVI = RI.ST.getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS;
|
||||
unsigned OffScale = isVI ? 1 : 4;
|
||||
// Handle the _IMM variant
|
||||
unsigned LoOffset = OffOp->getImm();
|
||||
unsigned HiOffset = LoOffset + (HalfSize / 4);
|
||||
unsigned LoOffset = OffOp->getImm() * OffScale;
|
||||
unsigned HiOffset = LoOffset + HalfSize;
|
||||
Lo = BuildMI(*MBB, MI, DL, get(HalfImmOp), RegLo)
|
||||
.addOperand(*SBase)
|
||||
.addImm(LoOffset);
|
||||
.addImm(LoOffset / OffScale);
|
||||
|
||||
if (!isUInt<8>(HiOffset)) {
|
||||
if (!isUInt<20>(HiOffset) || (!isVI && !isUInt<8>(HiOffset / OffScale))) {
|
||||
unsigned OffsetSGPR =
|
||||
MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
|
||||
BuildMI(*MBB, MI, DL, get(AMDGPU::S_MOV_B32), OffsetSGPR)
|
||||
.addImm(HiOffset << 2); // The immediate offset is in dwords,
|
||||
// but offset in register is in bytes.
|
||||
.addImm(HiOffset); // The offset in register is in bytes.
|
||||
Hi = BuildMI(*MBB, MI, DL, get(HalfSGPROp), RegHi)
|
||||
.addOperand(*SBase)
|
||||
.addReg(OffsetSGPR);
|
||||
} else {
|
||||
Hi = BuildMI(*MBB, MI, DL, get(HalfImmOp), RegHi)
|
||||
.addOperand(*SBase)
|
||||
.addImm(HiOffset);
|
||||
.addImm(HiOffset / OffScale);
|
||||
}
|
||||
} else {
|
||||
// Handle the _SGPR variant
|
||||
@@ -1786,10 +1793,13 @@ void SIInstrInfo::moveSMRDToVALU(MachineInstr *MI, MachineRegisterInfo &MRI) con
|
||||
ImmOffset = 0;
|
||||
} else {
|
||||
assert(MI->getOperand(2).isImm());
|
||||
// SMRD instructions take a dword offsets and MUBUF instructions
|
||||
// take a byte offset.
|
||||
ImmOffset = MI->getOperand(2).getImm() << 2;
|
||||
// SMRD instructions take a dword offsets on SI and byte offset on VI
|
||||
// and MUBUF instructions always take a byte offset.
|
||||
ImmOffset = MI->getOperand(2).getImm();
|
||||
if (RI.ST.getGeneration() <= AMDGPUSubtarget::SEA_ISLANDS)
|
||||
ImmOffset <<= 2;
|
||||
RegOffset = MRI.createVirtualRegister(&AMDGPU::SGPR_32RegClass);
|
||||
|
||||
if (isUInt<12>(ImmOffset)) {
|
||||
BuildMI(*MBB, MI, MI->getDebugLoc(), get(AMDGPU::S_MOV_B32),
|
||||
RegOffset)
|
||||
|
||||
Reference in New Issue
Block a user