From e5ba376985aeb93998a9fed476ce3e3cbab0aaeb Mon Sep 17 00:00:00 2001 From: TellowKrinkle Date: Sun, 10 Aug 2025 00:49:51 -0500 Subject: [PATCH] Common: Use inheritance for group 1/3 ops --- common/emitter/groups.cpp | 50 ++++++++++--------------- common/emitter/implement/group1.h | 61 +------------------------------ common/emitter/implement/group3.h | 37 ++----------------- common/emitter/movs.cpp | 2 +- common/emitter/x86emitter.cpp | 2 +- 5 files changed, 27 insertions(+), 125 deletions(-) diff --git a/common/emitter/groups.cpp b/common/emitter/groups.cpp index c811687f77..013534d5c2 100644 --- a/common/emitter/groups.cpp +++ b/common/emitter/groups.cpp @@ -29,7 +29,7 @@ namespace x86Emitter // Note on "[Indirect],Imm" forms : use int as the source operand since it's "reasonably inert" from a // compiler perspective. (using uint tends to make the compiler try and fail to match signed immediates // with one of the other overloads). - static void _g1_IndirectImm(G1Type InstType, const xIndirect64orLess& sibdest, int imm) + void xImpl_Group1::operator()(const xIndirect64orLess& sibdest, int imm) const { if (sibdest.Is8BitOp()) { @@ -49,7 +49,7 @@ namespace x86Emitter } } - void _g1_EmitOp(G1Type InstType, const xRegisterInt& to, const xRegisterInt& from) + void xImpl_Group1::operator()(const xRegisterInt& to, const xRegisterInt& from) const { pxAssert(to.GetOperandSize() == from.GetOperandSize()); @@ -57,19 +57,19 @@ namespace x86Emitter xOpWrite(to.GetPrefix16(), opcode, from, to); } - static void _g1_EmitOp(G1Type InstType, const xIndirectVoid& sibdest, const xRegisterInt& from) + void xImpl_Group1::operator()(const xIndirectVoid& sibdest, const xRegisterInt& from) const { u8 opcode = (from.Is8BitOp() ? 0 : 1) | (InstType << 3); xOpWrite(from.GetPrefix16(), opcode, from, sibdest); } - static void _g1_EmitOp(G1Type InstType, const xRegisterInt& to, const xIndirectVoid& sibsrc) + void xImpl_Group1::operator()(const xRegisterInt& to, const xIndirectVoid& sibsrc) const { u8 opcode = (to.Is8BitOp() ? 2 : 3) | (InstType << 3); xOpWrite(to.GetPrefix16(), opcode, to, sibsrc); } - static void _g1_EmitOp(G1Type InstType, const xRegisterInt& to, int imm) + void xImpl_Group1::operator()(const xRegisterInt& to, int imm) const { if (!to.Is8BitOp() && is_s8(imm)) { @@ -92,23 +92,12 @@ namespace x86Emitter } } -#define ImplementGroup1(g1type, insttype) \ - void g1type::operator()(const xRegisterInt& to, const xRegisterInt& from) const { _g1_EmitOp(insttype, to, from); } \ - void g1type::operator()(const xIndirectVoid& to, const xRegisterInt& from) const { _g1_EmitOp(insttype, to, from); } \ - void g1type::operator()(const xRegisterInt& to, const xIndirectVoid& from) const { _g1_EmitOp(insttype, to, from); } \ - void g1type::operator()(const xRegisterInt& to, int imm) const { _g1_EmitOp(insttype, to, imm); } \ - void g1type::operator()(const xIndirect64orLess& sibdest, int imm) const { _g1_IndirectImm(insttype, sibdest, imm); } + const xImpl_G1Logic xAND = {{G1Type_AND}, {0x00, 0x54}, {0x66, 0x54}}; + const xImpl_G1Logic xOR = {{G1Type_OR}, {0x00, 0x56}, {0x66, 0x56}}; + const xImpl_G1Logic xXOR = {{G1Type_XOR}, {0x00, 0x57}, {0x66, 0x57}}; - ImplementGroup1(xImpl_Group1, InstType) - ImplementGroup1(xImpl_G1Logic, InstType) - ImplementGroup1(xImpl_G1Arith, InstType) - - const xImpl_G1Logic xAND = {G1Type_AND, {0x00, 0x54}, {0x66, 0x54}}; - const xImpl_G1Logic xOR = {G1Type_OR, {0x00, 0x56}, {0x66, 0x56}}; - const xImpl_G1Logic xXOR = {G1Type_XOR, {0x00, 0x57}, {0x66, 0x57}}; - - const xImpl_G1Arith xADD = {G1Type_ADD, {0x00, 0x58}, {0x66, 0x58}, {0xf3, 0x58}, {0xf2, 0x58}}; - const xImpl_G1Arith xSUB = {G1Type_SUB, {0x00, 0x5c}, {0x66, 0x5c}, {0xf3, 0x5c}, {0xf2, 0x5c}}; + const xImpl_G1Arith xADD = {{G1Type_ADD}, {0x00, 0x58}, {0x66, 0x58}, {0xf3, 0x58}, {0xf2, 0x58}}; + const xImpl_G1Arith xSUB = {{G1Type_SUB}, {0x00, 0x5c}, {0x66, 0x5c}, {0xf3, 0x5c}, {0xf2, 0x5c}}; const xImpl_Group1 xADC = {G1Type_ADC}; const xImpl_Group1 xSBB = {G1Type_SBB}; @@ -185,11 +174,15 @@ namespace x86Emitter xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0xf6 : 0xf7, InstType, from); } - void xImpl_Group3::operator()(const xRegisterInt& from) const { _g3_EmitOp(InstType, from); } - void xImpl_Group3::operator()(const xIndirect64orLess& from) const { _g3_EmitOp(InstType, from); } + void xImpl_Group3::operator()(const xRegisterInt& from) const + { + xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0xf6 : 0xf7, InstType, from); + } - void xImpl_iDiv::operator()(const xRegisterInt& from) const { _g3_EmitOp(G3Type_iDIV, from); } - void xImpl_iDiv::operator()(const xIndirect64orLess& from) const { _g3_EmitOp(G3Type_iDIV, from); } + void xImpl_Group3::operator()(const xIndirect64orLess& from) const + { + xOpWrite(from.GetPrefix16(), from.Is8BitOp() ? 0xf6 : 0xf7, InstType, from); + } template static void _imul_ImmStyle(const xRegisterInt& param1, const SrcType& param2, int imm) @@ -204,9 +197,6 @@ namespace x86Emitter param1.xWriteImm(imm); } - void xImpl_iMul::operator()(const xRegisterInt& from) const { _g3_EmitOp(G3Type_iMUL, from); } - void xImpl_iMul::operator()(const xIndirect64orLess& from) const { _g3_EmitOp(G3Type_iMUL, from); } - void xImpl_iMul::operator()(const xRegister32& to, const xRegister32& from) const { xOpWrite0F(0xaf, to, from); } void xImpl_iMul::operator()(const xRegister32& to, const xIndirectVoid& src) const { xOpWrite0F(0xaf, to, src); } void xImpl_iMul::operator()(const xRegister16& to, const xRegister16& from) const { xOpWrite0F(0x66, 0xaf, to, from); } @@ -222,8 +212,8 @@ namespace x86Emitter const xImpl_Group3 xUMUL = {G3Type_MUL}; const xImpl_Group3 xUDIV = {G3Type_DIV}; - const xImpl_iDiv xDIV = {{0x00, 0x5e}, {0x66, 0x5e}, {0xf3, 0x5e}, {0xf2, 0x5e}}; - const xImpl_iMul xMUL = {{0x00, 0x59}, {0x66, 0x59}, {0xf3, 0x59}, {0xf2, 0x59}}; + const xImpl_iDiv xDIV = {{G3Type_iDIV}, {0x00, 0x5e}, {0x66, 0x5e}, {0xf3, 0x5e}, {0xf2, 0x5e}}; + const xImpl_iMul xMUL = {{G3Type_iMUL}, {0x00, 0x59}, {0x66, 0x59}, {0xf3, 0x59}, {0xf2, 0x59}}; // ===================================================================================================== // Group 8 Instructions diff --git a/common/emitter/implement/group1.h b/common/emitter/implement/group1.h index 9e6b94dfe5..2cb5da6eba 100644 --- a/common/emitter/implement/group1.h +++ b/common/emitter/implement/group1.h @@ -18,8 +18,6 @@ namespace x86Emitter G1Type_CMP }; - extern void _g1_EmitOp(G1Type InstType, const xRegisterInt& to, const xRegisterInt& from); - // -------------------------------------------------------------------------------------- // xImpl_Group1 // -------------------------------------------------------------------------------------- @@ -33,59 +31,14 @@ namespace x86Emitter void operator()(const xRegisterInt& to, const xIndirectVoid& from) const; void operator()(const xRegisterInt& to, int imm) const; void operator()(const xIndirect64orLess& to, int imm) const; - -#if 0 - // ------------------------------------------------------------------------ - template< typename T > __noinline void operator()( const ModSibBase& to, const xImmReg& immOrReg ) const - { - _DoI_helpermess( *this, to, immOrReg ); - } - - template< typename T > __noinline void operator()( const xDirectOrIndirect& to, const xImmReg& immOrReg ) const - { - _DoI_helpermess( *this, to, immOrReg ); - } - - template< typename T > __noinline void operator()( const xDirectOrIndirect& to, int imm ) const - { - _DoI_helpermess( *this, to, imm ); - } - - template< typename T > __noinline void operator()( const xDirectOrIndirect& to, const xDirectOrIndirect& from ) const - { - _DoI_helpermess( *this, to, from ); - } - - // FIXME : Make this struct to 8, 16, and 32 bit registers - template< typename T > __noinline void operator()( const xRegisterBase& to, const xDirectOrIndirect& from ) const - { - _DoI_helpermess( *this, xDirectOrIndirect( to ), from ); - } - - // FIXME : Make this struct to 8, 16, and 32 bit registers - template< typename T > __noinline void operator()( const xDirectOrIndirect& to, const xRegisterBase& from ) const - { - _DoI_helpermess( *this, to, xDirectOrIndirect( from ) ); - } -#endif }; // ------------------------------------------------------------------------ // This class combines x86 with SSE/SSE2 logic operations (ADD, OR, and NOT). // Note: ANDN [AndNot] is handled below separately. // - struct xImpl_G1Logic + struct xImpl_G1Logic : public xImpl_Group1 { - G1Type InstType; - - void operator()(const xRegisterInt& to, const xRegisterInt& from) const; - - void operator()(const xIndirectVoid& to, const xRegisterInt& from) const; - void operator()(const xRegisterInt& to, const xIndirectVoid& from) const; - void operator()(const xRegisterInt& to, int imm) const; - - void operator()(const xIndirect64orLess& to, int imm) const; - xImplSimd_DestRegSSE PS; // packed single precision xImplSimd_DestRegSSE PD; // packed double precision }; @@ -93,18 +46,8 @@ namespace x86Emitter // ------------------------------------------------------------------------ // This class combines x86 with SSE/SSE2 arithmetic operations (ADD/SUB). // - struct xImpl_G1Arith + struct xImpl_G1Arith : public xImpl_Group1 { - G1Type InstType; - - void operator()(const xRegisterInt& to, const xRegisterInt& from) const; - - void operator()(const xIndirectVoid& to, const xRegisterInt& from) const; - void operator()(const xRegisterInt& to, const xIndirectVoid& from) const; - void operator()(const xRegisterInt& to, int imm) const; - - void operator()(const xIndirect64orLess& to, int imm) const; - xImplSimd_DestRegSSE PS; // packed single precision xImplSimd_DestRegSSE PD; // packed double precision xImplSimd_DestRegSSE SS; // scalar single precision diff --git a/common/emitter/implement/group3.h b/common/emitter/implement/group3.h index 6492c25ee6..cb6289dd74 100644 --- a/common/emitter/implement/group3.h +++ b/common/emitter/implement/group3.h @@ -25,43 +25,13 @@ namespace x86Emitter void operator()(const xRegisterInt& from) const; void operator()(const xIndirect64orLess& from) const; - -#if 0 - template< typename T > - void operator()( const xDirectOrIndirect& from ) const - { - _DoI_helpermess( *this, from ); - } -#endif - }; - - // -------------------------------------------------------------------------------------- - // xImpl_MulDivBase - // -------------------------------------------------------------------------------------- - // This class combines x86 and SSE/SSE2 instructions for iMUL and iDIV. - // - struct xImpl_MulDivBase - { - G3Type InstType; - u16 OpcodeSSE; - - void operator()(const xRegisterInt& from) const; - void operator()(const xIndirect64orLess& from) const; - - const xImplSimd_DestRegSSE PS; - const xImplSimd_DestRegSSE PD; - const xImplSimd_DestRegSSE SS; - const xImplSimd_DestRegSSE SD; }; // -------------------------------------------------------------------------------------- // xImpl_iDiv // -------------------------------------------------------------------------------------- - struct xImpl_iDiv + struct xImpl_iDiv : public xImpl_Group3 { - void operator()(const xRegisterInt& from) const; - void operator()(const xIndirect64orLess& from) const; - const xImplSimd_DestRegSSE PS; const xImplSimd_DestRegSSE PD; const xImplSimd_DestRegSSE SS; @@ -72,10 +42,9 @@ namespace x86Emitter // xImpl_iMul // -------------------------------------------------------------------------------------- // - struct xImpl_iMul + struct xImpl_iMul : public xImpl_Group3 { - void operator()(const xRegisterInt& from) const; - void operator()(const xIndirect64orLess& from) const; + using xImpl_Group3::operator(); // The following iMul-specific forms are valid for 16 and 32 bit register operands only! diff --git a/common/emitter/movs.cpp b/common/emitter/movs.cpp index ca2402299d..36c607f338 100644 --- a/common/emitter/movs.cpp +++ b/common/emitter/movs.cpp @@ -101,7 +101,7 @@ namespace x86Emitter const xRegisterInt& to_ = to.GetNonWide(); if (!preserve_flags && (imm == 0)) { - _g1_EmitOp(G1Type_XOR, to_, to_); + xXOR(to_, to_); } else if (imm == (sptr)(u32)imm || !to.IsWide()) { diff --git a/common/emitter/x86emitter.cpp b/common/emitter/x86emitter.cpp index dde56878d8..1f3ee1d634 100644 --- a/common/emitter/x86emitter.cpp +++ b/common/emitter/x86emitter.cpp @@ -1066,7 +1066,7 @@ const xRegister32 else if (src.Displacement == 0) { _xMovRtoR(to, src.Base.MatchSizeTo(to)); - _g1_EmitOp(G1Type_ADD, to, src.Index.MatchSizeTo(to)); + xADD(to, src.Index.MatchSizeTo(to)); return; } }