JitArm64: Update CR helpers to reflect their usage.

This helpers are not for general CR calculation, they are just for the
common case of the sign extended result of integer instructions if the
rc bit is set.
They must not be used by other instructions like cmp, so there is no
need to be as flexible.
This commit is contained in:
Markus Wick 2017-08-11 19:39:39 +02:00
parent 7d4c14feba
commit ec5cfd2aae
2 changed files with 68 additions and 75 deletions

View File

@ -229,8 +229,8 @@ private:
FixupBranch JumpIfCRFieldBit(int field, int bit, bool jump_if_set);
void ComputeRC(Arm64Gen::ARM64Reg reg, int crf = 0, bool needs_sext = true);
void ComputeRC(u64 imm, int crf = 0, bool needs_sext = true);
void ComputeRC0(Arm64Gen::ARM64Reg reg);
void ComputeRC0(u64 imm);
void ComputeCarry(bool Carry);
void ComputeCarry();
void FlushCarry();

View File

@ -15,25 +15,18 @@
using namespace Arm64Gen;
void JitArm64::ComputeRC(ARM64Reg reg, int crf, bool needs_sext)
void JitArm64::ComputeRC0(ARM64Reg reg)
{
gpr.BindCRToRegister(crf, false);
if (needs_sext)
{
SXTW(gpr.CR(crf), reg);
}
else
{
MOV(gpr.CR(crf), EncodeRegTo64(reg));
}
gpr.BindCRToRegister(0, false);
SXTW(gpr.CR(0), reg);
}
void JitArm64::ComputeRC(u64 imm, int crf, bool needs_sext)
void JitArm64::ComputeRC0(u64 imm)
{
gpr.BindCRToRegister(crf, false);
MOVI2R(gpr.CR(crf), imm);
if (imm & 0x80000000 && needs_sext)
SXTW(gpr.CR(crf), DecodeReg(gpr.CR(crf)));
gpr.BindCRToRegister(0, false);
MOVI2R(gpr.CR(0), imm);
if (imm & 0x80000000)
SXTW(gpr.CR(0), DecodeReg(gpr.CR(0)));
}
void JitArm64::ComputeCarry(bool Carry)
@ -91,7 +84,7 @@ void JitArm64::reg_imm(u32 d, u32 a, u32 value, u32 (*do_op)(u32, u32),
{
gpr.SetImmediate(d, do_op(gpr.GetImm(a), value));
if (Rc)
ComputeRC(gpr.GetImm(d));
ComputeRC0(gpr.GetImm(d));
}
else
{
@ -101,7 +94,7 @@ void JitArm64::reg_imm(u32 d, u32 a, u32 value, u32 (*do_op)(u32, u32),
gpr.Unlock(WA);
if (Rc)
ComputeRC(gpr.R(d), 0);
ComputeRC0(gpr.R(d));
}
}
@ -214,7 +207,7 @@ void JitArm64::boolX(UGeckoInstruction inst)
gpr.SetImmediate(a, ~((u32)gpr.GetImm(s) ^ (u32)gpr.GetImm(b)));
if (inst.Rc)
ComputeRC(gpr.GetImm(a), 0);
ComputeRC0(gpr.GetImm(a));
}
else if (s == b)
{
@ -226,26 +219,26 @@ void JitArm64::boolX(UGeckoInstruction inst)
MOV(gpr.R(a), gpr.R(s));
}
if (inst.Rc)
ComputeRC(gpr.R(a));
ComputeRC0(gpr.R(a));
}
else if ((inst.SUBOP10 == 476 /* nandx */) || (inst.SUBOP10 == 124 /* norx */))
{
gpr.BindToRegister(a, a == s);
MVN(gpr.R(a), gpr.R(s));
if (inst.Rc)
ComputeRC(gpr.R(a));
ComputeRC0(gpr.R(a));
}
else if ((inst.SUBOP10 == 412 /* orcx */) || (inst.SUBOP10 == 284 /* eqvx */))
{
gpr.SetImmediate(a, 0xFFFFFFFF);
if (inst.Rc)
ComputeRC(gpr.GetImm(a), 0);
ComputeRC0(gpr.GetImm(a));
}
else if ((inst.SUBOP10 == 60 /* andcx */) || (inst.SUBOP10 == 316 /* xorx */))
{
gpr.SetImmediate(a, 0);
if (inst.Rc)
ComputeRC(gpr.GetImm(a), 0);
ComputeRC0(gpr.GetImm(a));
}
else
{
@ -294,7 +287,7 @@ void JitArm64::boolX(UGeckoInstruction inst)
PanicAlert("WTF!");
}
if (inst.Rc)
ComputeRC(gpr.R(a), 0);
ComputeRC0(gpr.R(a));
}
}
@ -311,7 +304,7 @@ void JitArm64::addx(UGeckoInstruction inst)
s32 i = (s32)gpr.GetImm(a), j = (s32)gpr.GetImm(b);
gpr.SetImmediate(d, i + j);
if (inst.Rc)
ComputeRC(gpr.GetImm(d), 0);
ComputeRC0(gpr.GetImm(d));
}
else if (gpr.IsImm(a) || gpr.IsImm(b))
{
@ -322,14 +315,14 @@ void JitArm64::addx(UGeckoInstruction inst)
ADDI2R(gpr.R(d), gpr.R(in_reg), gpr.GetImm(imm_reg), WA);
gpr.Unlock(WA);
if (inst.Rc)
ComputeRC(gpr.R(d), 0);
ComputeRC0(gpr.R(d));
}
else
{
gpr.BindToRegister(d, d == a || d == b);
ADD(gpr.R(d), gpr.R(a), gpr.R(b));
if (inst.Rc)
ComputeRC(gpr.R(d), 0);
ComputeRC0(gpr.R(d));
}
}
@ -344,14 +337,14 @@ void JitArm64::extsXx(UGeckoInstruction inst)
{
gpr.SetImmediate(a, (u32)(s32)(size == 16 ? (s16)gpr.GetImm(s) : (s8)gpr.GetImm(s)));
if (inst.Rc)
ComputeRC(gpr.GetImm(a), 0);
ComputeRC0(gpr.GetImm(a));
}
else
{
gpr.BindToRegister(a, a == s);
SBFM(gpr.R(a), gpr.R(s), 0, size - 1);
if (inst.Rc)
ComputeRC(gpr.R(a), 0);
ComputeRC0(gpr.R(a));
}
}
@ -366,14 +359,14 @@ void JitArm64::cntlzwx(UGeckoInstruction inst)
{
gpr.SetImmediate(a, __builtin_clz(gpr.GetImm(s)));
if (inst.Rc)
ComputeRC(gpr.GetImm(a), 0);
ComputeRC0(gpr.GetImm(a));
}
else
{
gpr.BindToRegister(a, a == s);
CLZ(gpr.R(a), gpr.R(s));
if (inst.Rc)
ComputeRC(gpr.R(a), 0);
ComputeRC0(gpr.R(a));
}
}
@ -390,14 +383,14 @@ void JitArm64::negx(UGeckoInstruction inst)
{
gpr.SetImmediate(d, ~((u32)gpr.GetImm(a)) + 1);
if (inst.Rc)
ComputeRC(gpr.GetImm(d), 0);
ComputeRC0(gpr.GetImm(d));
}
else
{
gpr.BindToRegister(d, d == a);
SUB(gpr.R(d), WSP, gpr.R(a));
if (inst.Rc)
ComputeRC(gpr.R(d), 0);
ComputeRC0(gpr.R(d));
}
}
@ -533,7 +526,7 @@ void JitArm64::rlwinmx(UGeckoInstruction inst)
{
gpr.SetImmediate(a, _rotl(gpr.GetImm(s), inst.SH) & mask);
if (inst.Rc)
ComputeRC(gpr.GetImm(a), 0);
ComputeRC0(gpr.GetImm(a));
return;
}
@ -546,7 +539,7 @@ void JitArm64::rlwinmx(UGeckoInstruction inst)
gpr.Unlock(WA);
if (inst.Rc)
ComputeRC(gpr.R(a), 0);
ComputeRC0(gpr.R(a));
}
void JitArm64::rlwnmx(UGeckoInstruction inst)
@ -560,7 +553,7 @@ void JitArm64::rlwnmx(UGeckoInstruction inst)
{
gpr.SetImmediate(a, _rotl(gpr.GetImm(s), gpr.GetImm(b) & 0x1F) & mask);
if (inst.Rc)
ComputeRC(gpr.GetImm(a), 0);
ComputeRC0(gpr.GetImm(a));
}
else if (gpr.IsImm(b))
{
@ -571,7 +564,7 @@ void JitArm64::rlwnmx(UGeckoInstruction inst)
AND(gpr.R(a), WA, gpr.R(s), Shift);
gpr.Unlock(WA);
if (inst.Rc)
ComputeRC(gpr.R(a), 0);
ComputeRC0(gpr.R(a));
}
else
{
@ -582,7 +575,7 @@ void JitArm64::rlwnmx(UGeckoInstruction inst)
ANDI2R(gpr.R(a), gpr.R(a), mask, WA);
gpr.Unlock(WA);
if (inst.Rc)
ComputeRC(gpr.R(a), 0);
ComputeRC0(gpr.R(a));
}
}
@ -653,7 +646,7 @@ void JitArm64::srawix(UGeckoInstruction inst)
}
if (inst.Rc)
ComputeRC(RA, 0);
ComputeRC0(RA);
}
}
@ -675,7 +668,7 @@ void JitArm64::addic(UGeckoInstruction inst)
bool has_carry = Interpreter::Helper_Carry(i, imm);
ComputeCarry(has_carry);
if (rc)
ComputeRC(gpr.GetImm(d), 0);
ComputeRC0(gpr.GetImm(d));
}
else
{
@ -686,7 +679,7 @@ void JitArm64::addic(UGeckoInstruction inst)
ComputeCarry();
if (rc)
ComputeRC(gpr.R(d), 0);
ComputeRC0(gpr.R(d));
}
}
@ -725,14 +718,14 @@ void JitArm64::mullwx(UGeckoInstruction inst)
s32 i = (s32)gpr.GetImm(a), j = (s32)gpr.GetImm(b);
gpr.SetImmediate(d, i * j);
if (inst.Rc)
ComputeRC(gpr.GetImm(d), 0);
ComputeRC0(gpr.GetImm(d));
}
else
{
gpr.BindToRegister(d, d == a || d == b);
MUL(gpr.R(d), gpr.R(a), gpr.R(b));
if (inst.Rc)
ComputeRC(gpr.R(d), 0);
ComputeRC0(gpr.R(d));
}
}
@ -748,7 +741,7 @@ void JitArm64::mulhwx(UGeckoInstruction inst)
s32 i = (s32)gpr.GetImm(a), j = (s32)gpr.GetImm(b);
gpr.SetImmediate(d, (u32)((u64)(((s64)i * (s64)j)) >> 32));
if (inst.Rc)
ComputeRC(gpr.GetImm(d), 0);
ComputeRC0(gpr.GetImm(d));
}
else
{
@ -757,7 +750,7 @@ void JitArm64::mulhwx(UGeckoInstruction inst)
LSR(EncodeRegTo64(gpr.R(d)), EncodeRegTo64(gpr.R(d)), 32);
if (inst.Rc)
ComputeRC(gpr.R(d), 0);
ComputeRC0(gpr.R(d));
}
}
@ -773,7 +766,7 @@ void JitArm64::mulhwux(UGeckoInstruction inst)
u32 i = gpr.GetImm(a), j = gpr.GetImm(b);
gpr.SetImmediate(d, (u32)(((u64)i * (u64)j) >> 32));
if (inst.Rc)
ComputeRC(gpr.GetImm(d), 0);
ComputeRC0(gpr.GetImm(d));
}
else
{
@ -782,7 +775,7 @@ void JitArm64::mulhwux(UGeckoInstruction inst)
LSR(EncodeRegTo64(gpr.R(d)), EncodeRegTo64(gpr.R(d)), 32);
if (inst.Rc)
ComputeRC(gpr.R(d), 0);
ComputeRC0(gpr.R(d));
}
}
@ -816,7 +809,7 @@ void JitArm64::addzex(UGeckoInstruction inst)
ComputeCarry();
if (inst.Rc)
ComputeRC(gpr.R(d), 0);
ComputeRC0(gpr.R(d));
}
void JitArm64::subfx(UGeckoInstruction inst)
@ -832,14 +825,14 @@ void JitArm64::subfx(UGeckoInstruction inst)
u32 i = gpr.GetImm(a), j = gpr.GetImm(b);
gpr.SetImmediate(d, j - i);
if (inst.Rc)
ComputeRC(gpr.GetImm(d), 0);
ComputeRC0(gpr.GetImm(d));
}
else
{
gpr.BindToRegister(d, d == a || d == b);
SUB(gpr.R(d), gpr.R(b), gpr.R(a));
if (inst.Rc)
ComputeRC(gpr.R(d), 0);
ComputeRC0(gpr.R(d));
}
}
@ -910,7 +903,7 @@ void JitArm64::subfex(UGeckoInstruction inst)
}
if (inst.Rc)
ComputeRC(gpr.R(d), 0);
ComputeRC0(gpr.R(d));
}
void JitArm64::subfcx(UGeckoInstruction inst)
@ -929,7 +922,7 @@ void JitArm64::subfcx(UGeckoInstruction inst)
ComputeCarry(a_imm == 0 || Interpreter::Helper_Carry(b_imm, 0u - a_imm));
if (inst.Rc)
ComputeRC(gpr.GetImm(d), 0);
ComputeRC0(gpr.GetImm(d));
}
else
{
@ -941,7 +934,7 @@ void JitArm64::subfcx(UGeckoInstruction inst)
ComputeCarry();
if (inst.Rc)
ComputeRC(gpr.R(d), 0);
ComputeRC0(gpr.R(d));
}
}
@ -972,7 +965,7 @@ void JitArm64::subfzex(UGeckoInstruction inst)
ComputeCarry();
if (inst.Rc)
ComputeRC(gpr.R(d));
ComputeRC0(gpr.R(d));
}
void JitArm64::subfic(UGeckoInstruction inst)
@ -1066,7 +1059,7 @@ void JitArm64::addex(UGeckoInstruction inst)
}
if (inst.Rc)
ComputeRC(gpr.R(d), 0);
ComputeRC0(gpr.R(d));
}
void JitArm64::addcx(UGeckoInstruction inst)
@ -1085,7 +1078,7 @@ void JitArm64::addcx(UGeckoInstruction inst)
bool has_carry = Interpreter::Helper_Carry(i, j);
ComputeCarry(has_carry);
if (inst.Rc)
ComputeRC(gpr.GetImm(d), 0);
ComputeRC0(gpr.GetImm(d));
}
else
{
@ -1094,7 +1087,7 @@ void JitArm64::addcx(UGeckoInstruction inst)
ComputeCarry();
if (inst.Rc)
ComputeRC(gpr.R(d), 0);
ComputeRC0(gpr.R(d));
}
}
@ -1112,7 +1105,7 @@ void JitArm64::divwux(UGeckoInstruction inst)
gpr.SetImmediate(d, j == 0 ? 0 : i / j);
if (inst.Rc)
ComputeRC(gpr.GetImm(d), 0);
ComputeRC0(gpr.GetImm(d));
}
else
{
@ -1122,7 +1115,7 @@ void JitArm64::divwux(UGeckoInstruction inst)
UDIV(gpr.R(d), gpr.R(a), gpr.R(b));
if (inst.Rc)
ComputeRC(gpr.R(d), 0);
ComputeRC0(gpr.R(d));
}
}
@ -1153,7 +1146,7 @@ void JitArm64::divwx(UGeckoInstruction inst)
gpr.SetImmediate(d, imm_d);
if (inst.Rc)
ComputeRC(imm_d);
ComputeRC0(imm_d);
}
else if (gpr.IsImm(b) && gpr.GetImm(b) != 0 && gpr.GetImm(b) != -1u)
{
@ -1167,7 +1160,7 @@ void JitArm64::divwx(UGeckoInstruction inst)
gpr.Unlock(WA);
if (inst.Rc)
ComputeRC(gpr.R(d));
ComputeRC0(gpr.R(d));
}
else
{
@ -1200,7 +1193,7 @@ void JitArm64::divwx(UGeckoInstruction inst)
gpr.Unlock(WA);
if (inst.Rc)
ComputeRC(RD);
ComputeRC0(RD);
}
}
@ -1217,7 +1210,7 @@ void JitArm64::slwx(UGeckoInstruction inst)
gpr.SetImmediate(a, (j & 0x20) ? 0 : i << (j & 0x1F));
if (inst.Rc)
ComputeRC(gpr.GetImm(a), 0);
ComputeRC0(gpr.GetImm(a));
}
else if (gpr.IsImm(b))
{
@ -1226,14 +1219,14 @@ void JitArm64::slwx(UGeckoInstruction inst)
{
gpr.SetImmediate(a, 0);
if (inst.Rc)
ComputeRC(0, 0);
ComputeRC0(0);
}
else
{
gpr.BindToRegister(a, a == s);
LSL(gpr.R(a), gpr.R(s), i & 0x1F);
if (inst.Rc)
ComputeRC(gpr.R(a), 0);
ComputeRC0(gpr.R(a));
}
}
else
@ -1248,7 +1241,7 @@ void JitArm64::slwx(UGeckoInstruction inst)
LSLV(EncodeRegTo64(gpr.R(a)), EncodeRegTo64(gpr.R(s)), EncodeRegTo64(gpr.R(b)));
if (inst.Rc)
ComputeRC(gpr.R(a), 0);
ComputeRC0(gpr.R(a));
}
}
@ -1265,7 +1258,7 @@ void JitArm64::srwx(UGeckoInstruction inst)
gpr.SetImmediate(a, (amount & 0x20) ? 0 : i >> (amount & 0x1F));
if (inst.Rc)
ComputeRC(gpr.GetImm(a), 0);
ComputeRC0(gpr.GetImm(a));
}
else if (gpr.IsImm(b))
{
@ -1274,14 +1267,14 @@ void JitArm64::srwx(UGeckoInstruction inst)
{
gpr.SetImmediate(a, 0);
if (inst.Rc)
ComputeRC(0, 0);
ComputeRC0(0);
}
else
{
gpr.BindToRegister(a, a == s);
LSR(gpr.R(a), gpr.R(s), amount & 0x1F);
if (inst.Rc)
ComputeRC(gpr.R(a), 0);
ComputeRC0(gpr.R(a));
}
}
else
@ -1295,7 +1288,7 @@ void JitArm64::srwx(UGeckoInstruction inst)
LSRV(EncodeRegTo64(gpr.R(a)), EncodeRegTo64(gpr.R(s)), EncodeRegTo64(gpr.R(b)));
if (inst.Rc)
ComputeRC(gpr.R(a), 0);
ComputeRC0(gpr.R(a));
}
}
@ -1323,7 +1316,7 @@ void JitArm64::srawx(UGeckoInstruction inst)
}
if (inst.Rc)
ComputeRC(gpr.GetImm(a), 0);
ComputeRC0(gpr.GetImm(a));
return;
}
@ -1399,7 +1392,7 @@ void JitArm64::srawx(UGeckoInstruction inst)
}
if (inst.Rc)
ComputeRC(gpr.R(a), 0);
ComputeRC0(gpr.R(a));
}
void JitArm64::rlwimix(UGeckoInstruction inst)
@ -1415,7 +1408,7 @@ void JitArm64::rlwimix(UGeckoInstruction inst)
u32 res = (gpr.GetImm(a) & ~mask) | (_rotl(gpr.GetImm(s), inst.SH) & mask);
gpr.SetImmediate(a, res);
if (inst.Rc)
ComputeRC(res, 0);
ComputeRC0(res);
}
else
{
@ -1474,6 +1467,6 @@ void JitArm64::rlwimix(UGeckoInstruction inst)
}
if (inst.Rc)
ComputeRC(gpr.R(a), 0);
ComputeRC0(gpr.R(a));
}
}