Skip to content

Commit

Permalink
Merge pull request #2928 from Sonicadvance1/aarch64_improved_singles
Browse files Browse the repository at this point in the history
[AArch64] Improve floating point single instructions.
  • Loading branch information
Sonicadvance1 committed Aug 31, 2015
2 parents d003934 + bcde1aa commit 0f54aa4
Show file tree
Hide file tree
Showing 8 changed files with 300 additions and 224 deletions.
18 changes: 4 additions & 14 deletions Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp
Expand Up @@ -76,23 +76,13 @@ void JitArm64::EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode,
if (flags & BackPatchInfo::FLAG_SIZE_F32)
{
m_float_emit.LDR(32, EncodeRegToDouble(RS), X28, addr);
m_float_emit.INS(32, RS, 1, RS, 0);
m_float_emit.REV32(8, EncodeRegToDouble(RS), EncodeRegToDouble(RS));
m_float_emit.FCVTL(64, EncodeRegToDouble(RS), EncodeRegToDouble(RS));
}
else
{
if (flags & BackPatchInfo::FLAG_ONLY_LOWER)
{
m_float_emit.LDR(64, EncodeRegToDouble(RS), X28, addr);
m_float_emit.REV64(8, EncodeRegToDouble(RS), EncodeRegToDouble(RS));
}
else
{
m_float_emit.LDR(64, Q0, X28, addr);
m_float_emit.REV64(8, D0, D0);
m_float_emit.INS(64, RS, 0, Q0, 0);
}
m_float_emit.LDR(64, EncodeRegToDouble(RS), X28, addr);
m_float_emit.REV64(8, EncodeRegToDouble(RS), EncodeRegToDouble(RS));
}
}
else if (flags & BackPatchInfo::FLAG_STORE)
Expand Down Expand Up @@ -142,7 +132,7 @@ void JitArm64::EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode,
handler.addr_reg = addr;
handler.gprs = gprs_to_push;
handler.fprs = fprs_to_push;
handler.flags = flags & ~BackPatchInfo::FLAG_ONLY_LOWER;
handler.flags = flags;

FastmemArea* fastmem_area = &m_fault_to_handler[fastmem_start];
auto handler_loc_iter = m_handler_to_loc.find(handler);
Expand Down Expand Up @@ -199,7 +189,7 @@ void JitArm64::EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode,
{
MOVI2R(X30, (u64)&PowerPC::Read_U32);
BLR(X30);
m_float_emit.DUP(32, RS, X0);
m_float_emit.INS(32, RS, 0, X0);
m_float_emit.FCVTL(64, RS, RS);
}
else
Expand Down
151 changes: 73 additions & 78 deletions Source/Core/Core/PowerPC/JitArm64/JitArm64_FloatingPoint.cpp
Expand Up @@ -24,7 +24,7 @@ void JitArm64::fabsx(UGeckoInstruction inst)

u32 b = inst.FB, d = inst.FD;
fpr.BindToRegister(d, d == b);
ARM64Reg VB = fpr.R(b);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d);

m_float_emit.FABS(EncodeRegToDouble(VD), EncodeRegToDouble(VB));
Expand All @@ -37,14 +37,13 @@ void JitArm64::faddsx(UGeckoInstruction inst)
FALLBACK_IF(inst.Rc);

u32 a = inst.FA, b = inst.FB, d = inst.FD;
fpr.BindToRegister(d, d == a || d == b, false);
fpr.BindToRegister(d, d == a || d == b, REG_DUP);

ARM64Reg VA = fpr.R(a);
ARM64Reg VB = fpr.R(b);
ARM64Reg VD = fpr.R(d, false);
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d, REG_DUP);

m_float_emit.FADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
m_float_emit.INS(64, VD, 1, VD, 0);
}

void JitArm64::faddx(UGeckoInstruction inst)
Expand All @@ -56,8 +55,8 @@ void JitArm64::faddx(UGeckoInstruction inst)
u32 a = inst.FA, b = inst.FB, d = inst.FD;
fpr.BindToRegister(d, d == a || d == b);

ARM64Reg VA = fpr.R(a);
ARM64Reg VB = fpr.R(b);
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d);

m_float_emit.FADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
Expand All @@ -70,17 +69,17 @@ void JitArm64::fmaddsx(UGeckoInstruction inst)
FALLBACK_IF(inst.Rc);

u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
fpr.BindToRegister(d, d == a || d == b || d == c, false);
fpr.BindToRegister(d, d == a || d == b || d == c, REG_DUP);

ARM64Reg VA = fpr.R(a);
ARM64Reg VB = fpr.R(b);
ARM64Reg VC = fpr.R(c);
ARM64Reg VD = fpr.R(d, false);
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VC = fpr.R(c, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d, REG_DUP);
ARM64Reg V0 = fpr.GetReg();

m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
m_float_emit.FADD(EncodeRegToDouble(VD), EncodeRegToDouble(V0), EncodeRegToDouble(VB));
m_float_emit.INS(64, VD, 1, VD, 0);

fpr.Unlock(V0);
}

Expand All @@ -93,9 +92,9 @@ void JitArm64::fmaddx(UGeckoInstruction inst)
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
fpr.BindToRegister(d, d == a || d == b || d == c);

ARM64Reg VA = fpr.R(a);
ARM64Reg VB = fpr.R(b);
ARM64Reg VC = fpr.R(c);
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VC = fpr.R(c, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d);

m_float_emit.FMADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
Expand All @@ -110,7 +109,7 @@ void JitArm64::fmrx(UGeckoInstruction inst)
u32 b = inst.FB, d = inst.FD;
fpr.BindToRegister(d, d == b);

ARM64Reg VB = fpr.R(b);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d);

m_float_emit.INS(64, VD, 0, VB, 0);
Expand All @@ -123,17 +122,17 @@ void JitArm64::fmsubsx(UGeckoInstruction inst)
FALLBACK_IF(inst.Rc);

u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
fpr.BindToRegister(d, d == a || d == b || d == c, false);
fpr.BindToRegister(d, d == a || d == b || d == c, REG_DUP);

ARM64Reg VA = fpr.R(a);
ARM64Reg VB = fpr.R(b);
ARM64Reg VC = fpr.R(c);
ARM64Reg VD = fpr.R(d, false);
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VC = fpr.R(c, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d, REG_DUP);
ARM64Reg V0 = fpr.GetReg();

m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
m_float_emit.FSUB(EncodeRegToDouble(VD), EncodeRegToDouble(V0), EncodeRegToDouble(VB));
m_float_emit.INS(64, VD, 1, VD, 0);

fpr.Unlock(V0);
}

Expand All @@ -146,9 +145,9 @@ void JitArm64::fmsubx(UGeckoInstruction inst)
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
fpr.BindToRegister(d, d == a || d == b || d == c);

ARM64Reg VA = fpr.R(a);
ARM64Reg VB = fpr.R(b);
ARM64Reg VC = fpr.R(c);
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VC = fpr.R(c, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d);

m_float_emit.FNMSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
Expand All @@ -161,14 +160,13 @@ void JitArm64::fmulsx(UGeckoInstruction inst)
FALLBACK_IF(inst.Rc);

u32 a = inst.FA, c = inst.FC, d = inst.FD;
fpr.BindToRegister(d, d == a || d == c, false);
fpr.BindToRegister(d, d == a || d == c, REG_DUP);

ARM64Reg VA = fpr.R(a);
ARM64Reg VC = fpr.R(c);
ARM64Reg VD = fpr.R(d, false);
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VC = fpr.R(c, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d, REG_DUP);

m_float_emit.FMUL(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
m_float_emit.INS(64, VD, 1, VD, 0);
}

void JitArm64::fmulx(UGeckoInstruction inst)
Expand All @@ -180,8 +178,8 @@ void JitArm64::fmulx(UGeckoInstruction inst)
u32 a = inst.FA, c = inst.FC, d = inst.FD;
fpr.BindToRegister(d, d == a || d == c);

ARM64Reg VA = fpr.R(a);
ARM64Reg VC = fpr.R(c);
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VC = fpr.R(c, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d);

m_float_emit.FMUL(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
Expand All @@ -196,7 +194,7 @@ void JitArm64::fnabsx(UGeckoInstruction inst)
u32 b = inst.FB, d = inst.FD;
fpr.BindToRegister(d, d == b);

ARM64Reg VB = fpr.R(b);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d);

m_float_emit.FABS(EncodeRegToDouble(VD), EncodeRegToDouble(VB));
Expand All @@ -212,7 +210,7 @@ void JitArm64::fnegx(UGeckoInstruction inst)
u32 b = inst.FB, d = inst.FD;
fpr.BindToRegister(d, d == b);

ARM64Reg VB = fpr.R(b);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d);

m_float_emit.FNEG(EncodeRegToDouble(VD), EncodeRegToDouble(VB));
Expand All @@ -225,18 +223,18 @@ void JitArm64::fnmaddsx(UGeckoInstruction inst)
FALLBACK_IF(inst.Rc);

u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
fpr.BindToRegister(d, d == a || d == b || d == c, false);
fpr.BindToRegister(d, d == a || d == b || d == c, REG_DUP);

ARM64Reg VA = fpr.R(a);
ARM64Reg VB = fpr.R(b);
ARM64Reg VC = fpr.R(c);
ARM64Reg VD = fpr.R(d, false);
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VC = fpr.R(c, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d, REG_DUP);
ARM64Reg V0 = fpr.GetReg();

m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
m_float_emit.FADD(EncodeRegToDouble(VD), EncodeRegToDouble(V0), EncodeRegToDouble(VB));
m_float_emit.FNEG(EncodeRegToDouble(VD), EncodeRegToDouble(VD));
m_float_emit.INS(64, VD, 1, VD, 0);

fpr.Unlock(V0);
}

Expand All @@ -249,9 +247,9 @@ void JitArm64::fnmaddx(UGeckoInstruction inst)
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
fpr.BindToRegister(d, d == a || d == b || d == c);

ARM64Reg VA = fpr.R(a);
ARM64Reg VB = fpr.R(b);
ARM64Reg VC = fpr.R(c);
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VC = fpr.R(c, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d);

m_float_emit.FNMADD(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
Expand All @@ -264,18 +262,18 @@ void JitArm64::fnmsubsx(UGeckoInstruction inst)
FALLBACK_IF(inst.Rc);

u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
fpr.BindToRegister(d, d == a || d == b || d == c, false);
fpr.BindToRegister(d, d == a || d == b || d == c, REG_DUP);

ARM64Reg VA = fpr.R(a);
ARM64Reg VB = fpr.R(b);
ARM64Reg VC = fpr.R(c);
ARM64Reg VD = fpr.R(d, false);
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VC = fpr.R(c, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d, REG_DUP);
ARM64Reg V0 = fpr.GetReg();

m_float_emit.FMUL(EncodeRegToDouble(V0), EncodeRegToDouble(VA), EncodeRegToDouble(VC));
m_float_emit.FSUB(EncodeRegToDouble(VD), EncodeRegToDouble(V0), EncodeRegToDouble(VB));
m_float_emit.FNEG(EncodeRegToDouble(VD), EncodeRegToDouble(VD));
m_float_emit.INS(64, VD, 1, VD, 0);

fpr.Unlock(V0);
}

Expand All @@ -288,9 +286,9 @@ void JitArm64::fnmsubx(UGeckoInstruction inst)
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
fpr.BindToRegister(d, d == a || d == b || d == c);

ARM64Reg VA = fpr.R(a);
ARM64Reg VB = fpr.R(b);
ARM64Reg VC = fpr.R(c);
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VC = fpr.R(c, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d);

m_float_emit.FMSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VC), EncodeRegToDouble(VB));
Expand All @@ -305,9 +303,9 @@ void JitArm64::fselx(UGeckoInstruction inst)
u32 a = inst.FA, b = inst.FB, c = inst.FC, d = inst.FD;
fpr.BindToRegister(d, d == a || d == b || d == c);

ARM64Reg VD = fpr.R(d);
ARM64Reg VA = fpr.R(a);
ARM64Reg VB = fpr.R(b);
ARM64Reg VD = fpr.R(d, REG_IS_LOADED);
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VC = fpr.R(c);

m_float_emit.FCMPE(EncodeRegToDouble(VA));
Expand All @@ -321,14 +319,13 @@ void JitArm64::fsubsx(UGeckoInstruction inst)
FALLBACK_IF(inst.Rc);

u32 a = inst.FA, b = inst.FB, d = inst.FD;
fpr.BindToRegister(d, d == a || d == b, false);
fpr.BindToRegister(d, d == a || d == b, REG_DUP);

ARM64Reg VA = fpr.R(a);
ARM64Reg VB = fpr.R(b);
ARM64Reg VD = fpr.R(d, false);
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d, REG_DUP);

m_float_emit.FSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
m_float_emit.INS(64, VD, 1, VD, 0);
}

void JitArm64::fsubx(UGeckoInstruction inst)
Expand All @@ -340,8 +337,8 @@ void JitArm64::fsubx(UGeckoInstruction inst)
u32 a = inst.FA, b = inst.FB, d = inst.FD;
fpr.BindToRegister(d, d == a || d == b);

ARM64Reg VA = fpr.R(a);
ARM64Reg VB = fpr.R(b);
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d);

m_float_emit.FSUB(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
Expand All @@ -353,14 +350,13 @@ void JitArm64::frspx(UGeckoInstruction inst)
JITDISABLE(bJITFloatingPointOff);

u32 b = inst.FB, d = inst.FD;
fpr.BindToRegister(d, d == b, false);
fpr.BindToRegister(d, d == b, REG_DUP);

ARM64Reg VB = fpr.R(b);
ARM64Reg VD = fpr.R(d, false);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d, REG_DUP);

m_float_emit.FCVTN(32, EncodeRegToDouble(VD), EncodeRegToDouble(VB));
m_float_emit.FCVTL(64, EncodeRegToDouble(VD), EncodeRegToDouble(VD));
m_float_emit.INS(64, VD, 1, VD, 0);
}

void JitArm64::fcmpx(UGeckoInstruction inst)
Expand All @@ -371,8 +367,8 @@ void JitArm64::fcmpx(UGeckoInstruction inst)
u32 a = inst.FA, b = inst.FB;
int crf = inst.CRFD;

ARM64Reg VA = fpr.R(a);
ARM64Reg VB = fpr.R(b);
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);

ARM64Reg WA = gpr.GetReg();
ARM64Reg XA = EncodeRegTo64(WA);
Expand Down Expand Up @@ -457,7 +453,7 @@ void JitArm64::fctiwzx(UGeckoInstruction inst)
u32 b = inst.FB, d = inst.FD;
fpr.BindToRegister(d, d == b);

ARM64Reg VB = fpr.R(b);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d);

ARM64Reg V0 = fpr.GetReg();
Expand All @@ -481,8 +477,8 @@ void JitArm64::fdivx(UGeckoInstruction inst)
u32 a = inst.FA, b = inst.FB, d = inst.FD;
fpr.BindToRegister(d, d == a || d == b);

ARM64Reg VA = fpr.R(a);
ARM64Reg VB = fpr.R(b);
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d);

m_float_emit.FDIV(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
Expand All @@ -495,12 +491,11 @@ void JitArm64::fdivsx(UGeckoInstruction inst)
FALLBACK_IF(inst.Rc);

u32 a = inst.FA, b = inst.FB, d = inst.FD;
fpr.BindToRegister(d, d == a || d == b, false);
fpr.BindToRegister(d, d == a || d == b, REG_DUP);

ARM64Reg VA = fpr.R(a);
ARM64Reg VB = fpr.R(b);
ARM64Reg VD = fpr.R(d, false);
ARM64Reg VA = fpr.R(a, REG_IS_LOADED);
ARM64Reg VB = fpr.R(b, REG_IS_LOADED);
ARM64Reg VD = fpr.R(d, REG_DUP);

m_float_emit.FDIV(EncodeRegToDouble(VD), EncodeRegToDouble(VA), EncodeRegToDouble(VB));
m_float_emit.INS(64, VD, 1, VD, 0);
}

0 comments on commit 0f54aa4

Please sign in to comment.