Merge pull request #1728 from Sonicadvance1/AArch64_BindToRegister
[AArch64] Adds support for BindToRegister to the integer instructions.
This commit is contained in:
commit
1da6995d5b
|
@ -16,13 +16,12 @@
|
|||
#include "Core/PowerPC/JitArmCommon/BackPatch.h"
|
||||
#include "Core/PowerPC/JitCommon/JitBase.h"
|
||||
|
||||
#define PPCSTATE_OFF(elem) ((s64)&PowerPC::ppcState.elem - (s64)&PowerPC::ppcState)
|
||||
#define PPCSTATE_OFF(elem) (offsetof(PowerPC::PowerPCState, elem))
|
||||
|
||||
// Some asserts to make sure we will be able to load everything
|
||||
static_assert(PPCSTATE_OFF(spr[1023]) <= 16380, "LDR(32bit) can't reach the last SPR");
|
||||
static_assert((PPCSTATE_OFF(ps[0][0]) % 8) == 0, "LDR(64bit VFP) requires FPRs to be 8 byte aligned");
|
||||
|
||||
using namespace Arm64Gen;
|
||||
class JitArm64 : public JitBase, public Arm64Gen::ARM64CodeBlock
|
||||
{
|
||||
public:
|
||||
|
@ -132,9 +131,10 @@ private:
|
|||
|
||||
FixupBranch JumpIfCRFieldBit(int field, int bit, bool jump_if_set);
|
||||
|
||||
void ComputeRC(u32 d);
|
||||
void ComputeRC(Arm64Gen::ARM64Reg reg, int crf = 0);
|
||||
void ComputeRC(u32 imm, int crf = 0);
|
||||
|
||||
typedef u32 (*Operation)(u32, u32);
|
||||
void reg_imm(u32 d, u32 a, bool binary, u32 value, Operation do_op, void (ARM64XEmitter::*op)(ARM64Reg, ARM64Reg, ARM64Reg, ArithOption), bool Rc = false);
|
||||
void reg_imm(u32 d, u32 a, bool binary, u32 value, Operation do_op, void (ARM64XEmitter::*op)(Arm64Gen::ARM64Reg, Arm64Gen::ARM64Reg, Arm64Gen::ARM64Reg, ArithOption), bool Rc = false);
|
||||
};
|
||||
|
||||
|
|
|
@ -15,22 +15,27 @@
|
|||
|
||||
using namespace Arm64Gen;
|
||||
|
||||
void JitArm64::ComputeRC(u32 d)
|
||||
void JitArm64::ComputeRC(ARM64Reg reg, int crf)
|
||||
{
|
||||
ARM64Reg WA = gpr.GetReg();
|
||||
ARM64Reg XA = EncodeRegTo64(WA);
|
||||
|
||||
if (gpr.IsImm(d))
|
||||
{
|
||||
MOVI2R(WA, gpr.GetImm(d));
|
||||
SXTW(XA, WA);
|
||||
}
|
||||
else
|
||||
{
|
||||
SXTW(XA, gpr.R(d));
|
||||
}
|
||||
SXTW(XA, reg);
|
||||
|
||||
STR(INDEX_UNSIGNED, XA, X29, PPCSTATE_OFF(cr_val[0]));
|
||||
STR(INDEX_UNSIGNED, XA, X29, PPCSTATE_OFF(cr_val[crf]));
|
||||
gpr.Unlock(WA);
|
||||
}
|
||||
|
||||
void JitArm64::ComputeRC(u32 imm, int crf)
|
||||
{
|
||||
ARM64Reg WA = gpr.GetReg();
|
||||
ARM64Reg XA = EncodeRegTo64(WA);
|
||||
|
||||
MOVI2R(WA, imm);
|
||||
if (!(imm & 0x80000000))
|
||||
SXTW(XA, WA);
|
||||
|
||||
STR(INDEX_UNSIGNED, XA, X29, PPCSTATE_OFF(cr_val[crf]));
|
||||
gpr.Unlock(WA);
|
||||
}
|
||||
|
||||
|
@ -62,24 +67,27 @@ void JitArm64::reg_imm(u32 d, u32 a, bool binary, u32 value, Operation do_op, vo
|
|||
if (gpr.IsImm(a))
|
||||
{
|
||||
gpr.SetImmediate(d, do_op(gpr.GetImm(a), value));
|
||||
if (Rc)
|
||||
ComputeRC(gpr.GetImm(d));
|
||||
}
|
||||
else
|
||||
{
|
||||
gpr.BindToRegister(d, d == a);
|
||||
ARM64Reg WA = gpr.GetReg();
|
||||
MOVI2R(WA, value);
|
||||
(this->*op)(gpr.R(d), gpr.R(a), WA, ArithOption(WA, ST_LSL, 0));
|
||||
gpr.Unlock(WA);
|
||||
}
|
||||
|
||||
if (Rc)
|
||||
ComputeRC(d);
|
||||
if (Rc)
|
||||
ComputeRC(gpr.R(d), 0);
|
||||
}
|
||||
}
|
||||
else if (do_op == Add)
|
||||
{
|
||||
// a == 0, implies zero register
|
||||
gpr.SetImmediate(d, value);
|
||||
if (Rc)
|
||||
ComputeRC(d);
|
||||
ComputeRC(value, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -153,7 +161,7 @@ void JitArm64::boolX(UGeckoInstruction inst)
|
|||
gpr.SetImmediate(a, ~((u32)gpr.GetImm(s) ^ (u32)gpr.GetImm(b)));
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(a);
|
||||
ComputeRC(gpr.GetImm(a), 0);
|
||||
}
|
||||
else if (s == b)
|
||||
{
|
||||
|
@ -161,30 +169,39 @@ void JitArm64::boolX(UGeckoInstruction inst)
|
|||
{
|
||||
if (a != s)
|
||||
{
|
||||
gpr.BindToRegister(a, false);
|
||||
MOV(gpr.R(a), gpr.R(s));
|
||||
}
|
||||
if (inst.Rc)
|
||||
ComputeRC(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));
|
||||
}
|
||||
else if ((inst.SUBOP10 == 412 /* orcx */) || (inst.SUBOP10 == 284 /* eqvx */))
|
||||
{
|
||||
gpr.SetImmediate(a, 0xFFFFFFFF);
|
||||
if (inst.Rc)
|
||||
ComputeRC(gpr.GetImm(a), 0);
|
||||
}
|
||||
else if ((inst.SUBOP10 == 60 /* andcx */) || (inst.SUBOP10 == 316 /* xorx */))
|
||||
{
|
||||
gpr.SetImmediate(a, 0);
|
||||
if (inst.Rc)
|
||||
ComputeRC(gpr.GetImm(a), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
PanicAlert("WTF!");
|
||||
}
|
||||
if (inst.Rc)
|
||||
ComputeRC(a);
|
||||
}
|
||||
else
|
||||
{
|
||||
gpr.BindToRegister(a, (a == s) || (a == b));
|
||||
if (inst.SUBOP10 == 28) // andx
|
||||
{
|
||||
AND(gpr.R(a), gpr.R(s), gpr.R(b), ArithOption(gpr.R(a), ST_LSL, 0));
|
||||
|
@ -224,7 +241,7 @@ void JitArm64::boolX(UGeckoInstruction inst)
|
|||
PanicAlert("WTF!");
|
||||
}
|
||||
if (inst.Rc)
|
||||
ComputeRC(a);
|
||||
ComputeRC(gpr.R(a), 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,13 +252,21 @@ void JitArm64::extsXx(UGeckoInstruction inst)
|
|||
int a = inst.RA, s = inst.RS;
|
||||
int size = inst.SUBOP10 == 922 ? 16 : 8;
|
||||
|
||||
if (gpr.IsImm(s))
|
||||
gpr.SetImmediate(a, (u32)(s32)(size == 16 ? (s16)gpr.GetImm(s) : (s8)gpr.GetImm(s)));
|
||||
else
|
||||
SBFM(gpr.R(a), gpr.R(s), 0, size - 1);
|
||||
gpr.BindToRegister(a, a == s);
|
||||
|
||||
if (gpr.IsImm(s))
|
||||
{
|
||||
gpr.SetImmediate(a, (u32)(s32)(size == 16 ? (s16)gpr.GetImm(s) : (s8)gpr.GetImm(s)));
|
||||
if (inst.Rc)
|
||||
ComputeRC(gpr.GetImm(a), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SBFM(gpr.R(a), gpr.R(s), 0, size - 1);
|
||||
if (inst.Rc)
|
||||
ComputeRC(gpr.R(a), 0);
|
||||
}
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(a);
|
||||
}
|
||||
|
||||
void JitArm64::cntlzwx(UGeckoInstruction inst)
|
||||
|
@ -251,13 +276,20 @@ void JitArm64::cntlzwx(UGeckoInstruction inst)
|
|||
int a = inst.RA;
|
||||
int s = inst.RS;
|
||||
|
||||
if (gpr.IsImm(s))
|
||||
gpr.SetImmediate(a, __builtin_clz(gpr.GetImm(s)));
|
||||
else
|
||||
CLZ(gpr.R(a), gpr.R(s));
|
||||
gpr.BindToRegister(a, a == s);
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(a);
|
||||
if (gpr.IsImm(s))
|
||||
{
|
||||
gpr.SetImmediate(a, __builtin_clz(gpr.GetImm(s)));
|
||||
if (inst.Rc)
|
||||
ComputeRC(gpr.GetImm(a), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLZ(gpr.R(a), gpr.R(s));
|
||||
if (inst.Rc)
|
||||
ComputeRC(gpr.R(a), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JitArm64::negx(UGeckoInstruction inst)
|
||||
|
@ -269,11 +301,18 @@ void JitArm64::negx(UGeckoInstruction inst)
|
|||
|
||||
FALLBACK_IF(inst.OE);
|
||||
|
||||
if (gpr.IsImm(a))
|
||||
gpr.SetImmediate(d, ~((u32)gpr.GetImm(a)) + 1);
|
||||
else
|
||||
SUB(gpr.R(d), WSP, gpr.R(a), ArithOption(gpr.R(a), ST_LSL, 0));
|
||||
gpr.BindToRegister(d, d == a);
|
||||
|
||||
if (inst.Rc)
|
||||
ComputeRC(d);
|
||||
if (gpr.IsImm(a))
|
||||
{
|
||||
gpr.SetImmediate(d, ~((u32)gpr.GetImm(a)) + 1);
|
||||
if (inst.Rc)
|
||||
ComputeRC(gpr.GetImm(d), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
SUB(gpr.R(d), WSP, gpr.R(a), ArithOption(gpr.R(a), ST_LSL, 0));
|
||||
if (inst.Rc)
|
||||
ComputeRC(gpr.R(d), 0);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue