Added SHRD/SHLD x86 emitters, further optimized srawx
This commit is contained in:
parent
31ff1907a4
commit
79ca43226c
|
@ -867,6 +867,69 @@ void XEmitter::BTS(int bits, OpArg dest, OpArg index) {WriteBitTest(bits, dest,
|
|||
void XEmitter::BTR(int bits, OpArg dest, OpArg index) {WriteBitTest(bits, dest, index, 6);}
|
||||
void XEmitter::BTC(int bits, OpArg dest, OpArg index) {WriteBitTest(bits, dest, index, 7);}
|
||||
|
||||
//shift can be either imm8 or cl
|
||||
void XEmitter::SHRD(int bits, OpArg dest, OpArg src, OpArg shift)
|
||||
{
|
||||
bool writeImm = false;
|
||||
if (dest.IsImm())
|
||||
{
|
||||
_assert_msg_(DYNA_REC, 0, "SHRD - can't use imms as destination");
|
||||
}
|
||||
if (!src.IsSimpleReg())
|
||||
{
|
||||
_assert_msg_(DYNA_REC, 0, "SHRD - must use simple register as source");
|
||||
}
|
||||
if ((shift.IsSimpleReg() && shift.GetSimpleReg() != ECX) || (shift.IsImm() && shift.GetImmBits() != 8))
|
||||
{
|
||||
_assert_msg_(DYNA_REC, 0, "SHRD - illegal shift");
|
||||
}
|
||||
if (bits == 16) Write8(0x66);
|
||||
X64Reg operand = src.GetSimpleReg();
|
||||
dest.WriteRex(this, bits, bits, operand);
|
||||
if (shift.GetImmBits() == 8)
|
||||
{
|
||||
Write8(0x0F); Write8(0xAC);
|
||||
dest.WriteRest(this, 1, operand);
|
||||
Write8((u8)shift.offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
Write8(0x0F); Write8(0xAD);
|
||||
dest.WriteRest(this, 0, operand);
|
||||
}
|
||||
}
|
||||
|
||||
void XEmitter::SHLD(int bits, OpArg dest, OpArg src, OpArg shift)
|
||||
{
|
||||
bool writeImm = false;
|
||||
if (dest.IsImm())
|
||||
{
|
||||
_assert_msg_(DYNA_REC, 0, "SHLD - can't use imms as destination");
|
||||
}
|
||||
if (!src.IsSimpleReg())
|
||||
{
|
||||
_assert_msg_(DYNA_REC, 0, "SHLD - must use simple register as source");
|
||||
}
|
||||
if ((shift.IsSimpleReg() && shift.GetSimpleReg() != ECX) || (shift.IsImm() && shift.GetImmBits() != 8))
|
||||
{
|
||||
_assert_msg_(DYNA_REC, 0, "SHLD - illegal shift");
|
||||
}
|
||||
if (bits == 16) Write8(0x66);
|
||||
X64Reg operand = src.GetSimpleReg();
|
||||
dest.WriteRex(this, bits, bits, operand);
|
||||
if (shift.GetImmBits() == 8)
|
||||
{
|
||||
Write8(0x0F); Write8(0xA4);
|
||||
dest.WriteRest(this, 1, operand);
|
||||
Write8((u8)shift.offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
Write8(0x0F); Write8(0xA5);
|
||||
dest.WriteRest(this, 0, operand);
|
||||
}
|
||||
}
|
||||
|
||||
void OpArg::WriteSingleByteOp(XEmitter *emit, u8 op, X64Reg _operandReg, int bits)
|
||||
{
|
||||
if (bits == 16)
|
||||
|
|
|
@ -381,6 +381,10 @@ public:
|
|||
void BTR(int bits, OpArg dest, OpArg index);
|
||||
void BTC(int bits, OpArg dest, OpArg index);
|
||||
|
||||
// Double-Precision Shift
|
||||
void SHRD(int bits, OpArg dest, OpArg src, OpArg shift);
|
||||
void SHLD(int bits, OpArg dest, OpArg src, OpArg shift);
|
||||
|
||||
// Extend EAX into EDX in various ways
|
||||
void CWD(int bits = 16);
|
||||
inline void CDQ() {CWD(32);}
|
||||
|
|
|
@ -1758,10 +1758,9 @@ void Jit64::srawx(UGeckoInstruction inst)
|
|||
MOV(32, gpr.R(a), gpr.R(s));
|
||||
TEST(32, R(ECX), Imm32(32));
|
||||
FixupBranch topBitSet = J_CC(CC_NZ);
|
||||
LEA(32, EAX, MComplex(gpr.RX(a), gpr.RX(a), 1, 0));
|
||||
XOR(32, R(EAX), R(EAX));
|
||||
SHRD(32, R(EAX), gpr.R(a), R(ECX));
|
||||
SAR(32, gpr.R(a), R(ECX));
|
||||
NOT(32, R(ECX));
|
||||
SHL(32, R(EAX), R(ECX));
|
||||
TEST(32, R(EAX), gpr.R(a));
|
||||
FixupBranch nocarry1 = J_CC(CC_Z);
|
||||
JitSetCA();
|
||||
|
|
Loading…
Reference in New Issue