Added SHRD/SHLD x86 emitters, further optimized srawx

This commit is contained in:
calc84maniac 2012-01-09 00:10:13 -05:00
parent 31ff1907a4
commit 79ca43226c
3 changed files with 69 additions and 3 deletions

View File

@ -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::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);} 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) void OpArg::WriteSingleByteOp(XEmitter *emit, u8 op, X64Reg _operandReg, int bits)
{ {
if (bits == 16) if (bits == 16)

View File

@ -381,6 +381,10 @@ public:
void BTR(int bits, OpArg dest, OpArg index); void BTR(int bits, OpArg dest, OpArg index);
void BTC(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 // Extend EAX into EDX in various ways
void CWD(int bits = 16); void CWD(int bits = 16);
inline void CDQ() {CWD(32);} inline void CDQ() {CWD(32);}

View File

@ -1758,10 +1758,9 @@ void Jit64::srawx(UGeckoInstruction inst)
MOV(32, gpr.R(a), gpr.R(s)); MOV(32, gpr.R(a), gpr.R(s));
TEST(32, R(ECX), Imm32(32)); TEST(32, R(ECX), Imm32(32));
FixupBranch topBitSet = J_CC(CC_NZ); 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)); SAR(32, gpr.R(a), R(ECX));
NOT(32, R(ECX));
SHL(32, R(EAX), R(ECX));
TEST(32, R(EAX), gpr.R(a)); TEST(32, R(EAX), gpr.R(a));
FixupBranch nocarry1 = J_CC(CC_Z); FixupBranch nocarry1 = J_CC(CC_Z);
JitSetCA(); JitSetCA();