From 76c9833ee50b63634dc528433ecaab289227cf82 Mon Sep 17 00:00:00 2001 From: LC Date: Wed, 17 Jun 2026 03:33:24 -0400 Subject: [PATCH 1/3] [SVE256] Handle SSE insertions for CMPPD/CMPPS See #3799 --- .../Core/OpcodeDispatcher/Vector.cpp | 2 +- unittests/ASM/SSELanePreservation/cmppd.asm | 28 +++++++++++++++++++ unittests/ASM/SSELanePreservation/cmpps.asm | 28 +++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 unittests/ASM/SSELanePreservation/cmppd.asm create mode 100644 unittests/ASM/SSELanePreservation/cmpps.asm diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index 30e7ba7a4..87c6672a9 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -2904,7 +2904,7 @@ void OpDispatchBuilder::VFCMPOp(OpcodeArgs, IR::OpSize ElementSize) { Ref Result = VFCMPOpImpl(OpSizeFromSrc(Op), ElementSize, Dest, Src, CompType & 0b111); - StoreResultFPR(Op, Result); + StoreResult_WithAVXInsert(VectorOpType::SSE, RegClass::FPR, Op, Result); } void OpDispatchBuilder::AVXVFCMPOp(OpcodeArgs, IR::OpSize ElementSize) { diff --git a/unittests/ASM/SSELanePreservation/cmppd.asm b/unittests/ASM/SSELanePreservation/cmppd.asm new file mode 100644 index 000000000..49cc34326 --- /dev/null +++ b/unittests/ASM/SSELanePreservation/cmppd.asm @@ -0,0 +1,28 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM0": ["0xffffffffffffffff", "0x0000000000000000", "0xccdbcfc31f3ff0f3", "0x108390defebac4be"], + "XMM1": ["0xffffffffffffffff", "0x0000000000000000", "0", "0"], + "XMM2": ["0xc4be43cc1ad6970b", "0x4549bd7eb46a1278", "0xf793ef673dac6e4c", "0xbb7b5b3d85d34271"], + "XMM3": ["0x000043cc1ad6970b", "0x4549bd7eb46a1278", "0xf793ef673dac6e4c", "0xbb7b5b3d85d34271"] + } +} +%endif + +vmovaps ymm0, [rel .data] +vmovaps ymm1, [rel .data + (1 * 32)] +vmovaps ymm2, [rel .data + (2 * 32)] +vmovaps ymm3, [rel .data + (3 * 32)] + +cmppd xmm0, xmm1, 1 +vcmppd xmm1, xmm2, xmm3, 1 + +hlt + +align 32 +.data: +dq 0xfdecd28fab3fa4a5, 0x7d7ccd8836d09fc2, 0xccdbcfc31f3ff0f3, 0x108390defebac4be +dq 0x43cc1ad6970b4549, 0xbd7eb46a1278f793, 0xef673dac6e4cbb7b, 0x5b3d85d342718be9 +dq 0xc4be43cc1ad6970b, 0x4549bd7eb46a1278, 0xf793ef673dac6e4c, 0xbb7b5b3d85d34271 +dq 0x000043cc1ad6970b, 0x4549bd7eb46a1278, 0xf793ef673dac6e4c, 0xbb7b5b3d85d34271 diff --git a/unittests/ASM/SSELanePreservation/cmpps.asm b/unittests/ASM/SSELanePreservation/cmpps.asm new file mode 100644 index 000000000..4b136e664 --- /dev/null +++ b/unittests/ASM/SSELanePreservation/cmpps.asm @@ -0,0 +1,28 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM0": ["0xffffffffffffffff", "0x0000000000000000", "0xccdbcfc31f3ff0f3", "0x108390defebac4be"], + "XMM1": ["0xffffffff00000000", "0x0000000000000000", "0", "0"], + "XMM2": ["0xc4be43cc1ad6970b", "0x4549bd7eb46a1278", "0xf793ef673dac6e4c", "0xbb7b5b3d85d34271"], + "XMM3": ["0x000043cc1ad6970b", "0x4549bd7eb46a1278", "0xf793ef673dac6e4c", "0xbb7b5b3d85d34271"] + } +} +%endif + +vmovaps ymm0, [rel .data] +vmovaps ymm1, [rel .data + (1 * 32)] +vmovaps ymm2, [rel .data + (2 * 32)] +vmovaps ymm3, [rel .data + (3 * 32)] + +cmpps xmm0, xmm1, 1 +vcmpps xmm1, xmm2, xmm3, 1 + +hlt + +align 32 +.data: +dq 0xfdecd28fab3fa4a5, 0x7d7ccd8836d09fc2, 0xccdbcfc31f3ff0f3, 0x108390defebac4be +dq 0x43cc1ad6970b4549, 0xbd7eb46a1278f793, 0xef673dac6e4cbb7b, 0x5b3d85d342718be9 +dq 0xc4be43cc1ad6970b, 0x4549bd7eb46a1278, 0xf793ef673dac6e4c, 0xbb7b5b3d85d34271 +dq 0x000043cc1ad6970b, 0x4549bd7eb46a1278, 0xf793ef673dac6e4c, 0xbb7b5b3d85d34271 From e16948bf802a0ef7c249316f87b917eeffe33eab Mon Sep 17 00:00:00 2001 From: LC Date: Wed, 17 Jun 2026 03:51:34 -0400 Subject: [PATCH 2/3] [SVE256] Handle SSE insertions for CVTPD2PS/CVTPS2PD See #3799 --- .../Core/OpcodeDispatcher/Vector.cpp | 5 +++- .../ASM/SSELanePreservation/cvtpd2ps.asm | 25 +++++++++++++++++++ .../ASM/SSELanePreservation/cvtps2pd.asm | 25 +++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 unittests/ASM/SSELanePreservation/cvtpd2ps.asm create mode 100644 unittests/ASM/SSELanePreservation/cvtps2pd.asm diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index 87c6672a9..4e10b8377 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -2706,8 +2706,11 @@ void OpDispatchBuilder::Vector_CVT_Float_To_Float(OpcodeArgs, IR::OpSize DstElem // VCVTPS2PD path Result = _VMov(OpSize::i128Bit, Result); } + + StoreResultFPR(Op, Result); + } else { + StoreResult_WithAVXInsert(VectorOpType::SSE, RegClass::FPR, Op, Result); } - StoreResultFPR(Op, Result); } void OpDispatchBuilder::MMX_To_XMM_Vector_CVT_Int_To_Float(OpcodeArgs) { diff --git a/unittests/ASM/SSELanePreservation/cvtpd2ps.asm b/unittests/ASM/SSELanePreservation/cvtpd2ps.asm new file mode 100644 index 000000000..17ac5b0ed --- /dev/null +++ b/unittests/ASM/SSELanePreservation/cvtpd2ps.asm @@ -0,0 +1,25 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM0": ["0xabf5a3515e60d6b5", "0x0000000000000000", "0xccdbcfc31f3ff0f3", "0x108390defebac4be"], + "XMM1": ["0x6a4debf6e5f21e61", "0x0000000000000000", "0", "0"], + "XMM2": ["0xc4be43cc1ad6970b", "0x4549bd7eb46a1278", "0xf793ef673dac6e4c", "0xbb7b5b3d85d34271"] + } +} +%endif + +vmovaps ymm0, [rel .data] +vmovaps ymm1, [rel .data + (1 * 32)] +vmovaps ymm2, [rel .data + (2 * 32)] + +cvtpd2ps xmm0, xmm1 +vcvtpd2ps xmm1, xmm2 + +hlt + +align 32 +.data: +dq 0xfdecd28fab3fa4a5, 0x7d7ccd8836d09fc2, 0xccdbcfc31f3ff0f3, 0x108390defebac4be +dq 0x43cc1ad6970b4549, 0xbd7eb46a1278f793, 0xef673dac6e4cbb7b, 0x5b3d85d342718be9 +dq 0xc4be43cc1ad6970b, 0x4549bd7eb46a1278, 0xf793ef673dac6e4c, 0xbb7b5b3d85d34271 diff --git a/unittests/ASM/SSELanePreservation/cvtps2pd.asm b/unittests/ASM/SSELanePreservation/cvtps2pd.asm new file mode 100644 index 000000000..4bd9ae402 --- /dev/null +++ b/unittests/ASM/SSELanePreservation/cvtps2pd.asm @@ -0,0 +1,25 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM0": ["0xbae168a920000000", "0x4079835ac0000000", "0xccdbcfc31f3ff0f3", "0x108390defebac4be"], + "XMM1": ["0x3b5ad2e160000000", "0xc097c87980000000", "0", "0"], + "XMM2": ["0xc4be43cc1ad6970b", "0x4549bd7eb46a1278", "0xf793ef673dac6e4c", "0xbb7b5b3d85d34271"] + } +} +%endif + +vmovaps ymm0, [rel .data] +vmovaps ymm1, [rel .data + (1 * 32)] +vmovaps ymm2, [rel .data + (2 * 32)] + +cvtps2pd xmm0, xmm1 +vcvtps2pd xmm1, xmm2 + +hlt + +align 32 +.data: +dq 0xfdecd28fab3fa4a5, 0x7d7ccd8836d09fc2, 0xccdbcfc31f3ff0f3, 0x108390defebac4be +dq 0x43cc1ad6970b4549, 0xbd7eb46a1278f793, 0xef673dac6e4cbb7b, 0x5b3d85d342718be9 +dq 0xc4be43cc1ad6970b, 0x4549bd7eb46a1278, 0xf793ef673dac6e4c, 0xbb7b5b3d85d34271 From 634fbb5a73be3883be6cec5018d4d4536052f746 Mon Sep 17 00:00:00 2001 From: LC Date: Wed, 17 Jun 2026 04:33:38 -0400 Subject: [PATCH 3/3] [SVE256] Handle SSE insertions for Float->Int/Int->Float conversions See #3799 --- .../Source/Interface/Core/OpcodeDispatcher.h | 4 +-- .../Core/OpcodeDispatcher/DDDTables.h | 4 +-- .../Core/OpcodeDispatcher/SecondaryTables.h | 12 ++++----- .../Core/OpcodeDispatcher/Vector.cpp | 18 ++++++++++--- .../Interface/Core/X86Tables/VEXTables.cpp | 12 ++++----- .../ASM/SSELanePreservation/cvtdq2pd.asm | 25 +++++++++++++++++++ .../ASM/SSELanePreservation/cvtdq2ps.asm | 25 +++++++++++++++++++ .../ASM/SSELanePreservation/cvtpd2dq.asm | 25 +++++++++++++++++++ .../ASM/SSELanePreservation/cvtps2dq.asm | 25 +++++++++++++++++++ .../ASM/SSELanePreservation/cvttpd2dq.asm | 25 +++++++++++++++++++ .../ASM/SSELanePreservation/cvttps2dq.asm | 25 +++++++++++++++++++ 11 files changed, 180 insertions(+), 20 deletions(-) create mode 100644 unittests/ASM/SSELanePreservation/cvtdq2pd.asm create mode 100644 unittests/ASM/SSELanePreservation/cvtdq2ps.asm create mode 100644 unittests/ASM/SSELanePreservation/cvtpd2dq.asm create mode 100644 unittests/ASM/SSELanePreservation/cvtps2dq.asm create mode 100644 unittests/ASM/SSELanePreservation/cvttpd2dq.asm create mode 100644 unittests/ASM/SSELanePreservation/cvttps2dq.asm diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 735c9de59..b597d1a71 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -523,9 +523,9 @@ public: void PSRAIOp(OpcodeArgs, IR::OpSize ElementSize); void MOVDDUPOp(OpcodeArgs); void CVTFPR_To_GPR(OpcodeArgs, IR::OpSize SrcElementSize, bool HostRoundingMode); - void Vector_CVT_Int_To_Float(OpcodeArgs, IR::OpSize SrcElementSize, bool Widen); + void Vector_CVT_Int_To_Float(OpcodeArgs, IR::OpSize SrcElementSize, bool Widen, bool IsAVX); void Vector_CVT_Float_To_Float(OpcodeArgs, IR::OpSize DstElementSize, IR::OpSize SrcElementSize, bool IsAVX); - void Vector_CVT_Float_To_Int(OpcodeArgs, IR::OpSize SrcElementSize, bool HostRoundingMode); + void Vector_CVT_Float_To_Int(OpcodeArgs, IR::OpSize SrcElementSize, bool HostRoundingMode, bool IsAVX); void MMX_To_XMM_Vector_CVT_Int_To_Float(OpcodeArgs); void XMM_To_MMX_Vector_CVT_Float_To_Int(OpcodeArgs, IR::OpSize SrcElementSize, bool HostRoundingMode); void MASKMOVOp(OpcodeArgs); diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/DDDTables.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher/DDDTables.h index f45c3a1e9..3aa58f579 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/DDDTables.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/DDDTables.h @@ -5,9 +5,9 @@ namespace FEXCore::IR { constexpr DispatchTableEntry OpDispatch_DDDTable[] = { {0x0C, 1, &OpDispatchBuilder::PI2FWOp}, - {0x0D, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Int_To_Float, OpSize::i32Bit, false>}, + {0x0D, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Int_To_Float, OpSize::i32Bit, false, false>}, {0x1C, 1, &OpDispatchBuilder::PF2IWOp}, - {0x1D, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Int, OpSize::i32Bit, false>}, + {0x1D, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Int, OpSize::i32Bit, false, false>}, {0x86, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorUnaryOp, IR::OP_VFRECPPRECISION, OpSize::i32Bit>}, {0x87, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::RSqrt3DNowOp, false>}, diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/SecondaryTables.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher/SecondaryTables.h index b6ee3332c..1562356fd 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/SecondaryTables.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/SecondaryTables.h @@ -70,7 +70,7 @@ constexpr DispatchTableEntry OpDispatch_TwoByteOpTable[] = { {0x58, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorALUOp, IR::OP_VFADD, OpSize::i32Bit>}, {0x59, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorALUOp, IR::OP_VFMUL, OpSize::i32Bit>}, {0x5A, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Float, OpSize::i64Bit, OpSize::i32Bit, false>}, - {0x5B, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Int_To_Float, OpSize::i32Bit, false>}, + {0x5B, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Int_To_Float, OpSize::i32Bit, false, false>}, {0x5C, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorALUOp, IR::OP_VFSUB, OpSize::i32Bit>}, {0x5D, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorALUOp, IR::OP_VFMIN, OpSize::i32Bit>}, {0x5E, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorALUOp, IR::OP_VFDIV, OpSize::i32Bit>}, @@ -163,7 +163,7 @@ constexpr DispatchTableEntry OpDispatch_SecondaryRepModTables[] = { {0x58, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorScalarInsertALUOp, IR::OP_VFADDSCALARINSERT, OpSize::i32Bit>}, {0x59, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorScalarInsertALUOp, IR::OP_VFMULSCALARINSERT, OpSize::i32Bit>}, {0x5A, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::InsertScalar_CVT_Float_To_Float, OpSize::i64Bit, OpSize::i32Bit>}, - {0x5B, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Int, OpSize::i32Bit, false>}, + {0x5B, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Int, OpSize::i32Bit, false, false>}, {0x5C, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorScalarInsertALUOp, IR::OP_VFSUBSCALARINSERT, OpSize::i32Bit>}, {0x5D, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorScalarInsertALUOp, IR::OP_VFMINSCALARINSERT, OpSize::i32Bit>}, {0x5E, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorScalarInsertALUOp, IR::OP_VFDIVSCALARINSERT, OpSize::i32Bit>}, @@ -177,7 +177,7 @@ constexpr DispatchTableEntry OpDispatch_SecondaryRepModTables[] = { {0xBD, 1, &OpDispatchBuilder::LZCNT}, {0xC2, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::InsertScalarFCMPOp, OpSize::i32Bit>}, {0xD6, 1, &OpDispatchBuilder::MOVQ2DQ}, - {0xE6, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Int_To_Float, OpSize::i32Bit, true>}, + {0xE6, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Int_To_Float, OpSize::i32Bit, true, false>}, }; constexpr DispatchTableEntry OpDispatch_SecondaryRepNEModTables[] = { @@ -204,7 +204,7 @@ constexpr DispatchTableEntry OpDispatch_SecondaryRepNEModTables[] = { {0xD0, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::ADDSUBPOp, OpSize::i32Bit>}, {0xD6, 1, &OpDispatchBuilder::MOVQ2DQ}, {0xC2, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::InsertScalarFCMPOp, OpSize::i64Bit>}, - {0xE6, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Int, OpSize::i64Bit, true>}, + {0xE6, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Int, OpSize::i64Bit, true, false>}, {0xF0, 1, &OpDispatchBuilder::MOVVectorUnalignedOp}, }; @@ -230,7 +230,7 @@ constexpr DispatchTableEntry OpDispatch_SecondaryOpSizeModTables[] = { {0x58, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorALUOp, IR::OP_VFADD, OpSize::i64Bit>}, {0x59, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorALUOp, IR::OP_VFMUL, OpSize::i64Bit>}, {0x5A, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Float, OpSize::i32Bit, OpSize::i64Bit, false>}, - {0x5B, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Int, OpSize::i32Bit, true>}, + {0x5B, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Int, OpSize::i32Bit, true, false>}, {0x5C, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorALUOp, IR::OP_VFSUB, OpSize::i64Bit>}, {0x5D, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorALUOp, IR::OP_VFMIN, OpSize::i64Bit>}, {0x5E, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorALUOp, IR::OP_VFDIV, OpSize::i64Bit>}, @@ -289,7 +289,7 @@ constexpr DispatchTableEntry OpDispatch_SecondaryOpSizeModTables[] = { {0xE3, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorALUOp, IR::OP_VURAVG, OpSize::i16Bit>}, {0xE4, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::PMULHW, false>}, {0xE5, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::PMULHW, true>}, - {0xE6, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Int, OpSize::i64Bit, false>}, + {0xE6, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Int, OpSize::i64Bit, false, false>}, {0xE7, 1, &OpDispatchBuilder::MOVVectorNTOp}, {0xE8, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorALUOp, IR::OP_VSQSUB, OpSize::i8Bit>}, {0xE9, 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VectorALUOp, IR::OP_VSQSUB, OpSize::i16Bit>}, diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index 4e10b8377..823735d5d 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -2616,9 +2616,14 @@ Ref OpDispatchBuilder::Vector_CVT_Int_To_FloatImpl(OpcodeArgs, IR::OpSize SrcEle return _Vector_SToF(Size, ElementSize, Src); } -void OpDispatchBuilder::Vector_CVT_Int_To_Float(OpcodeArgs, IR::OpSize SrcElementSize, bool Widen) { +void OpDispatchBuilder::Vector_CVT_Int_To_Float(OpcodeArgs, IR::OpSize SrcElementSize, bool Widen, bool IsAVX) { Ref Result = Vector_CVT_Int_To_FloatImpl(Op, SrcElementSize, Widen); - StoreResultFPR(Op, Result); + + if (IsAVX) { + StoreResultFPR(Op, Result); + } else { + StoreResult_WithAVXInsert(VectorOpType::SSE, RegClass::FPR, Op, Result); + } } Ref OpDispatchBuilder::Vector_CVT_Float_To_Int32Impl(OpcodeArgs, IR::OpSize DstSize, Ref Src, IR::OpSize SrcSize, IR::OpSize SrcElementSize, @@ -2658,12 +2663,17 @@ Ref OpDispatchBuilder::Vector_CVT_Float_To_Int32Impl(OpcodeArgs, IR::OpSize DstS } } -void OpDispatchBuilder::Vector_CVT_Float_To_Int(OpcodeArgs, IR::OpSize SrcElementSize, bool HostRoundingMode) { +void OpDispatchBuilder::Vector_CVT_Float_To_Int(OpcodeArgs, IR::OpSize SrcElementSize, bool HostRoundingMode, bool IsAVX) { const auto DstSize = OpSizeFromDst(Op); Ref Src = LoadSourceFPR(Op, Op->Src[0], Op->Flags); Ref Result = Vector_CVT_Float_To_Int32Impl(Op, DstSize, Src, OpSizeFromSrc(Op), SrcElementSize, HostRoundingMode, true); - StoreResultFPR_WithOpSize(Op, Op->Dest, Result, DstSize); + + if (IsAVX) { + StoreResultFPR(Op, Result); + } else { + StoreResult_WithAVXInsert(VectorOpType::SSE, RegClass::FPR, Op, Result); + } } Ref OpDispatchBuilder::Scalar_CVT_Float_To_FloatImpl(OpcodeArgs, IR::OpSize DstElementSize, IR::OpSize SrcElementSize, diff --git a/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp b/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp index 366fc68c7..0edbb1971 100644 --- a/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp +++ b/FEXCore/Source/Interface/Core/X86Tables/VEXTables.cpp @@ -554,9 +554,9 @@ namespace AVX256 { {OPD(1, 0b10, 0x5A), 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::AVXInsertScalar_CVT_Float_To_Float, OpSize::i64Bit, OpSize::i32Bit>}, {OPD(1, 0b11, 0x5A), 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::AVXInsertScalar_CVT_Float_To_Float, OpSize::i32Bit, OpSize::i64Bit>}, - {OPD(1, 0b00, 0x5B), 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Int_To_Float, OpSize::i32Bit, false>}, - {OPD(1, 0b01, 0x5B), 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Int, OpSize::i32Bit, true>}, - {OPD(1, 0b10, 0x5B), 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Int, OpSize::i32Bit, false>}, + {OPD(1, 0b00, 0x5B), 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Int_To_Float, OpSize::i32Bit, false, true>}, + {OPD(1, 0b01, 0x5B), 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Int, OpSize::i32Bit, true, true>}, + {OPD(1, 0b10, 0x5B), 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Int, OpSize::i32Bit, false, true>}, {OPD(1, 0b00, 0x5C), 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::AVXVectorALUOp, IR::OP_VFSUB, OpSize::i32Bit>}, {OPD(1, 0b01, 0x5C), 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::AVXVectorALUOp, IR::OP_VFSUB, OpSize::i64Bit>}, @@ -656,9 +656,9 @@ namespace AVX256 { {OPD(1, 0b01, 0xE4), 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VPMULHWOp, false>}, {OPD(1, 0b01, 0xE5), 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::VPMULHWOp, true>}, - {OPD(1, 0b01, 0xE6), 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Int, OpSize::i64Bit, false>}, - {OPD(1, 0b10, 0xE6), 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Int_To_Float, OpSize::i32Bit, true>}, - {OPD(1, 0b11, 0xE6), 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Int, OpSize::i64Bit, true>}, + {OPD(1, 0b01, 0xE6), 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Int, OpSize::i64Bit, false, true>}, + {OPD(1, 0b10, 0xE6), 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Int_To_Float, OpSize::i32Bit, true, true>}, + {OPD(1, 0b11, 0xE6), 1, &OpDispatchBuilder::Bind<&OpDispatchBuilder::Vector_CVT_Float_To_Int, OpSize::i64Bit, true, true>}, {OPD(1, 0b01, 0xE7), 1, &OpDispatchBuilder::MOVVectorNTOp}, diff --git a/unittests/ASM/SSELanePreservation/cvtdq2pd.asm b/unittests/ASM/SSELanePreservation/cvtdq2pd.asm new file mode 100644 index 000000000..fcfb3b8bb --- /dev/null +++ b/unittests/ASM/SSELanePreservation/cvtdq2pd.asm @@ -0,0 +1,25 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM0": ["0xc1da3d2eadc00000", "0x41d0f306b5800000", "0xccdbcfc31f3ff0f3", "0x108390defebac4be"], + "XMM1": ["0x41bad6970b000000", "0xc1cda0de1a000000", "0", "0"], + "XMM2": ["0xc4be43cc1ad6970b", "0x4549bd7eb46a1278", "0xf793ef673dac6e4c", "0xbb7b5b3d85d34271"] + } +} +%endif + +vmovaps ymm0, [rel .data] +vmovaps ymm1, [rel .data + (1 * 32)] +vmovaps ymm2, [rel .data + (2 * 32)] + +cvtdq2pd xmm0, xmm1 +vcvtdq2pd xmm1, xmm2 + +hlt + +align 32 +.data: +dq 0xfdecd28fab3fa4a5, 0x7d7ccd8836d09fc2, 0xccdbcfc31f3ff0f3, 0x108390defebac4be +dq 0x43cc1ad6970b4549, 0xbd7eb46a1278f793, 0xef673dac6e4cbb7b, 0x5b3d85d342718be9 +dq 0xc4be43cc1ad6970b, 0x4549bd7eb46a1278, 0xf793ef673dac6e4c, 0xbb7b5b3d85d34271 diff --git a/unittests/ASM/SSELanePreservation/cvtdq2ps.asm b/unittests/ASM/SSELanePreservation/cvtdq2ps.asm new file mode 100644 index 000000000..b8cde3612 --- /dev/null +++ b/unittests/ASM/SSELanePreservation/cvtdq2ps.asm @@ -0,0 +1,25 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM0": ["0x4e879836ced1e975", "0xce8502974d93c7bd", "0xccdbcfc31f3ff0f3", "0x108390defebac4be"], + "XMM1": ["0xce6d06f14dd6b4b8", "0x4e8a937bce972bdb", "0", "0"], + "XMM2": ["0xc4be43cc1ad6970b", "0x4549bd7eb46a1278", "0xf793ef673dac6e4c", "0xbb7b5b3d85d34271"] + } +} +%endif + +vmovaps ymm0, [rel .data] +vmovaps ymm1, [rel .data + (1 * 32)] +vmovaps ymm2, [rel .data + (2 * 32)] + +cvtdq2ps xmm0, xmm1 +vcvtdq2ps xmm1, xmm2 + +hlt + +align 32 +.data: +dq 0xfdecd28fab3fa4a5, 0x7d7ccd8836d09fc2, 0xccdbcfc31f3ff0f3, 0x108390defebac4be +dq 0x43cc1ad6970b4549, 0xbd7eb46a1278f793, 0xef673dac6e4cbb7b, 0x5b3d85d342718be9 +dq 0xc4be43cc1ad6970b, 0x4549bd7eb46a1278, 0xf793ef673dac6e4c, 0xbb7b5b3d85d34271 diff --git a/unittests/ASM/SSELanePreservation/cvtpd2dq.asm b/unittests/ASM/SSELanePreservation/cvtpd2dq.asm new file mode 100644 index 000000000..d67b1008f --- /dev/null +++ b/unittests/ASM/SSELanePreservation/cvtpd2dq.asm @@ -0,0 +1,25 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM0": ["0x0000000080000000", "0x0000000000000000", "0xccdbcfc31f3ff0f3", "0x108390defebac4be"], + "XMM1": ["0x8000000080000000", "0x0000000000000000", "0", "0"], + "XMM2": ["0xc4be43cc1ad6970b", "0x4549bd7eb46a1278", "0xf793ef673dac6e4c", "0xbb7b5b3d85d34271"] + } +} +%endif + +vmovaps ymm0, [rel .data] +vmovaps ymm1, [rel .data + (1 * 32)] +vmovaps ymm2, [rel .data + (2 * 32)] + +cvtpd2dq xmm0, xmm1 +vcvtpd2dq xmm1, xmm2 + +hlt + +align 32 +.data: +dq 0xfdecd28fab3fa4a5, 0x7d7ccd8836d09fc2, 0xccdbcfc31f3ff0f3, 0x108390defebac4be +dq 0x43cc1ad6970b4549, 0xbd7eb46a1278f793, 0xef673dac6e4cbb7b, 0x5b3d85d342718be9 +dq 0xc4be43cc1ad6970b, 0x4549bd7eb46a1278, 0xf793ef673dac6e4c, 0xbb7b5b3d85d34271 diff --git a/unittests/ASM/SSELanePreservation/cvtps2dq.asm b/unittests/ASM/SSELanePreservation/cvtps2dq.asm new file mode 100644 index 000000000..9902524e0 --- /dev/null +++ b/unittests/ASM/SSELanePreservation/cvtps2dq.asm @@ -0,0 +1,25 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM0": ["0x0000019800000000", "0x0000000000000000", "0xccdbcfc31f3ff0f3", "0x108390defebac4be"], + "XMM1": ["0xfffffa0e00000000", "0x00000c9c00000000", "0", "0"], + "XMM2": ["0xc4be43cc1ad6970b", "0x4549bd7eb46a1278", "0xf793ef673dac6e4c", "0xbb7b5b3d85d34271"] + } +} +%endif + +vmovaps ymm0, [rel .data] +vmovaps ymm1, [rel .data + (1 * 32)] +vmovaps ymm2, [rel .data + (2 * 32)] + +cvtps2dq xmm0, xmm1 +vcvtps2dq xmm1, xmm2 + +hlt + +align 32 +.data: +dq 0xfdecd28fab3fa4a5, 0x7d7ccd8836d09fc2, 0xccdbcfc31f3ff0f3, 0x108390defebac4be +dq 0x43cc1ad6970b4549, 0xbd7eb46a1278f793, 0xef673dac6e4cbb7b, 0x5b3d85d342718be9 +dq 0xc4be43cc1ad6970b, 0x4549bd7eb46a1278, 0xf793ef673dac6e4c, 0xbb7b5b3d85d34271 diff --git a/unittests/ASM/SSELanePreservation/cvttpd2dq.asm b/unittests/ASM/SSELanePreservation/cvttpd2dq.asm new file mode 100644 index 000000000..54f2f0714 --- /dev/null +++ b/unittests/ASM/SSELanePreservation/cvttpd2dq.asm @@ -0,0 +1,25 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM0": ["0x0000000080000000", "0x0000000000000000", "0xccdbcfc31f3ff0f3", "0x108390defebac4be"], + "XMM1": ["0x8000000080000000", "0x0000000000000000", "0", "0"], + "XMM2": ["0xc4be43cc1ad6970b", "0x4549bd7eb46a1278", "0xf793ef673dac6e4c", "0xbb7b5b3d85d34271"] + } +} +%endif + +vmovaps ymm0, [rel .data] +vmovaps ymm1, [rel .data + (1 * 32)] +vmovaps ymm2, [rel .data + (2 * 32)] + +cvttpd2dq xmm0, xmm1 +vcvttpd2dq xmm1, xmm2 + +hlt + +align 32 +.data: +dq 0xfdecd28fab3fa4a5, 0x7d7ccd8836d09fc2, 0xccdbcfc31f3ff0f3, 0x108390defebac4be +dq 0x43cc1ad6970b4549, 0xbd7eb46a1278f793, 0xef673dac6e4cbb7b, 0x5b3d85d342718be9 +dq 0xc4be43cc1ad6970b, 0x4549bd7eb46a1278, 0xf793ef673dac6e4c, 0xbb7b5b3d85d34271 diff --git a/unittests/ASM/SSELanePreservation/cvttps2dq.asm b/unittests/ASM/SSELanePreservation/cvttps2dq.asm new file mode 100644 index 000000000..80fabd181 --- /dev/null +++ b/unittests/ASM/SSELanePreservation/cvttps2dq.asm @@ -0,0 +1,25 @@ +%ifdef CONFIG +{ + "HostFeatures": ["AVX"], + "RegData": { + "XMM0": ["0x0000019800000000", "0x0000000000000000", "0xccdbcfc31f3ff0f3", "0x108390defebac4be"], + "XMM1": ["0xfffffa0e00000000", "0x00000c9b00000000", "0", "0"], + "XMM2": ["0xc4be43cc1ad6970b", "0x4549bd7eb46a1278", "0xf793ef673dac6e4c", "0xbb7b5b3d85d34271"] + } +} +%endif + +vmovaps ymm0, [rel .data] +vmovaps ymm1, [rel .data + (1 * 32)] +vmovaps ymm2, [rel .data + (2 * 32)] + +cvttps2dq xmm0, xmm1 +vcvttps2dq xmm1, xmm2 + +hlt + +align 32 +.data: +dq 0xfdecd28fab3fa4a5, 0x7d7ccd8836d09fc2, 0xccdbcfc31f3ff0f3, 0x108390defebac4be +dq 0x43cc1ad6970b4549, 0xbd7eb46a1278f793, 0xef673dac6e4cbb7b, 0x5b3d85d342718be9 +dq 0xc4be43cc1ad6970b, 0x4549bd7eb46a1278, 0xf793ef673dac6e4c, 0xbb7b5b3d85d34271