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);