diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index daa305092..280c1bce4 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -3857,15 +3857,23 @@ void OpDispatchBuilder::INTOp(OpcodeArgs) { } } -template -void OpDispatchBuilder::PSRLD(OpcodeArgs) { +template +void OpDispatchBuilder::PSRLDOp(OpcodeArgs) { OrderedNode *Src = LoadSource(FPRClass, Op, Op->Src[SrcIndex], Op->Flags, -1); OrderedNode *Dest = LoadSource(FPRClass, Op, Op->Dest, Op->Flags, -1); auto Size = GetSrcSize(Op); - auto Shift = _VUShr(Size, ElementSize, Dest, Src); - StoreResult(FPRClass, Op, Shift, -1); + OrderedNode *Result{}; + + if (Scalar) { + Result = _VUShrS(Size, ElementSize, Dest, Src); + } + else { + Result = _VUShr(Size, ElementSize, Dest, Src); + } + + StoreResult(FPRClass, Op, Result, -1); } template @@ -4814,6 +4822,9 @@ void InstallOpcodeHandlers() { {0xC4, 1, &OpDispatchBuilder::PINSROp<2>}, {0xC6, 1, &OpDispatchBuilder::SHUFOp<8>}, + {0xD1, 1, &OpDispatchBuilder::PSRLDOp<2, true, 0>}, + {0xD2, 1, &OpDispatchBuilder::PSRLDOp<4, true, 0>}, + {0xD3, 1, &OpDispatchBuilder::PSRLDOp<8, true, 0>}, {0xD4, 1, &OpDispatchBuilder::PADDQOp<8>}, // XXX: Causes LLVM to crash if commented out? {0xD6, 1, &OpDispatchBuilder::MOVQOp}, diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 3e73fd6b6..e29ffe26a 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -216,8 +216,8 @@ public: template void PCMPGTOp(OpcodeArgs); void MOVDOp(OpcodeArgs); - template - void PSRLD(OpcodeArgs); + template + void PSRLDOp(OpcodeArgs); template void PSRLI(OpcodeArgs); template diff --git a/unittests/ASM/OpSize/66_D1.asm b/unittests/ASM/OpSize/66_D1.asm new file mode 100644 index 000000000..6a1d5fded --- /dev/null +++ b/unittests/ASM/OpSize/66_D1.asm @@ -0,0 +1,63 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x20A121A222A323A4", "0x28A929AA2AAB2BAC"], + "XMM1": ["0x0041004300450047", "0x0051005300550057"], + "XMM2": ["0x0", "0x0"], + "XMM3": ["0x0", "0x0"], + "XMM4": ["0x0", "0x0"] + }, + "MemoryRegions": { + "0x100000000": "4096" + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434445464748 +mov [rdx + 8 * 0], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 1], rax + +mov rax, 0x1 +mov [rdx + 8 * 2], rax +mov rax, 0x0 +mov [rdx + 8 * 3], rax + +mov rax, 0x8 +mov [rdx + 8 * 4], rax +mov rax, 0x0 +mov [rdx + 8 * 5], rax + +; Will Zero +mov rax, 0x10 +mov [rdx + 8 * 6], rax +mov rax, 0x0 +mov [rdx + 8 * 7], rax + +; Will Zero +mov rax, 0x20 +mov [rdx + 8 * 8], rax +mov rax, 0x0 +mov [rdx + 8 * 9], rax + +; Will Zero +mov rax, 0x40 +mov [rdx + 8 * 10], rax +mov rax, 0x0 +mov [rdx + 8 * 11], rax + +movapd xmm0, [rdx + 8 * 0] +movapd xmm1, [rdx + 8 * 0] +movapd xmm2, [rdx + 8 * 0] +movapd xmm3, [rdx + 8 * 0] +movapd xmm4, [rdx + 8 * 0] + +psrlw xmm0, [rdx + 8 * 2] +psrlw xmm1, [rdx + 8 * 4] +psrlw xmm2, [rdx + 8 * 6] +psrlw xmm3, [rdx + 8 * 8] +psrlw xmm4, [rdx + 8 * 10] + +hlt diff --git a/unittests/ASM/OpSize/66_D2.asm b/unittests/ASM/OpSize/66_D2.asm new file mode 100644 index 000000000..95d7959e3 --- /dev/null +++ b/unittests/ASM/OpSize/66_D2.asm @@ -0,0 +1,62 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x20A121A222A323A4", "0x28A929AA2AAB2BAC"], + "XMM1": ["0x0041424300454647", "0x0051525300555657"], + "XMM2": ["0x0000414200004546", "0x0000515200005556"], + "XMM3": ["0x0", "0x0"], + "XMM4": ["0x0", "0x0"] + }, + "MemoryRegions": { + "0x100000000": "4096" + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434445464748 +mov [rdx + 8 * 0], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 1], rax + +mov rax, 0x1 +mov [rdx + 8 * 2], rax +mov rax, 0x0 +mov [rdx + 8 * 3], rax + +mov rax, 0x8 +mov [rdx + 8 * 4], rax +mov rax, 0x0 +mov [rdx + 8 * 5], rax + +mov rax, 0x10 +mov [rdx + 8 * 6], rax +mov rax, 0x0 +mov [rdx + 8 * 7], rax + +; Will Zero +mov rax, 0x20 +mov [rdx + 8 * 8], rax +mov rax, 0x0 +mov [rdx + 8 * 9], rax + +; Will Zero +mov rax, 0x40 +mov [rdx + 8 * 10], rax +mov rax, 0x0 +mov [rdx + 8 * 11], rax + +movapd xmm0, [rdx + 8 * 0] +movapd xmm1, [rdx + 8 * 0] +movapd xmm2, [rdx + 8 * 0] +movapd xmm3, [rdx + 8 * 0] +movapd xmm4, [rdx + 8 * 0] + +psrld xmm0, [rdx + 8 * 2] +psrld xmm1, [rdx + 8 * 4] +psrld xmm2, [rdx + 8 * 6] +psrld xmm3, [rdx + 8 * 8] +psrld xmm4, [rdx + 8 * 10] + +hlt diff --git a/unittests/ASM/OpSize/66_D3.asm b/unittests/ASM/OpSize/66_D3.asm new file mode 100644 index 000000000..8810db781 --- /dev/null +++ b/unittests/ASM/OpSize/66_D3.asm @@ -0,0 +1,61 @@ +%ifdef CONFIG +{ + "RegData": { + "XMM0": ["0x20A121A222A323A4", "0x28A929AA2AAB2BAC"], + "XMM1": ["0x0041424344454647", "0x0051525354555657"], + "XMM2": ["0x0000414243444546", "0x0000515253545556"], + "XMM3": ["0x0000000041424344", "0x0000000051525354"], + "XMM4": ["0x0", "0x0"] + }, + "MemoryRegions": { + "0x100000000": "4096" + } +} +%endif + +mov rdx, 0xe0000000 + +mov rax, 0x4142434445464748 +mov [rdx + 8 * 0], rax +mov rax, 0x5152535455565758 +mov [rdx + 8 * 1], rax + +mov rax, 0x1 +mov [rdx + 8 * 2], rax +mov rax, 0x0 +mov [rdx + 8 * 3], rax + +mov rax, 0x8 +mov [rdx + 8 * 4], rax +mov rax, 0x0 +mov [rdx + 8 * 5], rax + +mov rax, 0x10 +mov [rdx + 8 * 6], rax +mov rax, 0x0 +mov [rdx + 8 * 7], rax + +mov rax, 0x20 +mov [rdx + 8 * 8], rax +mov rax, 0x0 +mov [rdx + 8 * 9], rax + +; Will Zero +mov rax, 0x40 +mov [rdx + 8 * 10], rax +mov rax, 0x0 +mov [rdx + 8 * 11], rax + +movapd xmm0, [rdx + 8 * 0] +movapd xmm1, [rdx + 8 * 0] +movapd xmm2, [rdx + 8 * 0] +movapd xmm3, [rdx + 8 * 0] +movapd xmm4, [rdx + 8 * 0] + +psrlq xmm0, [rdx + 8 * 2] +psrlq xmm1, [rdx + 8 * 4] +psrlq xmm2, [rdx + 8 * 6] +psrlq xmm3, [rdx + 8 * 8] +psrlq xmm4, [rdx + 8 * 10] + +hlt