diff --git a/llvm/lib/Target/AMDGPU/SMInstructions.td b/llvm/lib/Target/AMDGPU/SMInstructions.td index 348ffd1482941..44c29288ebc63 100644 --- a/llvm/lib/Target/AMDGPU/SMInstructions.td +++ b/llvm/lib/Target/AMDGPU/SMInstructions.td @@ -122,18 +122,19 @@ class SM_Store_Pseudo - : SM_Pseudo { +class SM_Discard_Pseudo + : SM_Pseudo { let mayLoad = 0; let mayStore = 0; let has_glc = 0; let has_sdst = 0; let ScalarStore = 0; let hasSideEffects = 1; - let has_offset = isImm; - let has_soffset = !not(isImm); - let PseudoInstr = opName # !if(isImm, "_IMM", "_SGPR"); + let has_offset = hasOffset; + let has_soffset = hasSOffset; + let PseudoInstr = opName # variant; } multiclass SM_Pseudo_Loads { - def _IMM : SM_Discard_Pseudo ; - def _SGPR : SM_Discard_Pseudo ; + def _IMM : SM_Discard_Pseudo ; + def _SGPR : SM_Discard_Pseudo ; + def _SGPR_IMM : SM_Discard_Pseudo ; } class SM_Time_Pseudo : SM_Pseudo< @@ -529,8 +534,8 @@ class SMEM_Real_vi op, SM_Pseudo ps> : SM_Real , SIMCInstr , Enc64 { - field bit IsGFX9Specific = false; - let AssemblerPredicate = !if(IsGFX9Specific, isGFX9Only, isGFX8GFX9); + field bit IsGFX9SpecificEncoding = false; + let AssemblerPredicate = !if(IsGFX9SpecificEncoding, isGFX9Only, isGFX8GFX9); let DecoderNamespace = "GFX8"; let Inst{5-0} = !if(ps.has_sbase, sbase{6-1}, ?); @@ -540,7 +545,7 @@ class SMEM_Real_vi op, SM_Pseudo ps> // must be defined, whereas in GFX8 it's undefined in all cases, // meaning GFX9 is not perfectly backward-compatible with GFX8, despite // documentation suggesting otherwise. - field bit SOffsetEn = !if(IsGFX9Specific, + field bit SOffsetEn = !if(IsGFX9SpecificEncoding, !if(ps.has_offset, ps.has_soffset, !if(ps.has_soffset, 0, ?)), ?); let Inst{14} = SOffsetEn; @@ -565,7 +570,8 @@ class SMEM_Real_vi op, SM_Pseudo ps> let Inst{52-32} = Offset; // soffset - let Inst{63-57} = !if(!and(IsGFX9Specific, ps.has_soffset), soffset{6-0}, ?); + let Inst{63-57} = !if(!and(IsGFX9SpecificEncoding, ps.has_soffset), + soffset{6-0}, ?); } class SMEM_Real_Load_vi op, string ps, dag offsets> @@ -574,20 +580,26 @@ class SMEM_Real_Load_vi op, string ps, dag offsets> let InOperandList = !con((ins BaseClass:$sbase), offsets, (ins CPol:$cpol)); } +// 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. +class SMEM_Real_SGPR_alt_gfx9 { + bit IsGFX9SpecificEncoding = true; + bit SOffsetEn = 1; + bit Offset = ?; + int Subtarget = SIEncodingFamily.GFX9; + string AsmVariantName = "NonParsable"; +} + multiclass SM_Real_Loads_vi op, string ps> { def _IMM_vi : SMEM_Real_Load_vi ; def _SGPR_vi : SMEM_Real_Load_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_Load_vi ; - def _SGPR_IMM_gfx9 : SMEM_Real_Load_vi < - op, ps#"_SGPR_IMM", (ins SReg_32:$soffset, smem_offset_mod:$offset)>; - } + def _SGPR_alt_gfx9 : SMEM_Real_Load_vi , + SMEM_Real_SGPR_alt_gfx9; + let IsGFX9SpecificEncoding = true in + def _SGPR_IMM_gfx9 : SMEM_Real_Load_vi < + op, ps#"_SGPR_IMM", (ins SReg_32:$soffset, smem_offset_mod:$offset)>; } class SMEM_Real_Store_Base_vi op, SM_Pseudo ps> : SMEM_Real_vi { @@ -609,17 +621,12 @@ class SMEM_Real_Store_vi op, string ps, dag offsets> 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)>; - } + def _SGPR_alt_gfx9 : SMEM_Real_Store_vi , + SMEM_Real_SGPR_alt_gfx9; + let IsGFX9SpecificEncoding = true in + 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> { @@ -748,6 +755,10 @@ defm S_ATOMIC_DEC_X2 : SM_Real_Atomics_vi <0xac, "S_ATOMIC_DEC_X2"> multiclass SM_Real_Discard_vi op, string ps> { def _IMM_vi : SMEM_Real_vi (ps#_IMM)>; def _SGPR_vi : SMEM_Real_vi (ps#_SGPR)>; + def _SGPR_alt_gfx9 : SMEM_Real_vi (ps#_SGPR)>, + SMEM_Real_SGPR_alt_gfx9; + let IsGFX9SpecificEncoding = true in + def _SGPR_IMM_gfx9 : SMEM_Real_vi (ps#_SGPR_IMM)>; } defm S_DCACHE_DISCARD : SM_Real_Discard_vi <0x28, "S_DCACHE_DISCARD">; @@ -1142,6 +1153,7 @@ defm S_ATOMIC_DEC_X2 : SM_Real_Atomics_gfx10 <0xac, "S_ATOMIC_DEC_X multiclass SM_Real_Discard_gfx10 op, string ps> { def _IMM_gfx10 : SMEM_Real_gfx10 (ps#_IMM)>; def _SGPR_gfx10 : SMEM_Real_gfx10 (ps#_SGPR)>; + def _SGPR_IMM_gfx10 : SMEM_Real_gfx10 (ps#_SGPR_IMM)>; } defm S_DCACHE_DISCARD : SM_Real_Discard_gfx10 <0x28, "S_DCACHE_DISCARD">; diff --git a/llvm/test/MC/AMDGPU/gfx10_asm_smem.s b/llvm/test/MC/AMDGPU/gfx10_asm_smem.s index 73559b450f448..ea10c0fb9a8c4 100644 --- a/llvm/test/MC/AMDGPU/gfx10_asm_smem.s +++ b/llvm/test/MC/AMDGPU/gfx10_asm_smem.s @@ -959,12 +959,18 @@ s_dcache_discard s[2:3], s2 s_dcache_discard s[2:3], 100 // GFX10: s_dcache_discard s[2:3], 0x64 ; encoding: [0x01,0x00,0xa0,0xf4,0x64,0x00,0x00,0xfa] +s_dcache_discard s[2:3], s7 offset:100 +// GFX10: s_dcache_discard s[2:3], s7 offset:0x64 ; encoding: [0x01,0x00,0xa0,0xf4,0x64,0x00,0x00,0x0e] + s_dcache_discard_x2 s[2:3], s2 // GFX10: s_dcache_discard_x2 s[2:3], s2 ; encoding: [0x01,0x00,0xa4,0xf4,0x00,0x00,0x00,0x04] s_dcache_discard_x2 s[2:3], 100 // GFX10: s_dcache_discard_x2 s[2:3], 0x64 ; encoding: [0x01,0x00,0xa4,0xf4,0x64,0x00,0x00,0xfa] +s_dcache_discard_x2 s[2:3], s7 offset:100 +// GFX10: s_dcache_discard_x2 s[2:3], s7 offset:0x64 ; encoding: [0x01,0x00,0xa4,0xf4,0x64,0x00,0x00,0x0e] + s_atomic_add s5, s[2:3], s101 // GFX10: encoding: [0x41,0x01,0x08,0xf6,0x00,0x00,0x00,0xca] diff --git a/llvm/test/MC/AMDGPU/gfx11_asm_smem.s b/llvm/test/MC/AMDGPU/gfx11_asm_smem.s index d230a216f8a33..11abe7ae83456 100644 --- a/llvm/test/MC/AMDGPU/gfx11_asm_smem.s +++ b/llvm/test/MC/AMDGPU/gfx11_asm_smem.s @@ -812,6 +812,9 @@ s_dcache_discard s[2:3], s2 s_dcache_discard s[2:3], 100 // GFX11-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU +s_dcache_discard s[2:3], s7 offset:100 +// GFX11-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU + s_dcache_discard_x2 s[2:3], s2 // GFX11-ERR: :[[@LINE-1]]:{{[0-9]+}}: error: instruction not supported on this GPU diff --git a/llvm/test/MC/AMDGPU/gfx9_asm_smem.s b/llvm/test/MC/AMDGPU/gfx9_asm_smem.s index 66ef4cde4623c..1d17aa64b69d8 100644 --- a/llvm/test/MC/AMDGPU/gfx9_asm_smem.s +++ b/llvm/test/MC/AMDGPU/gfx9_asm_smem.s @@ -1452,6 +1452,9 @@ s_dcache_discard s[2:3], m0 s_dcache_discard s[2:3], 0x0 // CHECK: [0x01,0x00,0xa2,0xc0,0x00,0x00,0x00,0x00] +s_dcache_discard s[2:3], s7 offset:0x0 +// CHECK: [0x01,0x40,0xa2,0xc0,0x00,0x00,0x00,0x0e] + s_dcache_discard_x2 s[2:3], s0 // CHECK: [0x01,0x00,0xa4,0xc0,0x00,0x00,0x00,0x00] @@ -1494,6 +1497,9 @@ s_dcache_discard_x2 s[2:3], m0 s_dcache_discard_x2 s[2:3], 0x0 // CHECK: [0x01,0x00,0xa6,0xc0,0x00,0x00,0x00,0x00] +s_dcache_discard_x2 s[2:3], s7 offset:0x0 +// CHECK: [0x01,0x40,0xa6,0xc0,0x00,0x00,0x00,0x0e] + s_buffer_atomic_swap s5, s[4:7], s0 // CHECK: [0x42,0x01,0x00,0xc1,0x00,0x00,0x00,0x00] diff --git a/llvm/test/MC/Disassembler/AMDGPU/gfx10_dasm_all.txt b/llvm/test/MC/Disassembler/AMDGPU/gfx10_dasm_all.txt index d7acd256e0158..67f829c0378e0 100644 --- a/llvm/test/MC/Disassembler/AMDGPU/gfx10_dasm_all.txt +++ b/llvm/test/MC/Disassembler/AMDGPU/gfx10_dasm_all.txt @@ -13628,12 +13628,18 @@ # GFX10: s_dcache_discard s[2:3], s2 ; encoding: [0x01,0x00,0xa0,0xf4,0x00,0x00,0x00,0x04] 0x01,0x00,0xa0,0xf4,0x00,0x00,0x00,0x04 +# GFX10: s_dcache_discard s[2:3], s2 offset:0x12345 ; encoding: [0x01,0x00,0xa0,0xf4,0x45,0x23,0x01,0x04] +0x01,0x00,0xa0,0xf4,0x45,0x23,0x01,0x04 + # GFX10: s_dcache_discard_x2 s[2:3], 0x64 ; encoding: [0x01,0x00,0xa4,0xf4,0x64,0x00,0x00,0xfa] 0x01,0x00,0xa4,0xf4,0x64,0x00,0x00,0xfa # GFX10: s_dcache_discard_x2 s[2:3], s2 ; encoding: [0x01,0x00,0xa4,0xf4,0x00,0x00,0x00,0x04] 0x01,0x00,0xa4,0xf4,0x00,0x00,0x00,0x04 +# GFX10: s_dcache_discard_x2 s[2:3], s2 offset:0x12345 ; encoding: [0x01,0x00,0xa4,0xf4,0x45,0x23,0x01,0x04] +0x01,0x00,0xa4,0xf4,0x45,0x23,0x01,0x04 + # GFX10: s_dcache_inv ; encoding: [0x00,0x00,0x80,0xf4,0x00,0x00,0x00,0x00] 0x00,0x00,0x80,0xf4,0x00,0x00,0x00,0x00 diff --git a/llvm/test/MC/Disassembler/AMDGPU/smem_gfx9.txt b/llvm/test/MC/Disassembler/AMDGPU/smem_gfx9.txt index 849736ef3549b..ca8cfa7af1d0c 100644 --- a/llvm/test/MC/Disassembler/AMDGPU/smem_gfx9.txt +++ b/llvm/test/MC/Disassembler/AMDGPU/smem_gfx9.txt @@ -38,15 +38,27 @@ # GFX9: s_dcache_discard s[100:101], s0 ; encoding: [0x32,0x00,0xa0,0xc0,0x00,0x00,0x00,0x00] 0x32,0x00,0xa0,0xc0,0x00,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. +# GFX9: s_dcache_discard s[100:101], s64 ; encoding: [0x32,0x40,0xa0,0xc0,0x00,0x00,0x00,0x80] +0x32,0x40,0xa0,0xc0,0x25,0x00,0x00,0x80 + # GFX9: s_dcache_discard s[2:3], 0x0 ; encoding: [0x01,0x00,0xa2,0xc0,0x00,0x00,0x00,0x00] 0x01,0x00,0xa2,0xc0,0x00,0x00,0x00,0x00 +# GFX9: s_dcache_discard s[2:3], s2 offset:0x12345 ; encoding: [0x01,0x40,0xa2,0xc0,0x45,0x23,0x01,0x04] +0x01,0x40,0xa2,0xc0,0x45,0x23,0x01,0x04 + # GFX9: s_dcache_discard_x2 s[2:3], s101 ; encoding: [0x01,0x00,0xa4,0xc0,0x65,0x00,0x00,0x00] 0x01,0x00,0xa4,0xc0,0x65,0x00,0x00,0x00 # GFX9: s_dcache_discard_x2 s[2:3], 0x0 ; encoding: [0x01,0x00,0xa6,0xc0,0x00,0x00,0x00,0x00] 0x01,0x00,0xa6,0xc0,0x00,0x00,0x00,0x00 +# GFX9: s_dcache_discard_x2 s[2:3], s2 offset:0x12345 ; encoding: [0x01,0x40,0xa6,0xc0,0x45,0x23,0x01,0x04] +0x01,0x40,0xa6,0xc0,0x45,0x23,0x01,0x04 + #===------------------------------------------------------------------------===# # s_atomic #===------------------------------------------------------------------------===#