diff --git a/FEXCore/Source/Interface/Core/JIT/VectorOps.cpp b/FEXCore/Source/Interface/Core/JIT/VectorOps.cpp index 5f6f1a7c7..48a683a28 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 16a6c8004..fe85757a3 100644 --- a/unittests/InstructionCountCI/VEX_map1.json +++ b/unittests/InstructionCountCI/VEX_map1.json @@ -3969,14 +3969,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]" ] },