From aed8be3568048156019a9d8589cd43b6b3a58835 Mon Sep 17 00:00:00 2001 From: ParantezTech <12572227+par274@users.noreply.github.com> Date: Sun, 20 Sep 2026 19:39:30 +0300 Subject: [PATCH] [spirvtranslator] Added V_CMPX_NE_U64 instruction --- .../Gen5SpirvTranslator.Alu.cs | 11 +++++++++-- .../Gen5ShaderTranslator.cs | 1 + .../Agc/Gen5ShaderAtomicDecodeTests.cs | 14 ++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.Alu.cs b/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.Alu.cs index 4db415c..0f2ba19 100644 --- a/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.Alu.cs +++ b/src/SharpEmu.ShaderCompiler.Vulkan/Gen5SpirvTranslator.Alu.cs @@ -1783,8 +1783,14 @@ public static partial class Gen5SpirvTranslator } else if (opcode is not ("VCmpClassF32" or "VCmpxClassF32")) { - var left = GetRawSource(instruction, 0); - var right = GetRawSource(instruction, 1); + var compare64 = opcode.EndsWith("U64", StringComparison.Ordinal) || + opcode.EndsWith("I64", StringComparison.Ordinal); + var left = compare64 + ? GetRawSource64(instruction, 0) + : GetRawSource(instruction, 0); + var right = compare64 + ? GetRawSource64(instruction, 1) + : GetRawSource(instruction, 1); var signed = opcode.EndsWith("I32", StringComparison.Ordinal); if (signed) { @@ -1798,6 +1804,7 @@ public static partial class Gen5SpirvTranslator "VCmpEqU32" or "VCmpxEqU32" => SpirvOp.IEqual, "VCmpNeI32" or "VCmpxNeI32" or "VCmpNeU32" or "VCmpxNeU32" => SpirvOp.INotEqual, + "VCmpxNeU64" => SpirvOp.INotEqual, "VCmpLtI32" or "VCmpxLtI32" => SpirvOp.SLessThan, "VCmpLeI32" or "VCmpxLeI32" => SpirvOp.SLessThanEqual, "VCmpGtI32" or "VCmpxGtI32" => SpirvOp.SGreaterThan, diff --git a/src/SharpEmu.ShaderCompiler/Gen5ShaderTranslator.cs b/src/SharpEmu.ShaderCompiler/Gen5ShaderTranslator.cs index 818176d..7cd6b1e 100644 --- a/src/SharpEmu.ShaderCompiler/Gen5ShaderTranslator.cs +++ b/src/SharpEmu.ShaderCompiler/Gen5ShaderTranslator.cs @@ -1010,6 +1010,7 @@ public static partial class Gen5ShaderTranslator 0xED => "VCmpNeqF16", 0xEE => "VCmpNltF16", 0xEF => "VCmpTruF16", + 0xF5 => "VCmpxNeU64", 0xF8 => "VCmpxUF16", 0xF9 => "VCmpxNgeF16", 0xFA => "VCmpxNlgF16", diff --git a/tests/SharpEmu.Libs.Tests/Agc/Gen5ShaderAtomicDecodeTests.cs b/tests/SharpEmu.Libs.Tests/Agc/Gen5ShaderAtomicDecodeTests.cs index 7a10c8d..7a211ab 100644 --- a/tests/SharpEmu.Libs.Tests/Agc/Gen5ShaderAtomicDecodeTests.cs +++ b/tests/SharpEmu.Libs.Tests/Agc/Gen5ShaderAtomicDecodeTests.cs @@ -143,6 +143,20 @@ public sealed class Gen5ShaderAtomicDecodeTests Assert.False(control.Gds); } + [Fact] + public void VCmpxNeU64_DecodesVectorRegisterPairs() + { + // V_CMPX_NE_U64 v[0:1], v[3:4]. The translator consumes each encoded + // source as the low register of a 64-bit pair and updates EXEC. + var instruction = DecodeSingle(0x7DEA0700); + + Assert.Equal("VCmpxNeU64", instruction.Opcode); + Assert.Equal( + new[] { Gen5Operand.Vector(0), Gen5Operand.Vector(3) }, + instruction.Sources); + Assert.Empty(instruction.Destinations); + } + private static Gen5ShaderInstruction DecodeSingle(params uint[] words) { var memory = new FakeCpuMemory(ShaderAddress, 0x1000);