From 12a4dd6d2d94e6a777ea374a4e2f59eeddeac35a Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Thu, 24 Sep 2020 23:09:43 -0700 Subject: [PATCH] Fixes VExtr in the ARM64 JIT for 8byte registers We only expected 16byte registers before --- .../Interface/Core/JIT/Arm64/VectorOps.cpp | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp index cc3bc295b..bfb01cb58 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp @@ -1548,8 +1548,29 @@ DEF_OP(VExtractElement) { DEF_OP(VExtr) { auto Op = IROp->C(); + uint8_t OpSize = IROp->Size; + // AArch64 ext op has bit arrangement as [Vm:Vn] so arguments need to be swapped - ext(GetDst(Node).V16B(), GetSrc(Op->Header.Args[1].ID()).V16B(), GetSrc(Op->Header.Args[0].ID()).V16B(), Op->Index * Op->Header.ElementSize); + auto UpperBits = GetSrc(Op->Header.Args[0].ID()); + auto LowerBits = GetSrc(Op->Header.Args[1].ID()); + auto Index = Op->Index; + + if (Index >= OpSize) { + // Upper bits have moved in to the lower bits + LowerBits = UpperBits; + + // Upper bits are all now zero + UpperBits = VTMP1; + eor(VTMP1.V16B(), VTMP1.V16B(), VTMP1.V16B()); + Index -= OpSize; + } + + if (OpSize == 8) { + ext(GetDst(Node).V8B(), LowerBits.V8B(), UpperBits.V8B(), Index * Op->Header.ElementSize); + } + else { + ext(GetDst(Node).V16B(), LowerBits.V16B(), UpperBits.V16B(), Index * Op->Header.ElementSize); + } } DEF_OP(VSLI) {