x64Emitter: add MOVSLDUP/MOVSHDUP
This commit is contained in:
parent
f5a10bddee
commit
439fb26b9b
|
@ -1636,22 +1636,47 @@ void XEmitter::MOVMSKPD(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0x50, d
|
||||||
|
|
||||||
void XEmitter::LDDQU(X64Reg dest, const OpArg& arg) {WriteSSEOp(0xF2, sseLDDQU, dest, arg);} // For integer data only
|
void XEmitter::LDDQU(X64Reg dest, const OpArg& arg) {WriteSSEOp(0xF2, sseLDDQU, dest, arg);} // For integer data only
|
||||||
|
|
||||||
// THESE TWO ARE UNTESTED.
|
|
||||||
void XEmitter::UNPCKLPS(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x00, 0x14, dest, arg);}
|
void XEmitter::UNPCKLPS(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x00, 0x14, dest, arg);}
|
||||||
void XEmitter::UNPCKHPS(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x00, 0x15, dest, arg);}
|
void XEmitter::UNPCKHPS(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x00, 0x15, dest, arg);}
|
||||||
|
|
||||||
void XEmitter::UNPCKLPD(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0x14, dest, arg);}
|
void XEmitter::UNPCKLPD(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0x14, dest, arg);}
|
||||||
void XEmitter::UNPCKHPD(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0x15, dest, arg);}
|
void XEmitter::UNPCKHPD(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0x15, dest, arg);}
|
||||||
|
|
||||||
|
// Pretty much every x86 CPU nowadays supports SSE3,
|
||||||
|
// but the SSE2 fallbacks are easy.
|
||||||
|
void XEmitter::MOVSLDUP(X64Reg regOp, const OpArg& arg)
|
||||||
|
{
|
||||||
|
if (cpu_info.bSSE3)
|
||||||
|
{
|
||||||
|
WriteSSEOp(0xF3, 0x12, regOp, arg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!arg.IsSimpleReg(regOp))
|
||||||
|
MOVAPD(regOp, arg);
|
||||||
|
UNPCKLPS(regOp, R(regOp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void XEmitter::MOVSHDUP(X64Reg regOp, const OpArg& arg)
|
||||||
|
{
|
||||||
|
if (cpu_info.bSSE3)
|
||||||
|
{
|
||||||
|
WriteSSEOp(0xF3, 0x16, regOp, arg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!arg.IsSimpleReg(regOp))
|
||||||
|
MOVAPD(regOp, arg);
|
||||||
|
UNPCKHPS(regOp, R(regOp));
|
||||||
|
}
|
||||||
|
}
|
||||||
void XEmitter::MOVDDUP(X64Reg regOp, const OpArg& arg)
|
void XEmitter::MOVDDUP(X64Reg regOp, const OpArg& arg)
|
||||||
{
|
{
|
||||||
if (cpu_info.bSSE3)
|
if (cpu_info.bSSE3)
|
||||||
{
|
{
|
||||||
WriteSSEOp(0xF2, 0x12, regOp, arg); //SSE3 movddup
|
WriteSSEOp(0xF2, 0x12, regOp, arg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Simulate this instruction with SSE2 instructions
|
|
||||||
if (!arg.IsSimpleReg(regOp))
|
if (!arg.IsSimpleReg(regOp))
|
||||||
MOVSD(regOp, arg);
|
MOVSD(regOp, arg);
|
||||||
UNPCKLPD(regOp, R(regOp));
|
UNPCKLPD(regOp, R(regOp));
|
||||||
|
|
|
@ -581,9 +581,12 @@ public:
|
||||||
void SHUFPS(X64Reg regOp, const OpArg& arg, u8 shuffle);
|
void SHUFPS(X64Reg regOp, const OpArg& arg, u8 shuffle);
|
||||||
void SHUFPD(X64Reg regOp, const OpArg& arg, u8 shuffle);
|
void SHUFPD(X64Reg regOp, const OpArg& arg, u8 shuffle);
|
||||||
|
|
||||||
// SSE/SSE2: Useful alternative to shuffle in some cases.
|
// SSE3
|
||||||
|
void MOVSLDUP(X64Reg regOp, const OpArg& arg);
|
||||||
|
void MOVSHDUP(X64Reg regOp, const OpArg& arg);
|
||||||
void MOVDDUP(X64Reg regOp, const OpArg& arg);
|
void MOVDDUP(X64Reg regOp, const OpArg& arg);
|
||||||
|
|
||||||
|
// SSE/SSE2: Useful alternative to shuffle in some cases.
|
||||||
void UNPCKLPS(X64Reg dest, const OpArg& src);
|
void UNPCKLPS(X64Reg dest, const OpArg& src);
|
||||||
void UNPCKHPS(X64Reg dest, const OpArg& src);
|
void UNPCKHPS(X64Reg dest, const OpArg& src);
|
||||||
void UNPCKLPD(X64Reg dest, const OpArg& src);
|
void UNPCKLPD(X64Reg dest, const OpArg& src);
|
||||||
|
|
|
@ -721,6 +721,8 @@ TWO_OP_SSE_TEST(ANDNPD, "dqword")
|
||||||
TWO_OP_SSE_TEST(ORPD, "dqword")
|
TWO_OP_SSE_TEST(ORPD, "dqword")
|
||||||
TWO_OP_SSE_TEST(XORPD, "dqword")
|
TWO_OP_SSE_TEST(XORPD, "dqword")
|
||||||
|
|
||||||
|
TWO_OP_SSE_TEST(MOVSLDUP, "dqword")
|
||||||
|
TWO_OP_SSE_TEST(MOVSHDUP, "dqword")
|
||||||
TWO_OP_SSE_TEST(MOVDDUP, "qword")
|
TWO_OP_SSE_TEST(MOVDDUP, "qword")
|
||||||
|
|
||||||
TWO_OP_SSE_TEST(UNPCKLPS, "dqword")
|
TWO_OP_SSE_TEST(UNPCKLPS, "dqword")
|
||||||
|
|
Loading…
Reference in New Issue