Jit_Integer: boolX

This commit is contained in:
MerryMage
2018-10-15 21:01:20 +01:00
parent b7a4296bec
commit b256286690

View File

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