From 4e7bab849ca297dc3f42cf57b3d53d9d03f7f3f8 Mon Sep 17 00:00:00 2001 From: wannacu Date: Fri, 29 Dec 2023 15:10:33 +0800 Subject: [PATCH] JIT: Fixes broken register in VTBX1 If the Dst register is allocated as VectorIndices or VectorTable, using Dst as an operand to perform the tbx operation will result in an error. For example: %131(FPR0) i128 = LoadNamedVectorIndexedConstant u8:Tmp:RegisterSize, #0x6, #0xaa0 %132(FPR0) i128 = VTBX1 u8:Tmp:RegisterSize, %129(FPRFixed6) i32v4, %126(FPRFixed10) i16v8, %131(FPR0) i128 Since the tbx instruction's destination register is also the original operand, this is consistent with the semantics of VTBX1. Therefore, directly using VectorSrcDst as the destination operand for the tbx instruction is safe. --- .../Interface/Core/JIT/Arm64/VectorOps.cpp | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp b/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp index 00214c3ee..113dfc13e 100644 --- a/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/Arm64/VectorOps.cpp @@ -5009,42 +5009,50 @@ DEF_OP(VTBX1) { if (Dst != VectorSrcDst) { switch (OpSize) { case 8: { - mov(Dst.D(), VectorSrcDst.D()); + mov(VTMP1.D(), VectorSrcDst.D()); + tbx(VTMP1.D(), VectorTable.Q(), VectorIndices.D()); + mov(Dst.D(), VTMP1.D()); break; } case 16: { - mov(Dst.Q(), VectorSrcDst.Q()); + mov(VTMP1.Q(), VectorSrcDst.Q()); + tbx(VTMP1.Q(), VectorTable.Q(), VectorIndices.Q()); + mov(Dst.Q(), VTMP1.Q()); break; } case 32: { - mov(Dst.Z(), VectorSrcDst.Z()); + LOGMAN_THROW_AA_FMT(HostSupportsSVE256, + "Host does not support SVE. Cannot perform 256-bit table lookup"); + mov(VTMP1.Z(), VectorSrcDst.Z()); + tbx(ARMEmitter::SubRegSize::i8Bit, VTMP1.Z(), VectorTable.Z(), VectorIndices.Z()); + mov(Dst.Z(), VTMP1.Z()); break; } default: LOGMAN_MSG_A_FMT("Unknown OpSize: {}", OpSize); break; } - } + } else { + switch (OpSize) { + case 8: { + tbx(VectorSrcDst.D(), VectorTable.Q(), VectorIndices.D()); + break; + } + case 16: { + tbx(VectorSrcDst.Q(), VectorTable.Q(), VectorIndices.Q()); + break; + } + case 32: { + LOGMAN_THROW_AA_FMT(HostSupportsSVE256, + "Host does not support SVE. Cannot perform 256-bit table lookup"); - switch (OpSize) { - case 8: { - tbx(Dst.D(), VectorTable.Q(), VectorIndices.D()); - break; + tbx(ARMEmitter::SubRegSize::i8Bit, VectorSrcDst.Z(), VectorTable.Z(), VectorIndices.Z()); + break; + } + default: + LOGMAN_MSG_A_FMT("Unknown OpSize: {}", OpSize); + break; } - case 16: { - tbx(Dst.Q(), VectorTable.Q(), VectorIndices.Q()); - break; - } - case 32: { - LOGMAN_THROW_AA_FMT(HostSupportsSVE256, - "Host does not support SVE. Cannot perform 256-bit table lookup"); - - tbx(ARMEmitter::SubRegSize::i8Bit, Dst.Z(), VectorTable.Z(), VectorIndices.Z()); - break; - } - default: - LOGMAN_MSG_A_FMT("Unknown OpSize: {}", OpSize); - break; } }