forked from OSchip/llvm-project
[AMDGPU][MC][gfx8] Support 20-bit immediate offset in SMEM instructions.
Fixes Bug 30808. Note that passing subtarget information to predicates seems too complicated, so gfx8-specific def smrd_offset_20 introduced. Old gfx6/7-specific def renamed to smrd_offset_8 for clarity. Lit tests updated. Differential Revision: https://reviews.llvm.org/D26085 llvm-svn: 285590
This commit is contained in:
parent
54c5a545be
commit
54bfd548aa
|
@ -341,7 +341,8 @@ public:
|
||||||
bool isSWaitCnt() const;
|
bool isSWaitCnt() const;
|
||||||
bool isHwreg() const;
|
bool isHwreg() const;
|
||||||
bool isSendMsg() const;
|
bool isSendMsg() const;
|
||||||
bool isSMRDOffset() const;
|
bool isSMRDOffset8() const;
|
||||||
|
bool isSMRDOffset20() const;
|
||||||
bool isSMRDLiteralOffset() const;
|
bool isSMRDLiteralOffset() const;
|
||||||
bool isDPPCtrl() const;
|
bool isDPPCtrl() const;
|
||||||
bool isGPRIdxMode() const;
|
bool isGPRIdxMode() const;
|
||||||
|
@ -741,7 +742,8 @@ public:
|
||||||
AMDGPUOperand::Ptr defaultDA() const;
|
AMDGPUOperand::Ptr defaultDA() const;
|
||||||
AMDGPUOperand::Ptr defaultR128() const;
|
AMDGPUOperand::Ptr defaultR128() const;
|
||||||
AMDGPUOperand::Ptr defaultLWE() const;
|
AMDGPUOperand::Ptr defaultLWE() const;
|
||||||
AMDGPUOperand::Ptr defaultSMRDOffset() const;
|
AMDGPUOperand::Ptr defaultSMRDOffset8() const;
|
||||||
|
AMDGPUOperand::Ptr defaultSMRDOffset20() const;
|
||||||
AMDGPUOperand::Ptr defaultSMRDLiteralOffset() const;
|
AMDGPUOperand::Ptr defaultSMRDLiteralOffset() const;
|
||||||
|
|
||||||
OperandMatchResultTy parseOModOperand(OperandVector &Operands);
|
OperandMatchResultTy parseOModOperand(OperandVector &Operands);
|
||||||
|
@ -2533,20 +2535,25 @@ AMDGPUOperand::Ptr AMDGPUAsmParser::defaultLWE() const {
|
||||||
// smrd
|
// smrd
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
bool AMDGPUOperand::isSMRDOffset() const {
|
bool AMDGPUOperand::isSMRDOffset8() const {
|
||||||
|
|
||||||
// FIXME: Support 20-bit offsets on VI. We need to to pass subtarget
|
|
||||||
// information here.
|
|
||||||
return isImm() && isUInt<8>(getImm());
|
return isImm() && isUInt<8>(getImm());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AMDGPUOperand::isSMRDOffset20() const {
|
||||||
|
return isImm() && isUInt<20>(getImm());
|
||||||
|
}
|
||||||
|
|
||||||
bool AMDGPUOperand::isSMRDLiteralOffset() const {
|
bool AMDGPUOperand::isSMRDLiteralOffset() const {
|
||||||
// 32-bit literals are only supported on CI and we only want to use them
|
// 32-bit literals are only supported on CI and we only want to use them
|
||||||
// when the offset is > 8-bits.
|
// when the offset is > 8-bits.
|
||||||
return isImm() && !isUInt<8>(getImm()) && isUInt<32>(getImm());
|
return isImm() && !isUInt<8>(getImm()) && isUInt<32>(getImm());
|
||||||
}
|
}
|
||||||
|
|
||||||
AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSMRDOffset() const {
|
AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSMRDOffset8() const {
|
||||||
|
return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSMRDOffset20() const {
|
||||||
return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyOffset);
|
return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,13 @@ void AMDGPUInstPrinter::printOffset1(const MCInst *MI, unsigned OpNo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AMDGPUInstPrinter::printSMRDOffset(const MCInst *MI, unsigned OpNo,
|
void AMDGPUInstPrinter::printSMRDOffset8(const MCInst *MI, unsigned OpNo,
|
||||||
|
const MCSubtargetInfo &STI,
|
||||||
|
raw_ostream &O) {
|
||||||
|
printU32ImmOperand(MI, OpNo, STI, O);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMDGPUInstPrinter::printSMRDOffset20(const MCInst *MI, unsigned OpNo,
|
||||||
const MCSubtargetInfo &STI,
|
const MCSubtargetInfo &STI,
|
||||||
raw_ostream &O) {
|
raw_ostream &O) {
|
||||||
printU32ImmOperand(MI, OpNo, STI, O);
|
printU32ImmOperand(MI, OpNo, STI, O);
|
||||||
|
|
|
@ -56,7 +56,9 @@ private:
|
||||||
raw_ostream &O);
|
raw_ostream &O);
|
||||||
void printOffset1(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
|
void printOffset1(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
|
||||||
raw_ostream &O);
|
raw_ostream &O);
|
||||||
void printSMRDOffset(const MCInst *MI, unsigned OpNo,
|
void printSMRDOffset8(const MCInst *MI, unsigned OpNo,
|
||||||
|
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||||
|
void printSMRDOffset20(const MCInst *MI, unsigned OpNo,
|
||||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||||
void printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo,
|
void printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo,
|
||||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||||
|
|
|
@ -7,11 +7,15 @@
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
def smrd_offset : NamedOperandU32<"SMRDOffset",
|
def smrd_offset_8 : NamedOperandU32<"SMRDOffset8",
|
||||||
NamedMatchClass<"SMRDOffset">> {
|
NamedMatchClass<"SMRDOffset8">> {
|
||||||
let OperandType = "OPERAND_IMMEDIATE";
|
let OperandType = "OPERAND_IMMEDIATE";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def smrd_offset_20 : NamedOperandU32<"SMRDOffset20",
|
||||||
|
NamedMatchClass<"SMRDOffset20">> {
|
||||||
|
let OperandType = "OPERAND_IMMEDIATE";
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Scalar Memory classes
|
// Scalar Memory classes
|
||||||
|
@ -325,7 +329,7 @@ multiclass SM_Real_Loads_si<bits<5> op, string ps,
|
||||||
SM_Load_Pseudo sgprPs = !cast<SM_Load_Pseudo>(ps#_SGPR)> {
|
SM_Load_Pseudo sgprPs = !cast<SM_Load_Pseudo>(ps#_SGPR)> {
|
||||||
|
|
||||||
def _IMM_si : SMRD_Real_si <op, immPs> {
|
def _IMM_si : SMRD_Real_si <op, immPs> {
|
||||||
let InOperandList = (ins immPs.BaseClass:$sbase, smrd_offset:$offset, GLC:$glc);
|
let InOperandList = (ins immPs.BaseClass:$sbase, smrd_offset_8:$offset, GLC:$glc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: The operand name $offset is inconsistent with $soff used
|
// FIXME: The operand name $offset is inconsistent with $soff used
|
||||||
|
@ -378,7 +382,7 @@ multiclass SM_Real_Loads_vi<bits<8> op, string ps,
|
||||||
SM_Load_Pseudo immPs = !cast<SM_Load_Pseudo>(ps#_IMM),
|
SM_Load_Pseudo immPs = !cast<SM_Load_Pseudo>(ps#_IMM),
|
||||||
SM_Load_Pseudo sgprPs = !cast<SM_Load_Pseudo>(ps#_SGPR)> {
|
SM_Load_Pseudo sgprPs = !cast<SM_Load_Pseudo>(ps#_SGPR)> {
|
||||||
def _IMM_vi : SMEM_Real_vi <op, immPs> {
|
def _IMM_vi : SMEM_Real_vi <op, immPs> {
|
||||||
let InOperandList = (ins immPs.BaseClass:$sbase, smrd_offset:$offset, GLC:$glc);
|
let InOperandList = (ins immPs.BaseClass:$sbase, smrd_offset_20:$offset, GLC:$glc);
|
||||||
}
|
}
|
||||||
def _SGPR_vi : SMEM_Real_vi <op, sgprPs> {
|
def _SGPR_vi : SMEM_Real_vi <op, sgprPs> {
|
||||||
let InOperandList = (ins sgprPs.BaseClass:$sbase, SReg_32:$offset, GLC:$glc);
|
let InOperandList = (ins sgprPs.BaseClass:$sbase, SReg_32:$offset, GLC:$glc);
|
||||||
|
@ -391,7 +395,7 @@ multiclass SM_Real_Stores_vi<bits<8> op, string ps,
|
||||||
// FIXME: The operand name $offset is inconsistent with $soff used
|
// FIXME: The operand name $offset is inconsistent with $soff used
|
||||||
// in the pseudo
|
// in the pseudo
|
||||||
def _IMM_vi : SMEM_Real_vi <op, immPs> {
|
def _IMM_vi : SMEM_Real_vi <op, immPs> {
|
||||||
let InOperandList = (ins immPs.SrcClass:$sdata, immPs.BaseClass:$sbase, smrd_offset:$offset, GLC:$glc);
|
let InOperandList = (ins immPs.SrcClass:$sdata, immPs.BaseClass:$sbase, smrd_offset_20:$offset, GLC:$glc);
|
||||||
}
|
}
|
||||||
|
|
||||||
def _SGPR_vi : SMEM_Real_vi <op, sgprPs> {
|
def _SGPR_vi : SMEM_Real_vi <op, sgprPs> {
|
||||||
|
|
|
@ -21,8 +21,23 @@ s_load_dword s1, s[2:3], 0xff
|
||||||
|
|
||||||
s_load_dword s1, s[2:3], 0x100
|
s_load_dword s1, s[2:3], 0x100
|
||||||
// NOSI: error: instruction not supported on this GPU
|
// NOSI: error: instruction not supported on this GPU
|
||||||
// NOVI: error: instruction not supported on this GPU
|
|
||||||
// CI: s_load_dword s1, s[2:3], 0x100 ; encoding: [0xff,0x82,0x00,0xc0,0x00,0x01,0x00,0x00]
|
// CI: s_load_dword s1, s[2:3], 0x100 ; encoding: [0xff,0x82,0x00,0xc0,0x00,0x01,0x00,0x00]
|
||||||
|
// VI: s_load_dword s1, s[2:3], 0x100 ; encoding: [0x41,0x00,0x02,0xc0,0x00,0x01,0x00,0x00]
|
||||||
|
|
||||||
|
s_load_dword s1, s[2:3], 0xfffff
|
||||||
|
// NOSI: error: instruction not supported on this GPU
|
||||||
|
// CI: s_load_dword s1, s[2:3], 0xfffff ; encoding: [0xff,0x82,0x00,0xc0,0xff,0xff,0x0f,0x00]
|
||||||
|
// VI: s_load_dword s1, s[2:3], 0xfffff ; encoding: [0x41,0x00,0x02,0xc0,0xff,0xff,0x0f,0x00]
|
||||||
|
|
||||||
|
s_load_dword s1, s[2:3], 0x100000
|
||||||
|
// NOSI: error: instruction not supported on this GPU
|
||||||
|
// CI: s_load_dword s1, s[2:3], 0x100000 ; encoding: [0xff,0x82,0x00,0xc0,0x00,0x00,0x10,0x00]
|
||||||
|
// NOVI: error: instruction not supported on this GPU
|
||||||
|
|
||||||
|
s_load_dword s1, s[2:3], 0xffffffff
|
||||||
|
// NOSI: error: instruction not supported on this GPU
|
||||||
|
// CI: s_load_dword s1, s[2:3], 0xffffffff ; encoding: [0xff,0x82,0x00,0xc0,0xff,0xff,0xff,0xff]
|
||||||
|
// NOVI: error: instruction not supported on this GPU
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Instructions
|
// Instructions
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
# VI: s_load_dword s1, s[2:3], 0x1 ; encoding: [0x41,0x00,0x02,0xc0,0x01,0x00,0x00,0x00]
|
# VI: s_load_dword s1, s[2:3], 0x1 ; encoding: [0x41,0x00,0x02,0xc0,0x01,0x00,0x00,0x00]
|
||||||
0x41 0x00 0x02 0xc0 0x01 0x00 0x00 0x00
|
0x41 0x00 0x02 0xc0 0x01 0x00 0x00 0x00
|
||||||
|
|
||||||
|
# VI: s_load_dword s1, s[2:3], 0xfffff ; encoding: [0x41,0x00,0x02,0xc0,0xff,0xff,0x0f,0x00]
|
||||||
|
0x41,0x00,0x02,0xc0,0xff,0xff,0x0f,0x00
|
||||||
|
|
||||||
# VI: s_load_dword s1, s[2:3], s4 ; encoding: [0x41,0x00,0x00,0xc0,0x04,0x00,0x00,0x00]
|
# VI: s_load_dword s1, s[2:3], s4 ; encoding: [0x41,0x00,0x00,0xc0,0x04,0x00,0x00,0x00]
|
||||||
0x41 0x00 0x00 0xc0 0x04 0x00 0x00 0x00
|
0x41 0x00 0x00 0xc0 0x04 0x00 0x00 0x00
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue