Jit_Integer: boolX

This commit is contained in:
MerryMage 2018-10-15 21:01:20 +01:00
parent b7a4296bec
commit b256286690
1 changed files with 67 additions and 64 deletions

View File

@ -648,10 +648,10 @@ void Jit64::boolX(UGeckoInstruction inst)
bool needs_test = false;
DEBUG_ASSERT_MSG(DYNA_REC, inst.OPCD == 31, "Invalid boolX");
if (gpr.R(s).IsImm() && gpr.R(b).IsImm())
if (gpr.IsImm(s, b))
{
const u32 rs_offset = gpr.R(s).Imm32();
const u32 rb_offset = gpr.R(b).Imm32();
const u32 rs_offset = gpr.Imm32(s);
const u32 rb_offset = gpr.Imm32(b);
if (inst.SUBOP10 == 28) // andx
gpr.SetImmediate32(a, rs_offset & rb_offset);
@ -676,33 +676,33 @@ void Jit64::boolX(UGeckoInstruction inst)
{
if (a != s)
{
gpr.Lock(a, s);
gpr.BindToRegister(a, false, true);
MOV(32, gpr.R(a), gpr.R(s));
RCOpArg Rs = gpr.Use(s, RCMode::Read);
RCX64Reg Ra = gpr.Bind(a, RCMode::Write);
RegCache::Realize(Rs, Ra);
MOV(32, Ra, Rs);
}
else if (inst.Rc)
{
gpr.BindToRegister(a, true, false);
gpr.Bind(a, RCMode::Read).Realize();
}
needs_test = true;
}
else if ((inst.SUBOP10 == 476 /* nandx */) || (inst.SUBOP10 == 124 /* norx */))
{
if (a != s)
if (a == s && !inst.Rc)
{
gpr.Lock(a, s);
gpr.BindToRegister(a, false, true);
MOV(32, gpr.R(a), gpr.R(s));
}
else if (inst.Rc)
{
gpr.BindToRegister(a, true, true);
RCOpArg Ra = gpr.UseNoImm(a, RCMode::ReadWrite);
RegCache::Realize(Ra);
NOT(32, Ra);
}
else
{
gpr.KillImmediate(a, true, true);
RCOpArg Rs = gpr.Use(s, RCMode::Read);
RCX64Reg Ra = gpr.Bind(a, RCMode::ReadWrite);
RegCache::Realize(Rs, Ra);
MOV(32, Ra, Rs);
NOT(32, Ra);
}
NOT(32, gpr.R(a));
needs_test = true;
}
else if ((inst.SUBOP10 == 412 /* orcx */) || (inst.SUBOP10 == 284 /* eqvx */))
@ -720,70 +720,72 @@ void Jit64::boolX(UGeckoInstruction inst)
}
else if ((a == s) || (a == b))
{
gpr.Lock(a, ((a == s) ? b : s));
OpArg operand = ((a == s) ? gpr.R(b) : gpr.R(s));
gpr.BindToRegister(a, true, true);
RCOpArg Rb = gpr.Use(b, RCMode::Read);
RCOpArg Rs = gpr.Use(s, RCMode::Read);
RCOpArg operand = gpr.Use(a == s ? b : s, RCMode::Read);
RCX64Reg Ra = gpr.Bind(a, RCMode::ReadWrite);
RegCache::Realize(Rb, Rs, operand, Ra);
if (inst.SUBOP10 == 28) // andx
{
AND(32, gpr.R(a), operand);
AND(32, Ra, operand);
}
else if (inst.SUBOP10 == 476) // nandx
{
AND(32, gpr.R(a), operand);
NOT(32, gpr.R(a));
AND(32, Ra, operand);
NOT(32, Ra);
needs_test = true;
}
else if (inst.SUBOP10 == 60) // andcx
{
if (cpu_info.bBMI1 && gpr.R(b).IsSimpleReg() && !gpr.R(s).IsImm())
if (cpu_info.bBMI1 && Rb.IsSimpleReg() && !Rs.IsImm())
{
ANDN(32, gpr.RX(a), gpr.RX(b), gpr.R(s));
ANDN(32, Ra, Rb.GetSimpleReg(), Rs);
}
else if (a == b)
{
NOT(32, gpr.R(a));
AND(32, gpr.R(a), operand);
NOT(32, Ra);
AND(32, Ra, operand);
}
else
{
MOV(32, R(RSCRATCH), operand);
NOT(32, R(RSCRATCH));
AND(32, gpr.R(a), R(RSCRATCH));
AND(32, Ra, R(RSCRATCH));
}
}
else if (inst.SUBOP10 == 444) // orx
{
OR(32, gpr.R(a), operand);
OR(32, Ra, operand);
}
else if (inst.SUBOP10 == 124) // norx
{
OR(32, gpr.R(a), operand);
NOT(32, gpr.R(a));
OR(32, Ra, operand);
NOT(32, Ra);
needs_test = true;
}
else if (inst.SUBOP10 == 412) // orcx
{
if (a == b)
{
NOT(32, gpr.R(a));
OR(32, gpr.R(a), operand);
NOT(32, Ra);
OR(32, Ra, operand);
}
else
{
MOV(32, R(RSCRATCH), operand);
NOT(32, R(RSCRATCH));
OR(32, gpr.R(a), R(RSCRATCH));
OR(32, Ra, R(RSCRATCH));
}
}
else if (inst.SUBOP10 == 316) // xorx
{
XOR(32, gpr.R(a), operand);
XOR(32, Ra, operand);
}
else if (inst.SUBOP10 == 284) // eqvx
{
NOT(32, gpr.R(a));
XOR(32, gpr.R(a), operand);
NOT(32, Ra);
XOR(32, Ra, operand);
}
else
{
@ -792,62 +794,64 @@ void Jit64::boolX(UGeckoInstruction inst)
}
else
{
gpr.Lock(a, s, b);
gpr.BindToRegister(a, false, true);
RCOpArg Rb = gpr.Use(b, RCMode::Read);
RCOpArg Rs = gpr.Use(s, RCMode::Read);
RCX64Reg Ra = gpr.Bind(a, RCMode::Write);
RegCache::Realize(Rb, Rs, Ra);
if (inst.SUBOP10 == 28) // andx
{
MOV(32, gpr.R(a), gpr.R(s));
AND(32, gpr.R(a), gpr.R(b));
MOV(32, Ra, Rs);
AND(32, Ra, Rb);
}
else if (inst.SUBOP10 == 476) // nandx
{
MOV(32, gpr.R(a), gpr.R(s));
AND(32, gpr.R(a), gpr.R(b));
NOT(32, gpr.R(a));
MOV(32, Ra, Rs);
AND(32, Ra, Rb);
NOT(32, Ra);
needs_test = true;
}
else if (inst.SUBOP10 == 60) // andcx
{
if (cpu_info.bBMI1 && gpr.R(b).IsSimpleReg() && !gpr.R(s).IsImm())
if (cpu_info.bBMI1 && Rb.IsSimpleReg() && !Rs.IsImm())
{
ANDN(32, gpr.RX(a), gpr.RX(b), gpr.R(s));
ANDN(32, Ra, Rb.GetSimpleReg(), Rs);
}
else
{
MOV(32, gpr.R(a), gpr.R(b));
NOT(32, gpr.R(a));
AND(32, gpr.R(a), gpr.R(s));
MOV(32, Ra, Rb);
NOT(32, Ra);
AND(32, Ra, Rs);
}
}
else if (inst.SUBOP10 == 444) // orx
{
MOV(32, gpr.R(a), gpr.R(s));
OR(32, gpr.R(a), gpr.R(b));
MOV(32, Ra, Rs);
OR(32, Ra, Rb);
}
else if (inst.SUBOP10 == 124) // norx
{
MOV(32, gpr.R(a), gpr.R(s));
OR(32, gpr.R(a), gpr.R(b));
NOT(32, gpr.R(a));
MOV(32, Ra, Rs);
OR(32, Ra, Rb);
NOT(32, Ra);
needs_test = true;
}
else if (inst.SUBOP10 == 412) // orcx
{
MOV(32, gpr.R(a), gpr.R(b));
NOT(32, gpr.R(a));
OR(32, gpr.R(a), gpr.R(s));
MOV(32, Ra, Rb);
NOT(32, Ra);
OR(32, Ra, Rs);
}
else if (inst.SUBOP10 == 316) // xorx
{
MOV(32, gpr.R(a), gpr.R(s));
XOR(32, gpr.R(a), gpr.R(b));
MOV(32, Ra, Rs);
XOR(32, Ra, Rb);
}
else if (inst.SUBOP10 == 284) // eqvx
{
MOV(32, gpr.R(a), gpr.R(s));
NOT(32, gpr.R(a));
XOR(32, gpr.R(a), gpr.R(b));
MOV(32, Ra, Rs);
NOT(32, Ra);
XOR(32, Ra, Rb);
}
else
{
@ -855,8 +859,7 @@ void Jit64::boolX(UGeckoInstruction inst)
}
}
if (inst.Rc)
ComputeRC(gpr.R(a), needs_test);
gpr.UnlockAll();
ComputeRC(a, needs_test);
}
void Jit64::extsXx(UGeckoInstruction inst)