Skip to content

Commit

Permalink
[AArch64] Adds support for BindToRegister to the integer instructions.
Browse files Browse the repository at this point in the history
This requires PR dolphin-emu#1723 prior to merging.
  • Loading branch information
Sonicadvance1 committed Dec 20, 2014
1 parent 31bc510 commit dae45f7
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 30 deletions.
8 changes: 4 additions & 4 deletions Source/Core/Core/PowerPC/JitArm64/Jit.h
Expand Up @@ -13,13 +13,12 @@
#include "Core/PowerPC/JitArm64/JitAsm.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:
Expand Down Expand Up @@ -117,9 +116,10 @@ class JitArm64 : public JitBase, public Arm64Gen::ARM64CodeBlock

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);
};

91 changes: 65 additions & 26 deletions Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
Expand Up @@ -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, reg);

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);
}
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);
}

Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -153,38 +161,47 @@ 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)
{
if ((inst.SUBOP10 == 28 /* andx */) || (inst.SUBOP10 == 444 /* orx */))
{
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));
Expand Down Expand Up @@ -224,7 +241,7 @@ void JitArm64::boolX(UGeckoInstruction inst)
PanicAlert("WTF!");
}
if (inst.Rc)
ComputeRC(a);
ComputeRC(gpr.R(a), 0);
}
}

Expand All @@ -235,13 +252,21 @@ void JitArm64::extsXx(UGeckoInstruction inst)
int a = inst.RA, s = inst.RS;
int size = inst.SUBOP10 == 922 ? 16 : 8;

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)
Expand All @@ -251,13 +276,20 @@ void JitArm64::cntlzwx(UGeckoInstruction inst)
int a = inst.RA;
int s = inst.RS;

gpr.BindToRegister(a, a == s);

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(a);
if (inst.Rc)
ComputeRC(gpr.R(a), 0);
}
}

void JitArm64::negx(UGeckoInstruction inst)
Expand All @@ -269,11 +301,18 @@ void JitArm64::negx(UGeckoInstruction inst)

FALLBACK_IF(inst.OE);

gpr.BindToRegister(d, d == a);

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(d);
if (inst.Rc)
ComputeRC(gpr.R(d), 0);
}
}

0 comments on commit dae45f7

Please sign in to comment.