diff --git a/Source/Interface/Core/Interpreter/InterpreterCore.cpp b/Source/Interface/Core/Interpreter/InterpreterCore.cpp index 3e4c7b5b5..6b5e338bf 100644 --- a/Source/Interface/Core/Interpreter/InterpreterCore.cpp +++ b/Source/Interface/Core/Interpreter/InterpreterCore.cpp @@ -2966,7 +2966,34 @@ void InterpreterCore::ExecuteCode(FEXCore::Core::InternalThreadState *Thread) { memcpy(GDP, Tmp, Op->RegisterSize); break; } + case IR::OP_VFCMPNEQ: { + auto Op = IROp->C(); + void *Src1 = GetSrc(Op->Header.Args[0]); + void *Src2 = GetSrc(Op->Header.Args[1]); + auto Func = [](auto a, auto b) { return a != b ? ~0ULL : 0; }; + + uint8_t Tmp[16]; + uint8_t Elements = Op->RegisterSize / Op->ElementSize; + + if (Op->ElementSize == Op->RegisterSize) { + switch (Op->ElementSize) { + DO_SCALAR_COMPARE_OP(4, float, uint32_t, Func); + DO_SCALAR_COMPARE_OP(8, double, uint64_t, Func); + default: LogMan::Msg::A("Unsupported elementSize: %d", Op->ElementSize); + } + } + else { + switch (Op->ElementSize) { + DO_VECTOR_COMPARE_OP(4, float, uint32_t, Func); + DO_VECTOR_COMPARE_OP(8, double, uint64_t, Func); + default: LogMan::Msg::A("Unsupported elementSize: %d", Op->ElementSize); + } + } + + memcpy(GDP, Tmp, Op->RegisterSize); + break; + } case IR::OP_VFCMPLT: { auto Op = IROp->C(); void *Src1 = GetSrc(Op->Header.Args[0]); diff --git a/Source/Interface/Core/OpcodeDispatcher.cpp b/Source/Interface/Core/OpcodeDispatcher.cpp index b5c0e255c..c95c3a123 100644 --- a/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/Source/Interface/Core/OpcodeDispatcher.cpp @@ -3988,6 +3988,9 @@ void OpDispatchBuilder::VFCMPOp(OpcodeArgs) { case 0x02: case 0x0A: case 0x12: case 0x1A: // LE, GE(Swapped operand) Result = _VFCMPLE(Size, ElementSize, Dest, Src); break; + case 0x04: case 0x0C: case 0x14: case 0x1C: // NEQ + Result = _VFCMPNEQ(Size, ElementSize, Dest, Src); + break; case 0x05: case 0x0D: case 0x15: case 0x1D: // NLT, NGT(Swapped operand) Result = _VFCMPLE(Size, ElementSize, Src, Dest); break; diff --git a/Source/Interface/Core/OpcodeDispatcher.h b/Source/Interface/Core/OpcodeDispatcher.h index 5772da6e2..6b04f7de0 100644 --- a/Source/Interface/Core/OpcodeDispatcher.h +++ b/Source/Interface/Core/OpcodeDispatcher.h @@ -365,6 +365,9 @@ public: IRPair _VFCMPEQ(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, OrderedNode *ssa1) { return _VFCMPEQ(ssa0, ssa1, RegisterSize, ElementSize); } + IRPair _VFCMPNEQ(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, OrderedNode *ssa1) { + return _VFCMPNEQ(ssa0, ssa1, RegisterSize, ElementSize); + } IRPair _VFCMPLT(uint8_t RegisterSize, uint8_t ElementSize, OrderedNode *ssa0, OrderedNode *ssa1) { return _VFCMPLT(ssa0, ssa1, RegisterSize, ElementSize); } diff --git a/Source/Interface/IR/IR.json b/Source/Interface/IR/IR.json index 9434671b0..d470121e4 100644 --- a/Source/Interface/IR/IR.json +++ b/Source/Interface/IR/IR.json @@ -852,6 +852,15 @@ ] }, + "VFCMPNEQ": { + "HasDest": true, + "SSAArgs": "2", + "Args": [ + "uint8_t", "RegisterSize", + "uint8_t", "ElementSize" + ] + }, + "VFCMPLT": { "HasDest": true, "SSAArgs": "2",