From 23918e25c2e50a3c06ed8c8d6f96e332ad604693 Mon Sep 17 00:00:00 2001 From: TellowKrinkle Date: Sun, 1 Jun 2025 18:42:40 -0500 Subject: [PATCH] Common: Switch CVT instructions to auto SSE/AVX --- common/emitter/instructions.h | 20 ++++-- common/emitter/simd.cpp | 65 ++++++++++--------- .../common/x86emitter/codegen_tests_main.cpp | 44 +++++++++++++ 3 files changed, 91 insertions(+), 38 deletions(-) diff --git a/common/emitter/instructions.h b/common/emitter/instructions.h index 2e68794f59..13c0d6652b 100644 --- a/common/emitter/instructions.h +++ b/common/emitter/instructions.h @@ -565,15 +565,23 @@ namespace x86Emitter extern void xCVTSD2SI(const xRegister32or64& to, const xRegisterSSE& from); extern void xCVTSD2SI(const xRegister32or64& to, const xIndirect64& from); - extern void xCVTSD2SS(const xRegisterSSE& to, const xRegisterSSE& from); - extern void xCVTSD2SS(const xRegisterSSE& to, const xIndirect64& from); - extern void xCVTSI2SS(const xRegisterSSE& to, const xRegister32or64& from); - extern void xCVTSI2SS(const xRegisterSSE& to, const xIndirect32& from); + extern void xCVTSD2SS(const xRegisterSSE& dst, const xRegisterSSE& src1, const xRegisterSSE& src2); + extern void xCVTSD2SS(const xRegisterSSE& dst, const xRegisterSSE& src1, const xIndirect64& src2); + extern void xCVTSI2SS(const xRegisterSSE& dst, const xRegisterSSE& src1, const xRegister32or64& src2); + extern void xCVTSI2SS(const xRegisterSSE& dst, const xRegisterSSE& src1, const xIndirect32& src2); + extern void xCVTSI2SS(const xRegisterSSE& dst, const xRegisterSSE& src1, const xIndirect64& src2); + static void xCVTSD2SS(const xRegisterSSE& to, const xRegisterSSE& from) { xCVTSD2SS(to, to, from); } + static void xCVTSD2SS(const xRegisterSSE& to, const xIndirect64& from) { xCVTSD2SS(to, to, from); } + static void xCVTSI2SS(const xRegisterSSE& to, const xRegister32or64& from) { xCVTSI2SS(to, to, from); } + static void xCVTSI2SS(const xRegisterSSE& to, const xIndirect32& from) { xCVTSI2SS(to, to, from); } + static void xCVTSI2SS(const xRegisterSSE& to, const xIndirect64& from) { xCVTSI2SS(to, to, from); } - extern void xCVTSS2SD(const xRegisterSSE& to, const xRegisterSSE& from); - extern void xCVTSS2SD(const xRegisterSSE& to, const xIndirect32& from); extern void xCVTSS2SI(const xRegister32or64& to, const xRegisterSSE& from); extern void xCVTSS2SI(const xRegister32or64& to, const xIndirect32& from); + extern void xCVTSS2SD(const xRegisterSSE& dst, const xRegisterSSE& src1, const xRegisterSSE& src2); + extern void xCVTSS2SD(const xRegisterSSE& dst, const xRegisterSSE& src1, const xIndirect32& src2); + static void xCVTSS2SD(const xRegisterSSE& to, const xRegisterSSE& from) { xCVTSS2SD(to, to, from); } + static void xCVTSS2SD(const xRegisterSSE& to, const xIndirect32& from) { xCVTSS2SD(to, to, from); } extern void xCVTTPD2DQ(const xRegisterSSE& to, const xRegisterSSE& from); extern void xCVTTPD2DQ(const xRegisterSSE& to, const xIndirect128& from); diff --git a/common/emitter/simd.cpp b/common/emitter/simd.cpp index f231db124f..fb1ebe9b78 100644 --- a/common/emitter/simd.cpp +++ b/common/emitter/simd.cpp @@ -229,45 +229,46 @@ namespace x86Emitter // nature of the functions. (so if a function expects an m32, you must use (u32*) or ptr32[]). // - __fi void xCVTDQ2PD(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0xf3, 0xe6); } - __fi void xCVTDQ2PD(const xRegisterSSE& to, const xIndirect64& from) { OpWriteSSE(0xf3, 0xe6); } - __fi void xCVTDQ2PS(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0x00, 0x5b); } - __fi void xCVTDQ2PS(const xRegisterSSE& to, const xIndirect128& from) { OpWriteSSE(0x00, 0x5b); } + __fi void xCVTDQ2PD(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0xe6).pf3()); } + __fi void xCVTDQ2PD(const xRegisterSSE& to, const xIndirect64& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0xe6).pf3()); } + __fi void xCVTDQ2PS(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x5b)); } + __fi void xCVTDQ2PS(const xRegisterSSE& to, const xIndirect128& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x5b)); } - __fi void xCVTPD2DQ(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0xf2, 0xe6); } - __fi void xCVTPD2DQ(const xRegisterSSE& to, const xIndirect128& from) { OpWriteSSE(0xf2, 0xe6); } - __fi void xCVTPD2PS(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0x66, 0x5a); } - __fi void xCVTPD2PS(const xRegisterSSE& to, const xIndirect128& from) { OpWriteSSE(0x66, 0x5a); } + __fi void xCVTPD2DQ(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0xe6).pf2()); } + __fi void xCVTPD2DQ(const xRegisterSSE& to, const xIndirect128& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0xe6).pf2()); } + __fi void xCVTPD2PS(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x5a).p66()); } + __fi void xCVTPD2PS(const xRegisterSSE& to, const xIndirect128& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x5a).p66()); } - __fi void xCVTPI2PD(const xRegisterSSE& to, const xIndirect64& from) { OpWriteSSE(0x66, 0x2a); } - __fi void xCVTPI2PS(const xRegisterSSE& to, const xIndirect64& from) { OpWriteSSE(0x00, 0x2a); } + __fi void xCVTPI2PD(const xRegisterSSE& to, const xIndirect64& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x2a).p66()); } + __fi void xCVTPI2PS(const xRegisterSSE& to, const xIndirect64& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x2a)); } - __fi void xCVTPS2DQ(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0x66, 0x5b); } - __fi void xCVTPS2DQ(const xRegisterSSE& to, const xIndirect128& from) { OpWriteSSE(0x66, 0x5b); } - __fi void xCVTPS2PD(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0x00, 0x5a); } - __fi void xCVTPS2PD(const xRegisterSSE& to, const xIndirect64& from) { OpWriteSSE(0x00, 0x5a); } + __fi void xCVTPS2DQ(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x5b).p66()); } + __fi void xCVTPS2DQ(const xRegisterSSE& to, const xIndirect128& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x5b).p66()); } + __fi void xCVTPS2PD(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x5a)); } + __fi void xCVTPS2PD(const xRegisterSSE& to, const xIndirect64& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x5a)); } - __fi void xCVTSD2SI(const xRegister32or64& to, const xRegisterSSE& from) { OpWriteSSE(0xf2, 0x2d); } - __fi void xCVTSD2SI(const xRegister32or64& to, const xIndirect64& from) { OpWriteSSE(0xf2, 0x2d); } - __fi void xCVTSD2SS(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0xf2, 0x5a); } - __fi void xCVTSD2SS(const xRegisterSSE& to, const xIndirect64& from) { OpWriteSSE(0xf2, 0x5a); } - __fi void xCVTSI2SS(const xRegisterSSE& to, const xRegister32or64& from) { OpWriteSSE(0xf3, 0x2a); } - __fi void xCVTSI2SS(const xRegisterSSE& to, const xIndirect32& from) { OpWriteSSE(0xf3, 0x2a); } + __fi void xCVTSD2SI(const xRegister32or64& to, const xRegisterSSE& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x2d).dstw().pf2()); } + __fi void xCVTSD2SI(const xRegister32or64& to, const xIndirect64& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x2d).dstw().pf2()); } + __fi void xCVTSD2SS(const xRegisterSSE& dst, const xRegisterSSE& src1, const xRegisterSSE& src2) { EmitSIMD(SIMDInstructionInfo(0x5a).pf2(), dst, src1, src2); } + __fi void xCVTSD2SS(const xRegisterSSE& dst, const xRegisterSSE& src1, const xIndirect64& src2) { EmitSIMD(SIMDInstructionInfo(0x5a).pf2(), dst, src1, src2); } + __fi void xCVTSI2SS(const xRegisterSSE& dst, const xRegisterSSE& src1, const xRegister32or64& src2) { EmitSIMD(SIMDInstructionInfo(0x2a).srcw().pf3(), dst, src1, src2); } + __fi void xCVTSI2SS(const xRegisterSSE& dst, const xRegisterSSE& src1, const xIndirect32& src2) { EmitSIMD(SIMDInstructionInfo(0x2a).srcw().pf3(), dst, src1, src2); } + __fi void xCVTSI2SS(const xRegisterSSE& dst, const xRegisterSSE& src1, const xIndirect64& src2) { EmitSIMD(SIMDInstructionInfo(0x2a).srcw().pf3(), dst, src1, src2); } - __fi void xCVTSS2SD(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0xf3, 0x5a); } - __fi void xCVTSS2SD(const xRegisterSSE& to, const xIndirect32& from) { OpWriteSSE(0xf3, 0x5a); } - __fi void xCVTSS2SI(const xRegister32or64& to, const xRegisterSSE& from) { OpWriteSSE(0xf3, 0x2d); } - __fi void xCVTSS2SI(const xRegister32or64& to, const xIndirect32& from) { OpWriteSSE(0xf3, 0x2d); } + __fi void xCVTSS2SI(const xRegister32or64& to, const xRegisterSSE& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x2d).dstw().pf3()); } + __fi void xCVTSS2SI(const xRegister32or64& to, const xIndirect32& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x2d).dstw().pf3()); } + __fi void xCVTSS2SD(const xRegisterSSE& dst, const xRegisterSSE& src1, const xRegisterSSE& src2) { EmitSIMD(SIMDInstructionInfo(0x5a).pf3(), dst, src1, src2); } + __fi void xCVTSS2SD(const xRegisterSSE& dst, const xRegisterSSE& src1, const xIndirect32& src2) { EmitSIMD(SIMDInstructionInfo(0x5a).pf3(), dst, src1, src2); } - __fi void xCVTTPD2DQ(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0x66, 0xe6); } - __fi void xCVTTPD2DQ(const xRegisterSSE& to, const xIndirect128& from) { OpWriteSSE(0x66, 0xe6); } - __fi void xCVTTPS2DQ(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSSE(0xf3, 0x5b); } - __fi void xCVTTPS2DQ(const xRegisterSSE& to, const xIndirect128& from) { OpWriteSSE(0xf3, 0x5b); } + __fi void xCVTTPD2DQ(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0xe6).p66()); } + __fi void xCVTTPD2DQ(const xRegisterSSE& to, const xIndirect128& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0xe6).p66()); } + __fi void xCVTTPS2DQ(const xRegisterSSE& to, const xRegisterSSE& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x5b).pf3()); } + __fi void xCVTTPS2DQ(const xRegisterSSE& to, const xIndirect128& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x5b).pf3()); } - __fi void xCVTTSD2SI(const xRegister32or64& to, const xRegisterSSE& from) { OpWriteSSE(0xf2, 0x2c); } - __fi void xCVTTSD2SI(const xRegister32or64& to, const xIndirect64& from) { OpWriteSSE(0xf2, 0x2c); } - __fi void xCVTTSS2SI(const xRegister32or64& to, const xRegisterSSE& from) { OpWriteSSE(0xf3, 0x2c); } - __fi void xCVTTSS2SI(const xRegister32or64& to, const xIndirect32& from) { OpWriteSSE(0xf3, 0x2c); } + __fi void xCVTTSD2SI(const xRegister32or64& to, const xRegisterSSE& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x2c).dstw().pf2()); } + __fi void xCVTTSD2SI(const xRegister32or64& to, const xIndirect64& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x2c).dstw().pf2()); } + __fi void xCVTTSS2SI(const xRegister32or64& to, const xRegisterSSE& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x2c).dstw().pf3()); } + __fi void xCVTTSS2SI(const xRegister32or64& to, const xIndirect32& from) { OpWriteSIMDMovOp(SIMDInstructionInfo(0x2c).dstw().pf3()); } // ------------------------------------------------------------------------ diff --git a/tests/ctest/common/x86emitter/codegen_tests_main.cpp b/tests/ctest/common/x86emitter/codegen_tests_main.cpp index 9457737358..7808314c95 100644 --- a/tests/ctest/common/x86emitter/codegen_tests_main.cpp +++ b/tests/ctest/common/x86emitter/codegen_tests_main.cpp @@ -147,6 +147,27 @@ TEST(CodegenTests, JmpTest) TEST(CodegenTests, SSETest) { + x86Emitter::use_avx = false; + + CODEGEN_TEST(xCVTDQ2PD(xmm0, ptr64[rax]), "f3 0f e6 00"); + CODEGEN_TEST(xCVTDQ2PS(xmm0, xmm8), "41 0f 5b c0"); + CODEGEN_TEST(xCVTPD2DQ(xmm8, ptr128[r8]), "f2 45 0f e6 00"); + CODEGEN_TEST(xCVTPD2PS(xmm1, xmm7), "66 0f 5a cf"); + CODEGEN_TEST(xCVTSD2SI(rax, xmm1), "f2 48 0f 2d c1"); + CODEGEN_TEST(xCVTSD2SI(esi, ptr64[rax]), "f2 0f 2d 30"); + CODEGEN_TEST(xCVTSD2SS(xmm3, xmm4), "f2 0f 5a dc"); + CODEGEN_TEST(xCVTSI2SS(xmm8, ecx), "f3 44 0f 2a c1"); + CODEGEN_TEST(xCVTSI2SS(xmm3, ptr32[r8]), "f3 41 0f 2a 18"); + CODEGEN_TEST(xCVTSI2SS(xmm3, ptr64[r8]), "f3 49 0f 2a 18"); + CODEGEN_TEST(xCVTSS2SD(xmm8, xmm7), "f3 44 0f 5a c7"); + CODEGEN_TEST(xCVTSS2SD(xmm4, ptr32[rcx]), "f3 0f 5a 21"); + CODEGEN_TEST(xCVTSS2SI(eax, xmm4), "f3 0f 2d c4"); + CODEGEN_TEST(xCVTSS2SI(rcx, ptr32[rax]), "f3 48 0f 2d 08"); + CODEGEN_TEST(xCVTTPD2DQ(xmm4, xmm7), "66 0f e6 e7"); + CODEGEN_TEST(xCVTTPS2DQ(xmm5, xmm3), "f3 0f 5b eb"); + CODEGEN_TEST(xCVTTSD2SI(rdx, xmm4), "f2 48 0f 2c d4"); + CODEGEN_TEST(xCVTTSS2SI(ecx, xmm3), "f3 0f 2c cb"); + CODEGEN_TEST(xMOVAPS(xmm0, xmm1), "0f 28 c1"); CODEGEN_TEST(xMOVAPS(xmm8, xmm9), "45 0f 28 c1"); CODEGEN_TEST(xMOVUPS(xmm8, ptr128[r8+r9]), "47 0f 10 04 08"); @@ -175,6 +196,27 @@ TEST(CodegenTests, SSETest) TEST(CodegenTests, AVXTest) { + x86Emitter::use_avx = true; + + CODEGEN_TEST(xCVTDQ2PD(xmm0, ptr64[rax]), "c5 fa e6 00"); + CODEGEN_TEST(xCVTDQ2PS(xmm0, xmm8), "c4 c1 78 5b c0"); + CODEGEN_TEST(xCVTPD2DQ(xmm8, ptr128[r8]), "c4 41 7b e6 00"); + CODEGEN_TEST(xCVTPD2PS(xmm1, xmm7), "c5 f9 5a cf"); + CODEGEN_TEST(xCVTSD2SI(rax, xmm1), "c4 e1 fb 2d c1"); + CODEGEN_TEST(xCVTSD2SI(esi, ptr64[rax]), "c5 fb 2d 30"); + CODEGEN_TEST(xCVTSD2SS(xmm3, xmm4), "c5 e3 5a dc"); + CODEGEN_TEST(xCVTSI2SS(xmm8, ecx), "c5 3a 2a c1"); + CODEGEN_TEST(xCVTSI2SS(xmm3, ptr32[r8]), "c4 c1 62 2a 18"); + CODEGEN_TEST(xCVTSI2SS(xmm3, ptr64[r8]), "c4 c1 e2 2a 18"); + CODEGEN_TEST(xCVTSS2SD(xmm8, xmm7), "c5 3a 5a c7"); + CODEGEN_TEST(xCVTSS2SD(xmm4, ptr32[rcx]), "c5 da 5a 21"); + CODEGEN_TEST(xCVTSS2SI(eax, xmm4), "c5 fa 2d c4"); + CODEGEN_TEST(xCVTSS2SI(rcx, ptr32[rax]), "c4 e1 fa 2d 08"); + CODEGEN_TEST(xCVTTPD2DQ(xmm4, xmm7), "c5 f9 e6 e7"); + CODEGEN_TEST(xCVTTPS2DQ(xmm5, xmm3), "c5 fa 5b eb"); + CODEGEN_TEST(xCVTTSD2SI(rdx, xmm4), "c4 e1 fb 2c d4"); + CODEGEN_TEST(xCVTTSS2SI(ecx, xmm3), "c5 fa 2c cb"); + CODEGEN_TEST(xVMOVAPS(xmm0, xmm1), "c5 f8 28 c1"); CODEGEN_TEST(xVMOVAPS(xmm0, ptr32[rdi]), "c5 f8 28 07"); CODEGEN_TEST(xVMOVAPS(ptr32[rdi], xmm0), "c5 f8 29 07"); @@ -226,6 +268,8 @@ TEST(CodegenTests, AVXTest) TEST(CodegenTests, AVX256Test) { + x86Emitter::use_avx = true; + CODEGEN_TEST(xVMOVAPS(ymm0, ymm1), "c5 fc 28 c1"); CODEGEN_TEST(xVMOVAPS(ymm0, ptr32[rdi]), "c5 fc 28 07"); CODEGEN_TEST(xVMOVAPS(ptr32[rdi], ymm0), "c5 fc 29 07");