From c1e29f9013e9dbd716d5e9f84d5962f880e7c948 Mon Sep 17 00:00:00 2001 From: LC Date: Tue, 30 Jun 2026 05:06:23 -0400 Subject: [PATCH] VectorOps: Eliminate unnecessary moves in VMov if applicable If the destination and source don't match, then we can just zero and insert directly into the destination instead of a temporary. --- .../Source/Interface/Core/JIT/VectorOps.cpp | 22 +++++++++++-------- unittests/InstructionCountCI/VEX_map1.json | 7 +++--- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/FEXCore/Source/Interface/Core/JIT/VectorOps.cpp b/FEXCore/Source/Interface/Core/JIT/VectorOps.cpp index 530fb4b11..d84389e64 100644 --- a/FEXCore/Source/Interface/Core/JIT/VectorOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/VectorOps.cpp @@ -1036,24 +1036,28 @@ DEF_OP(VMov) { const auto Dst = GetVReg(Node); const auto Source = GetVReg(Op->Source); + const auto Sub64BitHandler = [&](ARMEmitter::SubRegSize InsertSize) { + if (Dst != Source) { + movi(ARMEmitter::SubRegSize::i64Bit, Dst.Q(), 0); + ins(InsertSize, Dst, 0, Source, 0); + } else { + movi(ARMEmitter::SubRegSize::i64Bit, VTMP1.Q(), 0); + ins(InsertSize, VTMP1, 0, Source, 0); + mov(Dst.Q(), VTMP1.Q()); + } + }; switch (OpSize) { case IR::OpSize::i8Bit: { - movi(ARMEmitter::SubRegSize::i64Bit, VTMP1.Q(), 0); - ins(ARMEmitter::SubRegSize::i8Bit, VTMP1, 0, Source, 0); - mov(Dst.Q(), VTMP1.Q()); + Sub64BitHandler(ARMEmitter::SubRegSize::i8Bit); break; } case IR::OpSize::i16Bit: { - movi(ARMEmitter::SubRegSize::i64Bit, VTMP1.Q(), 0); - ins(ARMEmitter::SubRegSize::i16Bit, VTMP1, 0, Source, 0); - mov(Dst.Q(), VTMP1.Q()); + Sub64BitHandler(ARMEmitter::SubRegSize::i16Bit); break; } case IR::OpSize::i32Bit: { - movi(ARMEmitter::SubRegSize::i64Bit, VTMP1.Q(), 0); - ins(ARMEmitter::SubRegSize::i32Bit, VTMP1, 0, Source, 0); - mov(Dst.Q(), VTMP1.Q()); + Sub64BitHandler(ARMEmitter::SubRegSize::i32Bit); break; } case IR::OpSize::i64Bit: { diff --git a/unittests/InstructionCountCI/VEX_map1.json b/unittests/InstructionCountCI/VEX_map1.json index 6d7231c04..69b769482 100644 --- a/unittests/InstructionCountCI/VEX_map1.json +++ b/unittests/InstructionCountCI/VEX_map1.json @@ -3970,14 +3970,13 @@ ] }, "vmovd dword [rax], xmm0": { - "ExpectedInstructionCount": 4, + "ExpectedInstructionCount": 3, "Comment": [ "Map 1 0b01 0x7e 128-bit" ], "ExpectedArm64ASM": [ - "movi v0.2d, #0x0", - "mov v0.s[0], v16.s[0]", - "mov v2.16b, v0.16b", + "movi v2.2d, #0x0", + "mov v2.s[0], v16.s[0]", "str s2, [x4]" ] },