mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-08 23:45:31 +02:00
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/JitArmCommon/BackPatch.h"
|
||||||
#include "Core/PowerPC/JitCommon/JitBase.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
|
// 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(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");
|
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
|
class JitArm64 : public JitBase, public Arm64Gen::ARM64CodeBlock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -132,9 +131,10 @@ private:
|
|||||||
|
|
||||||
FixupBranch JumpIfCRFieldBit(int field, int bit, bool jump_if_set);
|
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);
|
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;
|
using namespace Arm64Gen;
|
||||||
|
|
||||||
void JitArm64::ComputeRC(u32 d)
|
void JitArm64::ComputeRC(ARM64Reg reg, int crf)
|
||||||
{
|
{
|
||||||
ARM64Reg WA = gpr.GetReg();
|
ARM64Reg WA = gpr.GetReg();
|
||||||
ARM64Reg XA = EncodeRegTo64(WA);
|
ARM64Reg XA = EncodeRegTo64(WA);
|
||||||
|
|
||||||
if (gpr.IsImm(d))
|
SXTW(XA, reg);
|
||||||
{
|
|
||||||
MOVI2R(WA, gpr.GetImm(d));
|
|
||||||
SXTW(XA, WA);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SXTW(XA, gpr.R(d));
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
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))
|
if (gpr.IsImm(a))
|
||||||
{
|
{
|
||||||
gpr.SetImmediate(d, do_op(gpr.GetImm(a), value));
|
gpr.SetImmediate(d, do_op(gpr.GetImm(a), value));
|
||||||
|
if (Rc)
|
||||||
|
ComputeRC(gpr.GetImm(d));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
gpr.BindToRegister(d, d == a);
|
||||||
ARM64Reg WA = gpr.GetReg();
|
ARM64Reg WA = gpr.GetReg();
|
||||||
MOVI2R(WA, value);
|
MOVI2R(WA, value);
|
||||||
(this->*op)(gpr.R(d), gpr.R(a), WA, ArithOption(WA, ST_LSL, 0));
|
(this->*op)(gpr.R(d), gpr.R(a), WA, ArithOption(WA, ST_LSL, 0));
|
||||||
gpr.Unlock(WA);
|
gpr.Unlock(WA);
|
||||||
}
|
|
||||||
|
|
||||||
if (Rc)
|
if (Rc)
|
||||||
ComputeRC(d);
|
ComputeRC(gpr.R(d), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (do_op == Add)
|
else if (do_op == Add)
|
||||||
{
|
{
|
||||||
// a == 0, implies zero register
|
// a == 0, implies zero register
|
||||||
gpr.SetImmediate(d, value);
|
gpr.SetImmediate(d, value);
|
||||||
if (Rc)
|
if (Rc)
|
||||||
ComputeRC(d);
|
ComputeRC(value, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -153,7 +161,7 @@ void JitArm64::boolX(UGeckoInstruction inst)
|
|||||||
gpr.SetImmediate(a, ~((u32)gpr.GetImm(s) ^ (u32)gpr.GetImm(b)));
|
gpr.SetImmediate(a, ~((u32)gpr.GetImm(s) ^ (u32)gpr.GetImm(b)));
|
||||||
|
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
ComputeRC(a);
|
ComputeRC(gpr.GetImm(a), 0);
|
||||||
}
|
}
|
||||||
else if (s == b)
|
else if (s == b)
|
||||||
{
|
{
|
||||||
@ -161,30 +169,39 @@ void JitArm64::boolX(UGeckoInstruction inst)
|
|||||||
{
|
{
|
||||||
if (a != s)
|
if (a != s)
|
||||||
{
|
{
|
||||||
|
gpr.BindToRegister(a, false);
|
||||||
MOV(gpr.R(a), gpr.R(s));
|
MOV(gpr.R(a), gpr.R(s));
|
||||||
}
|
}
|
||||||
|
if (inst.Rc)
|
||||||
|
ComputeRC(gpr.R(a));
|
||||||
}
|
}
|
||||||
else if ((inst.SUBOP10 == 476 /* nandx */) || (inst.SUBOP10 == 124 /* norx */))
|
else if ((inst.SUBOP10 == 476 /* nandx */) || (inst.SUBOP10 == 124 /* norx */))
|
||||||
{
|
{
|
||||||
|
gpr.BindToRegister(a, a == s);
|
||||||
MVN(gpr.R(a), gpr.R(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 */))
|
else if ((inst.SUBOP10 == 412 /* orcx */) || (inst.SUBOP10 == 284 /* eqvx */))
|
||||||
{
|
{
|
||||||
gpr.SetImmediate(a, 0xFFFFFFFF);
|
gpr.SetImmediate(a, 0xFFFFFFFF);
|
||||||
|
if (inst.Rc)
|
||||||
|
ComputeRC(gpr.GetImm(a), 0);
|
||||||
}
|
}
|
||||||
else if ((inst.SUBOP10 == 60 /* andcx */) || (inst.SUBOP10 == 316 /* xorx */))
|
else if ((inst.SUBOP10 == 60 /* andcx */) || (inst.SUBOP10 == 316 /* xorx */))
|
||||||
{
|
{
|
||||||
gpr.SetImmediate(a, 0);
|
gpr.SetImmediate(a, 0);
|
||||||
|
if (inst.Rc)
|
||||||
|
ComputeRC(gpr.GetImm(a), 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PanicAlert("WTF!");
|
PanicAlert("WTF!");
|
||||||
}
|
}
|
||||||
if (inst.Rc)
|
|
||||||
ComputeRC(a);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
gpr.BindToRegister(a, (a == s) || (a == b));
|
||||||
if (inst.SUBOP10 == 28) // andx
|
if (inst.SUBOP10 == 28) // andx
|
||||||
{
|
{
|
||||||
AND(gpr.R(a), gpr.R(s), gpr.R(b), ArithOption(gpr.R(a), ST_LSL, 0));
|
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!");
|
PanicAlert("WTF!");
|
||||||
}
|
}
|
||||||
if (inst.Rc)
|
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 a = inst.RA, s = inst.RS;
|
||||||
int size = inst.SUBOP10 == 922 ? 16 : 8;
|
int size = inst.SUBOP10 == 922 ? 16 : 8;
|
||||||
|
|
||||||
if (gpr.IsImm(s))
|
gpr.BindToRegister(a, a == s);
|
||||||
gpr.SetImmediate(a, (u32)(s32)(size == 16 ? (s16)gpr.GetImm(s) : (s8)gpr.GetImm(s)));
|
|
||||||
else
|
if (gpr.IsImm(s))
|
||||||
SBFM(gpr.R(a), gpr.R(s), 0, size - 1);
|
{
|
||||||
|
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)
|
void JitArm64::cntlzwx(UGeckoInstruction inst)
|
||||||
@ -251,13 +276,20 @@ void JitArm64::cntlzwx(UGeckoInstruction inst)
|
|||||||
int a = inst.RA;
|
int a = inst.RA;
|
||||||
int s = inst.RS;
|
int s = inst.RS;
|
||||||
|
|
||||||
if (gpr.IsImm(s))
|
gpr.BindToRegister(a, a == s);
|
||||||
gpr.SetImmediate(a, __builtin_clz(gpr.GetImm(s)));
|
|
||||||
else
|
|
||||||
CLZ(gpr.R(a), gpr.R(s));
|
|
||||||
|
|
||||||
if (inst.Rc)
|
if (gpr.IsImm(s))
|
||||||
ComputeRC(a);
|
{
|
||||||
|
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)
|
void JitArm64::negx(UGeckoInstruction inst)
|
||||||
@ -269,11 +301,18 @@ void JitArm64::negx(UGeckoInstruction inst)
|
|||||||
|
|
||||||
FALLBACK_IF(inst.OE);
|
FALLBACK_IF(inst.OE);
|
||||||
|
|
||||||
if (gpr.IsImm(a))
|
gpr.BindToRegister(d, d == 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));
|
|
||||||
|
|
||||||
if (inst.Rc)
|
if (gpr.IsImm(a))
|
||||||
ComputeRC(d);
|
{
|
||||||
|
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
Block a user