Index: lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp =================================================================== --- lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -864,7 +864,7 @@ unsigned& RegNum, unsigned& RegWidth, unsigned *DwordRegIndex); void cvtMubufImpl(MCInst &Inst, const OperandVector &Operands, - bool IsAtomic, bool IsAtomicReturn); + bool IsAtomic, bool IsAtomicReturn, bool IsLds = false); void cvtDSImpl(MCInst &Inst, const OperandVector &Operands, bool IsGdsHardcoded); @@ -1092,6 +1092,7 @@ void cvtMubuf(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, false, false); } void cvtMubufAtomic(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, true, false); } void cvtMubufAtomicReturn(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, true, true); } + void cvtMubufLds(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, false, false, true); } void cvtMtbuf(MCInst &Inst, const OperandVector &Operands); AMDGPUOperand::Ptr defaultGLC() const; @@ -4081,7 +4082,10 @@ void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst, const OperandVector &Operands, - bool IsAtomic, bool IsAtomicReturn) { + bool IsAtomic, + bool IsAtomicReturn, + bool IsLds) { + bool IsLdsOpcode = IsLds; bool HasLdsModifier = false; OptionalImmIndexMap OptionalIdx; assert(IsAtomicReturn ? IsAtomic : true); @@ -4121,10 +4125,11 @@ // optional modifiers and llvm asm matcher regards this 'lds' // modifier as an optional one. As a result, an lds version // of opcode may be selected even if it has no 'lds' modifier. - if (!HasLdsModifier) { + if (IsLdsOpcode && !HasLdsModifier) { int NoLdsOpcode = AMDGPU::getMUBUFNoLdsInst(Inst.getOpcode()); if (NoLdsOpcode != -1) { // Got lds version - correct it. Inst.setOpcode(NoLdsOpcode); + IsLdsOpcode = false; } } @@ -4140,7 +4145,7 @@ } addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySLC); - if (!HasLdsModifier) { // tfe is not legal with lds opcodes + if (!IsLdsOpcode) { // tfe is not legal with lds opcodes addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyTFE); } } Index: lib/Target/AMDGPU/BUFInstructions.td =================================================================== --- lib/Target/AMDGPU/BUFInstructions.td +++ lib/Target/AMDGPU/BUFInstructions.td @@ -449,6 +449,7 @@ MUBUF_SetupAddr { let PseudoInstr = opName # !if(isLds, "_lds", "") # "_" # getAddrName.ret; + let AsmMatchConverter = !if(isLds, "cvtMubufLds", "cvtMubuf"); let Constraints = !if(HasTiedDest, "$vdata = $vdata_in", ""); let mayLoad = 1; @@ -548,6 +549,23 @@ } } +class MUBUF_Pseudo_Store_Lds + : MUBUF_Pseudo { + let mayLoad = 0; + let mayStore = 1; + let maybeAtomic = 1; + + let has_vdata = 0; + let has_vaddr = 0; + let has_tfe = 0; + let lds = 1; + + let Uses = [EXEC, M0]; + let AsmMatchConverter = "cvtMubufLds"; +} class getMUBUFAtomicInsDA vaddrList=[]> { @@ -877,6 +895,10 @@ "buffer_atomic_dec_x2", VReg_64, i64, atomic_dec_global >; +let SubtargetPredicate = isVI in { +def BUFFER_STORE_LDS_DWORD : MUBUF_Pseudo_Store_Lds <"buffer_store_lds_dword">; +} + let SubtargetPredicate = isSI in { // isn't on CI & VI /* defm BUFFER_ATOMIC_RSUB : MUBUF_Pseudo_Atomics <"buffer_atomic_rsub">; @@ -1952,6 +1974,8 @@ defm BUFFER_ATOMIC_INC_X2 : MUBUF_Real_Atomic_vi <0x6b>; defm BUFFER_ATOMIC_DEC_X2 : MUBUF_Real_Atomic_vi <0x6c>; +def BUFFER_STORE_LDS_DWORD_vi : MUBUF_Real_vi <0x3d, BUFFER_STORE_LDS_DWORD>; + def BUFFER_WBINVL1_vi : MUBUF_Real_vi <0x3e, BUFFER_WBINVL1>; def BUFFER_WBINVL1_VOL_vi : MUBUF_Real_vi <0x3f, BUFFER_WBINVL1_VOL>; Index: test/MC/AMDGPU/mubuf.s =================================================================== --- test/MC/AMDGPU/mubuf.s +++ test/MC/AMDGPU/mubuf.s @@ -2,8 +2,8 @@ // RUN: not llvm-mc -arch=amdgcn -mcpu=bonaire -show-encoding %s | FileCheck -check-prefix=GCN -check-prefix=CI -check-prefix=SICI %s // RUN: not llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding %s | FileCheck -check-prefix=GCN -check-prefix=VI %s -// RUN: not llvm-mc -arch=amdgcn -mcpu=tahiti %s 2>&1 | FileCheck -check-prefix=NOSI -check-prefix=NOSICIVI %s -// RUN: not llvm-mc -arch=amdgcn -mcpu=bonaire %s 2>&1 | FileCheck -check-prefix=NOCI -check-prefix=NOSICIVI %s +// RUN: not llvm-mc -arch=amdgcn -mcpu=tahiti %s 2>&1 | FileCheck -check-prefix=NOSI -check-prefix=NOSICIVI -check-prefix=NOSICI %s +// RUN: not llvm-mc -arch=amdgcn -mcpu=bonaire %s 2>&1 | FileCheck -check-prefix=NOCI -check-prefix=NOSICIVI -check-prefix=NOSICI %s // RUN: not llvm-mc -arch=amdgcn -mcpu=tonga %s 2>&1 | FileCheck -check-prefix=NOVI -check-prefix=NOSICIVI %s //===----------------------------------------------------------------------===// @@ -767,6 +767,18 @@ // SICI: buffer_load_format_x v5, v[0:1], s[8:11], s3 idxen offen offset:4095 glc slc lds ; encoding: [0xff,0x7f,0x01,0xe0,0x00,0x05,0x42,0x03] // VI: buffer_load_format_x v5, v[0:1], s[8:11], s3 idxen offen offset:4095 glc slc lds ; encoding: [0xff,0x7f,0x03,0xe0,0x00,0x05,0x02,0x03] +buffer_store_lds_dword s[4:7], s0 lds +// NOSICI: error: instruction not supported on this GPU +// VI: buffer_store_lds_dword s[4:7], s0 lds ; encoding: [0x00,0x00,0xf5,0xe0,0x00,0x00,0x01,0x00] + +buffer_store_lds_dword s[4:7], s0 offset:4095 lds +// NOSICI: error: not a valid operand. +// VI: buffer_store_lds_dword s[4:7], s0 offset:4095 lds ; encoding: [0xff,0x0f,0xf5,0xe0,0x00,0x00,0x01,0x00] + +buffer_store_lds_dword s[4:7], s8 offset:4 lds glc slc +// NOSICI: error: not a valid operand. +// VI: buffer_store_lds_dword s[4:7], s8 offset:4 lds glc slc ; encoding: [0x04,0x40,0xf7,0xe0,0x00,0x00,0x01,0x08] + //===----------------------------------------------------------------------===// // Errors handling //===----------------------------------------------------------------------===// @@ -776,3 +788,11 @@ buffer_load_dword v5, off, s[8:11], s3 tfe lds // NOSICIVI: error: invalid operand for instruction + +buffer_store_lds_dword s[4:7], s8 offset:4 lds tfe +// NOSICI: error: not a valid operand. +// NOVI: error: invalid operand for instruction + +buffer_store_lds_dword s[4:7], s8 offset:4 tfe lds +// NOSICI: error: not a valid operand. +// NOVI: error: invalid operand for instruction Index: test/MC/Disassembler/AMDGPU/mubuf_vi.txt =================================================================== --- test/MC/Disassembler/AMDGPU/mubuf_vi.txt +++ test/MC/Disassembler/AMDGPU/mubuf_vi.txt @@ -402,3 +402,12 @@ # VI: buffer_load_format_x v5, v[0:1], s[8:11], s3 idxen offen offset:4095 glc slc lds ; encoding: [0xff,0x7f,0x03,0xe0,0x00,0x05,0x02,0x03] 0xff,0x7f,0x03,0xe0,0x00,0x05,0x02,0x03 + +# VI: buffer_store_lds_dword s[4:7], s0 lds ; encoding: [0x00,0x00,0xf5,0xe0,0x00,0x00,0x01,0x00] +0x00,0x00,0xf5,0xe0,0x00,0x00,0x01,0x00 + +# VI: buffer_store_lds_dword s[4:7], s0 offset:4095 lds ; encoding: [0xff,0x0f,0xf5,0xe0,0x00,0x00,0x01,0x00] +0xff,0x0f,0xf5,0xe0,0x00,0x00,0x01,0x00 + +# VI: buffer_store_lds_dword s[4:7], s8 offset:4 lds glc slc ; encoding: [0x04,0x40,0xf7,0xe0,0x00,0x00,0x01,0x08] +0x04,0x40,0xf7,0xe0,0x00,0x00,0x01,0x08