From: Artem Tamazov Date: Mon, 31 Oct 2016 16:07:39 +0000 (+0000) Subject: [AMDGPU][MC][gfx8] Support 20-bit immediate offset in SMEM instructions. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=86d93952ed625036fdfb652cc25c41757862d815;p=llvm [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@285590 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index 957233caa9f..b7e61ad35fc 100644 --- a/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -341,7 +341,8 @@ public: bool isSWaitCnt() const; bool isHwreg() const; bool isSendMsg() const; - bool isSMRDOffset() const; + bool isSMRDOffset8() const; + bool isSMRDOffset20() const; bool isSMRDLiteralOffset() const; bool isDPPCtrl() const; bool isGPRIdxMode() const; @@ -741,7 +742,8 @@ public: AMDGPUOperand::Ptr defaultDA() const; AMDGPUOperand::Ptr defaultR128() const; AMDGPUOperand::Ptr defaultLWE() const; - AMDGPUOperand::Ptr defaultSMRDOffset() const; + AMDGPUOperand::Ptr defaultSMRDOffset8() const; + AMDGPUOperand::Ptr defaultSMRDOffset20() const; AMDGPUOperand::Ptr defaultSMRDLiteralOffset() const; OperandMatchResultTy parseOModOperand(OperandVector &Operands); @@ -2533,20 +2535,25 @@ AMDGPUOperand::Ptr AMDGPUAsmParser::defaultLWE() const { // smrd //===----------------------------------------------------------------------===// -bool AMDGPUOperand::isSMRDOffset() const { - - // FIXME: Support 20-bit offsets on VI. We need to to pass subtarget - // information here. +bool AMDGPUOperand::isSMRDOffset8() const { return isImm() && isUInt<8>(getImm()); } +bool AMDGPUOperand::isSMRDOffset20() const { + return isImm() && isUInt<20>(getImm()); +} + bool AMDGPUOperand::isSMRDLiteralOffset() const { // 32-bit literals are only supported on CI and we only want to use them // when the offset is > 8-bits. 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); } diff --git a/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp b/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp index aec10087a88..3ab030082ec 100644 --- a/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp +++ b/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp @@ -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, raw_ostream &O) { printU32ImmOperand(MI, OpNo, STI, O); diff --git a/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h b/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h index 8a5ce607428..960e65814c1 100644 --- a/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h +++ b/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.h @@ -56,7 +56,9 @@ private: raw_ostream &O); void printOffset1(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, 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); void printSMRDLiteralOffset(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); diff --git a/lib/Target/AMDGPU/SMInstructions.td b/lib/Target/AMDGPU/SMInstructions.td index 9b9d5588ed5..ddb695aa3e4 100644 --- a/lib/Target/AMDGPU/SMInstructions.td +++ b/lib/Target/AMDGPU/SMInstructions.td @@ -7,11 +7,15 @@ // //===----------------------------------------------------------------------===// -def smrd_offset : NamedOperandU32<"SMRDOffset", - NamedMatchClass<"SMRDOffset">> { +def smrd_offset_8 : NamedOperandU32<"SMRDOffset8", + NamedMatchClass<"SMRDOffset8">> { let OperandType = "OPERAND_IMMEDIATE"; } +def smrd_offset_20 : NamedOperandU32<"SMRDOffset20", + NamedMatchClass<"SMRDOffset20">> { + let OperandType = "OPERAND_IMMEDIATE"; +} //===----------------------------------------------------------------------===// // Scalar Memory classes @@ -325,7 +329,7 @@ multiclass SM_Real_Loads_si op, string ps, SM_Load_Pseudo sgprPs = !cast(ps#_SGPR)> { def _IMM_si : SMRD_Real_si { - 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 @@ -378,7 +382,7 @@ multiclass SM_Real_Loads_vi op, string ps, SM_Load_Pseudo immPs = !cast(ps#_IMM), SM_Load_Pseudo sgprPs = !cast(ps#_SGPR)> { def _IMM_vi : SMEM_Real_vi { - 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 { let InOperandList = (ins sgprPs.BaseClass:$sbase, SReg_32:$offset, GLC:$glc); @@ -391,7 +395,7 @@ multiclass SM_Real_Stores_vi op, string ps, // FIXME: The operand name $offset is inconsistent with $soff used // in the pseudo def _IMM_vi : SMEM_Real_vi { - 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 { diff --git a/test/MC/AMDGPU/smrd.s b/test/MC/AMDGPU/smrd.s index ac3ce26db98..211ec7e618b 100644 --- a/test/MC/AMDGPU/smrd.s +++ b/test/MC/AMDGPU/smrd.s @@ -21,8 +21,23 @@ s_load_dword s1, s[2:3], 0xff s_load_dword s1, s[2:3], 0x100 // 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] +// 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 diff --git a/test/MC/Disassembler/AMDGPU/smrd_vi.txt b/test/MC/Disassembler/AMDGPU/smrd_vi.txt index 8191bd1845e..630c55f6b55 100644 --- a/test/MC/Disassembler/AMDGPU/smrd_vi.txt +++ b/test/MC/Disassembler/AMDGPU/smrd_vi.txt @@ -9,6 +9,9 @@ # 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 +# 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] 0x41 0x00 0x00 0xc0 0x04 0x00 0x00 0x00