diff --git a/llvm/lib/Target/AMDGPU/SMInstructions.td b/llvm/lib/Target/AMDGPU/SMInstructions.td --- a/llvm/lib/Target/AMDGPU/SMInstructions.td +++ b/llvm/lib/Target/AMDGPU/SMInstructions.td @@ -590,7 +590,7 @@ } } -class SMEM_Real_Store_vi op, SM_Pseudo ps> : SMEM_Real_vi { +class SMEM_Real_Store_Probe_vi op, SM_Pseudo ps> : SMEM_Real_vi { // encoding bits<7> sdata; @@ -598,21 +598,33 @@ let Inst{12-6} = !if(ps.has_sdst, sdata{6-0}, ?); } -multiclass SM_Real_Stores_vi op, string ps, - SM_Store_Pseudo immPs = !cast(ps#_IMM), - SM_Store_Pseudo sgprPs = !cast(ps#_SGPR)> { - def _IMM_vi : SMEM_Real_Store_vi { - let InOperandList = (ins immPs.SrcClass:$sdata, immPs.BaseClass:$sbase, smem_offset:$offset, CPol:$cpol); - } +class SMEM_Real_Store_vi op, string ps, dag offsets> + : SMEM_Real_Store_Probe_vi (ps)> { + RegisterClass SrcClass = !cast(ps).SrcClass; + RegisterClass BaseClass = !cast(ps).BaseClass; + let InOperandList = !con((ins SrcClass:$sdata, BaseClass:$sbase), + offsets, (ins CPol:$cpol)); +} - def _SGPR_vi : SMEM_Real_Store_vi { - let InOperandList = (ins sgprPs.SrcClass:$sdata, sgprPs.BaseClass:$sbase, SReg_32:$soffset, CPol:$cpol); +multiclass SM_Real_Stores_vi op, string ps> { + def _IMM_vi : SMEM_Real_Store_vi ; + def _SGPR_vi : SMEM_Real_Store_vi ; + let IsGFX9Specific = true in { + // The alternative GFX9 SGPR encoding using soffset to encode the + // offset register. Not available in assembler and goes to the GFX9 + // encoding family to avoid conflicts with the primary SGPR variant. + let SOffsetEn = 1, Offset = ?, Subtarget = SIEncodingFamily.GFX9, + AsmVariantName = "NonParsable" in + def _SGPR_alt_gfx9 : SMEM_Real_Store_vi ; + def _SGPR_IMM_gfx9 : SMEM_Real_Store_vi < + op, ps#"_SGPR_IMM", (ins SReg_32:$soffset, smem_offset_mod:$offset)>; } } multiclass SM_Real_Probe_vi op, string ps> { - def _IMM_vi : SMEM_Real_Store_vi (ps#_IMM)>; - def _SGPR_vi : SMEM_Real_Store_vi (ps#_SGPR)>; + def _IMM_vi : SMEM_Real_Store_Probe_vi (ps#_IMM)>; + def _SGPR_vi : SMEM_Real_Store_Probe_vi (ps#_SGPR)>; } defm S_LOAD_DWORD : SM_Real_Loads_vi <0x00, "S_LOAD_DWORD">; diff --git a/llvm/test/MC/AMDGPU/gfx9_asm_smem.s b/llvm/test/MC/AMDGPU/gfx9_asm_smem.s --- a/llvm/test/MC/AMDGPU/gfx9_asm_smem.s +++ b/llvm/test/MC/AMDGPU/gfx9_asm_smem.s @@ -816,6 +816,9 @@ s_store_dword s1, s[4:5], 0x0 // CHECK: [0x42,0x00,0x42,0xc0,0x00,0x00,0x00,0x00] +s_store_dword s1, s[4:5], s7 offset:0x12345 +// CHECK: [0x42,0x40,0x42,0xc0,0x45,0x23,0x01,0x0e] + s_store_dword s1, s[4:5], s0 glc // CHECK: [0x42,0x00,0x41,0xc0,0x00,0x00,0x00,0x00] diff --git a/llvm/test/MC/Disassembler/AMDGPU/gfx8_dasm_all.txt b/llvm/test/MC/Disassembler/AMDGPU/gfx8_dasm_all.txt --- a/llvm/test/MC/Disassembler/AMDGPU/gfx8_dasm_all.txt +++ b/llvm/test/MC/Disassembler/AMDGPU/gfx8_dasm_all.txt @@ -10264,6 +10264,11 @@ # CHECK: s_store_dword s1, s[4:5], m0 ; encoding: [0x42,0x00,0x40,0xc0,0x7c,0x00,0x00,0x00] 0x42,0x00,0x40,0xc0,0x7c,0x00,0x00,0x00 +# Make sure that raising the GFX9 soffset_en bit doesn't affect GFX8 +# decoding. +# CHECK: s_store_dword s1, s[4:5], m0 ; encoding: [0x42,0x00,0x40,0xc0,0x7c,0x00,0x00,0x00] +0x42,0x40,0x40,0xc0,0x7c,0x00,0x00,0x00 + # CHECK: s_store_dword s101, s[4:5], m0 ; encoding: [0x42,0x19,0x40,0xc0,0x7c,0x00,0x00,0x00] 0x42,0x19,0x40,0xc0,0x7c,0x00,0x00,0x00 @@ -10318,6 +10323,11 @@ # CHECK: s_store_dword s1, s[4:5], 0x7ffff ; encoding: [0x42,0x00,0x42,0xc0,0xff,0xff,0x07,0x00] 0x42,0x00,0x42,0xc0,0xff,0xff,0x07,0x00 +# Make sure that raising the GFX9 soffset_en bit doesn't affect GFX8 +# decoding. +# CHECK: s_store_dword s1, s[4:5], 0x7ffff ; encoding: [0x42,0x00,0x42,0xc0,0xff,0xff,0x07,0x00] +0x42,0x40,0x42,0xc0,0xff,0xff,0x07,0x00 + # CHECK: s_store_dword s1, s[4:5], m0 glc ; encoding: [0x42,0x00,0x41,0xc0,0x7c,0x00,0x00,0x00] 0x42,0x00,0x41,0xc0,0x7c,0x00,0x00,0x00 diff --git a/llvm/test/MC/Disassembler/AMDGPU/gfx9_dasm_all.txt b/llvm/test/MC/Disassembler/AMDGPU/gfx9_dasm_all.txt --- a/llvm/test/MC/Disassembler/AMDGPU/gfx9_dasm_all.txt +++ b/llvm/test/MC/Disassembler/AMDGPU/gfx9_dasm_all.txt @@ -10547,6 +10547,12 @@ # CHECK: s_store_dword s1, s[4:5], s101 ; encoding: [0x42,0x00,0x40,0xc0,0x65,0x00,0x00,0x00] 0x42,0x00,0x40,0xc0,0x65,0x00,0x00,0x00 +# The SGRP variants can alternatively be encoded with imm=0, soffset_en=1 +# and the offset register encoded in the soffset field with the offset +# field being disregarded. +# CHECK: s_store_dword s5, s[2:3], s64 ; encoding: [0x41,0x41,0x40,0xc0,0x00,0x00,0x00,0x80] +0x41,0x41,0x40,0xc0,0x65,0x00,0x00,0x80 + # CHECK: s_store_dword s1, s[4:5], flat_scratch_lo ; encoding: [0x42,0x00,0x40,0xc0,0x66,0x00,0x00,0x00] 0x42,0x00,0x40,0xc0,0x66,0x00,0x00,0x00 @@ -10565,6 +10571,15 @@ # CHECK: s_store_dword s1, s[4:5], 0x0 ; encoding: [0x42,0x00,0x42,0xc0,0x00,0x00,0x00,0x00] 0x42,0x00,0x42,0xc0,0x00,0x00,0x00,0x00 +# CHECK: s_store_dword s1, s[4:5], s7 offset:0x12345 ; encoding: [0x42,0x40,0x42,0xc0,0x45,0x23,0x01,0x0e] +0x42,0x40,0x42,0xc0,0x45,0x23,0x01,0x0e + +# SP3 prefers to decode instructions with imm=1 and soffset_en=1 to the +# form with the 'offset:' modifier, even if the offset is 0. +# CHECK: s_store_dword s5, s[2:3], s0 offset:0x0 ; encoding: [0x41,0x41,0x42,0xc0,0x00,0x00,0x00,0x00] +0x41,0x41,0x42,0xc0,0x00,0x00,0x00,0x00 + + # CHECK: s_store_dword s1, s[4:5], s0 glc ; encoding: [0x42,0x00,0x41,0xc0,0x00,0x00,0x00,0x00] 0x42,0x00,0x41,0xc0,0x00,0x00,0x00,0x00