mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-12 23:48:58 +01:00
[ARM] fcmpo/fcmpu implementations.
This commit is contained in:
parent
c56ecce840
commit
0bcc20ca5b
@ -200,7 +200,9 @@ public:
|
|||||||
void fmrx(UGeckoInstruction _inst);
|
void fmrx(UGeckoInstruction _inst);
|
||||||
void fmaddsx(UGeckoInstruction _inst);
|
void fmaddsx(UGeckoInstruction _inst);
|
||||||
void fmaddx(UGeckoInstruction _inst);
|
void fmaddx(UGeckoInstruction _inst);
|
||||||
void fctiwzx(UGeckoInstruction inst);
|
void fctiwzx(UGeckoInstruction _inst);
|
||||||
|
void fcmpo(UGeckoInstruction _inst);
|
||||||
|
void fcmpu(UGeckoInstruction _inst);
|
||||||
|
|
||||||
// Floating point loadStore
|
// Floating point loadStore
|
||||||
void lfs(UGeckoInstruction _inst);
|
void lfs(UGeckoInstruction _inst);
|
||||||
|
@ -38,10 +38,12 @@ static Operand2 FRFIMask(5, 0x8); // 0x60000
|
|||||||
static Operand2 FIMask(2, 8); // 0x20000
|
static Operand2 FIMask(2, 8); // 0x20000
|
||||||
static Operand2 FRMask(4, 8); // 0x40000
|
static Operand2 FRMask(4, 8); // 0x40000
|
||||||
static Operand2 FXMask(2, 1); // 0x80000000
|
static Operand2 FXMask(2, 1); // 0x80000000
|
||||||
|
static Operand2 VEMask(0x40, 0); // 0x40
|
||||||
|
|
||||||
static Operand2 XXException(2, 4); // 0x2000000
|
static Operand2 XXException(2, 4); // 0x2000000
|
||||||
static Operand2 CVIException(1, 0xC); // 0x100
|
static Operand2 CVIException(1, 0xC); // 0x100
|
||||||
|
static Operand2 NANException(1, 4); // 0x1000000
|
||||||
|
static Operand2 VXVCException(8, 8); // 0x80000
|
||||||
void JitArm::Helper_UpdateCR1(ARMReg value)
|
void JitArm::Helper_UpdateCR1(ARMReg value)
|
||||||
{
|
{
|
||||||
// Should just update exception flags, not do any compares.
|
// Should just update exception flags, not do any compares.
|
||||||
@ -59,6 +61,12 @@ void JitArm::SetFPException(ARMReg Reg, u32 Exception)
|
|||||||
case FPSCR_XX:
|
case FPSCR_XX:
|
||||||
ExceptionMask = &XXException;
|
ExceptionMask = &XXException;
|
||||||
break;
|
break;
|
||||||
|
case FPSCR_VXSNAN:
|
||||||
|
ExceptionMask = &NANException;
|
||||||
|
break;
|
||||||
|
case FPSCR_VXVC:
|
||||||
|
ExceptionMask = &VXVCException;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
_assert_msg_(DYNA_REC, false, "Passed unsupported FPexception: 0x%08x", Exception);
|
_assert_msg_(DYNA_REC, false, "Passed unsupported FPexception: 0x%08x", Exception);
|
||||||
return;
|
return;
|
||||||
@ -87,7 +95,7 @@ void JitArm::fctiwzx(UGeckoInstruction inst)
|
|||||||
ARMReg V0 = fpr.GetReg();
|
ARMReg V0 = fpr.GetReg();
|
||||||
ARMReg V1 = fpr.GetReg();
|
ARMReg V1 = fpr.GetReg();
|
||||||
ARMReg V2 = fpr.GetReg();
|
ARMReg V2 = fpr.GetReg();
|
||||||
|
|
||||||
ARMReg rA = gpr.GetReg();
|
ARMReg rA = gpr.GetReg();
|
||||||
ARMReg fpscrReg = gpr.GetReg();
|
ARMReg fpscrReg = gpr.GetReg();
|
||||||
|
|
||||||
@ -155,6 +163,136 @@ void JitArm::fctiwzx(UGeckoInstruction inst)
|
|||||||
fpr.Unlock(V2);
|
fpr.Unlock(V2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JitArm::fcmpo(UGeckoInstruction inst)
|
||||||
|
{
|
||||||
|
INSTRUCTION_START
|
||||||
|
JITDISABLE(bJITFloatingPointOff)
|
||||||
|
u32 a = inst.FA, b = inst.FB;
|
||||||
|
int cr = inst.CRFD;
|
||||||
|
|
||||||
|
ARMReg vA = fpr.R0(a);
|
||||||
|
ARMReg vB = fpr.R0(b);
|
||||||
|
ARMReg fpscrReg = gpr.GetReg();
|
||||||
|
ARMReg crReg = gpr.GetReg();
|
||||||
|
Operand2 FPRFMask(0x1F, 0xA); // 0x1F000
|
||||||
|
Operand2 LessThan(0x8, 0xA); // 0x8000
|
||||||
|
Operand2 GreaterThan(0x4, 0xA); // 0x4000
|
||||||
|
Operand2 EqualTo(0x2, 0xA); // 0x2000
|
||||||
|
Operand2 NANRes(0x1, 0xA); // 0x1000
|
||||||
|
FixupBranch Done1, Done2, Done3;
|
||||||
|
LDR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
|
||||||
|
BIC(fpscrReg, fpscrReg, FPRFMask);
|
||||||
|
|
||||||
|
VCMPE(vA, vB);
|
||||||
|
VMRS(_PC);
|
||||||
|
SetCC(CC_LT);
|
||||||
|
ORR(fpscrReg, fpscrReg, LessThan);
|
||||||
|
MOV(crReg, 8);
|
||||||
|
Done1 = B();
|
||||||
|
SetCC(CC_GT);
|
||||||
|
ORR(fpscrReg, fpscrReg, GreaterThan);
|
||||||
|
MOV(crReg, 4);
|
||||||
|
Done2 = B();
|
||||||
|
SetCC(CC_EQ);
|
||||||
|
ORR(fpscrReg, fpscrReg, EqualTo);
|
||||||
|
MOV(crReg, 2);
|
||||||
|
Done3 = B();
|
||||||
|
SetCC();
|
||||||
|
|
||||||
|
ORR(fpscrReg, fpscrReg, NANRes);
|
||||||
|
MOV(crReg, 1);
|
||||||
|
|
||||||
|
VCMPE(vA, vA);
|
||||||
|
VMRS(_PC);
|
||||||
|
FixupBranch NanA = B_CC(CC_NEQ);
|
||||||
|
VCMPE(vB, vB);
|
||||||
|
VMRS(_PC);
|
||||||
|
FixupBranch NanB = B_CC(CC_NEQ);
|
||||||
|
|
||||||
|
SetFPException(fpscrReg, FPSCR_VXVC);
|
||||||
|
FixupBranch Done4 = B();
|
||||||
|
|
||||||
|
SetJumpTarget(NanA);
|
||||||
|
SetJumpTarget(NanB);
|
||||||
|
|
||||||
|
SetFPException(fpscrReg, FPSCR_VXSNAN);
|
||||||
|
|
||||||
|
TST(fpscrReg, VEMask);
|
||||||
|
|
||||||
|
FixupBranch noVXVC = B_CC(CC_NEQ);
|
||||||
|
SetFPException(fpscrReg, FPSCR_VXVC);
|
||||||
|
|
||||||
|
SetJumpTarget(noVXVC);
|
||||||
|
SetJumpTarget(Done1);
|
||||||
|
SetJumpTarget(Done2);
|
||||||
|
SetJumpTarget(Done3);
|
||||||
|
SetJumpTarget(Done4);
|
||||||
|
STRB(crReg, R9, PPCSTATE_OFF(cr_fast) + cr);
|
||||||
|
STR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
|
||||||
|
gpr.Unlock(fpscrReg, crReg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JitArm::fcmpu(UGeckoInstruction inst)
|
||||||
|
{
|
||||||
|
INSTRUCTION_START
|
||||||
|
JITDISABLE(bJITFloatingPointOff)
|
||||||
|
u32 a = inst.FA, b = inst.FB;
|
||||||
|
int cr = inst.CRFD;
|
||||||
|
|
||||||
|
ARMReg vA = fpr.R0(a);
|
||||||
|
ARMReg vB = fpr.R0(b);
|
||||||
|
ARMReg fpscrReg = gpr.GetReg();
|
||||||
|
ARMReg crReg = gpr.GetReg();
|
||||||
|
Operand2 FPRFMask(0x1F, 0xA); // 0x1F000
|
||||||
|
Operand2 LessThan(0x8, 0xA); // 0x8000
|
||||||
|
Operand2 GreaterThan(0x4, 0xA); // 0x4000
|
||||||
|
Operand2 EqualTo(0x2, 0xA); // 0x2000
|
||||||
|
Operand2 NANRes(0x1, 0xA); // 0x1000
|
||||||
|
FixupBranch Done1, Done2, Done3;
|
||||||
|
LDR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
|
||||||
|
BIC(fpscrReg, fpscrReg, FPRFMask);
|
||||||
|
|
||||||
|
VCMPE(vA, vB);
|
||||||
|
VMRS(_PC);
|
||||||
|
SetCC(CC_LT);
|
||||||
|
ORR(fpscrReg, fpscrReg, LessThan);
|
||||||
|
MOV(crReg, 8);
|
||||||
|
Done1 = B();
|
||||||
|
SetCC(CC_GT);
|
||||||
|
ORR(fpscrReg, fpscrReg, GreaterThan);
|
||||||
|
MOV(crReg, 4);
|
||||||
|
Done2 = B();
|
||||||
|
SetCC(CC_EQ);
|
||||||
|
ORR(fpscrReg, fpscrReg, EqualTo);
|
||||||
|
MOV(crReg, 2);
|
||||||
|
Done3 = B();
|
||||||
|
SetCC();
|
||||||
|
|
||||||
|
ORR(fpscrReg, fpscrReg, NANRes);
|
||||||
|
MOV(crReg, 1);
|
||||||
|
|
||||||
|
VCMPE(vA, vA);
|
||||||
|
VMRS(_PC);
|
||||||
|
FixupBranch NanA = B_CC(CC_NEQ);
|
||||||
|
VCMPE(vB, vB);
|
||||||
|
VMRS(_PC);
|
||||||
|
FixupBranch NanB = B_CC(CC_NEQ);
|
||||||
|
FixupBranch Done4 = B();
|
||||||
|
|
||||||
|
SetJumpTarget(NanA);
|
||||||
|
SetJumpTarget(NanB);
|
||||||
|
|
||||||
|
SetFPException(fpscrReg, FPSCR_VXSNAN);
|
||||||
|
|
||||||
|
SetJumpTarget(Done1);
|
||||||
|
SetJumpTarget(Done2);
|
||||||
|
SetJumpTarget(Done3);
|
||||||
|
SetJumpTarget(Done4);
|
||||||
|
STRB(crReg, R9, PPCSTATE_OFF(cr_fast) + cr);
|
||||||
|
STR(fpscrReg, R9, PPCSTATE_OFF(fpscr));
|
||||||
|
gpr.Unlock(fpscrReg, crReg);
|
||||||
|
}
|
||||||
|
|
||||||
void JitArm::fabsx(UGeckoInstruction inst)
|
void JitArm::fabsx(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
|
@ -347,8 +347,8 @@ static GekkoOPTemplate table59[] =
|
|||||||
static GekkoOPTemplate table63[] =
|
static GekkoOPTemplate table63[] =
|
||||||
{
|
{
|
||||||
{264, &JitArm::fabsx}, //"fabsx", OPTYPE_FPU, FL_RC_BIT_F}},
|
{264, &JitArm::fabsx}, //"fabsx", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
{32, &JitArm::Default}, //"fcmpo", OPTYPE_FPU, FL_RC_BIT_F}},
|
{32, &JitArm::fcmpo}, //"fcmpo", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
{0, &JitArm::Default}, //"fcmpu", OPTYPE_FPU, FL_RC_BIT_F}},
|
{0, &JitArm::fcmpu}, //"fcmpu", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
{14, &JitArm::Default}, //"fctiwx", OPTYPE_FPU, FL_RC_BIT_F}},
|
{14, &JitArm::Default}, //"fctiwx", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
{15, &JitArm::fctiwzx}, //"fctiwzx", OPTYPE_FPU, FL_RC_BIT_F}},
|
{15, &JitArm::fctiwzx}, //"fctiwzx", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
{72, &JitArm::fmrx}, //"fmrx", OPTYPE_FPU, FL_RC_BIT_F}},
|
{72, &JitArm::fmrx}, //"fmrx", OPTYPE_FPU, FL_RC_BIT_F}},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user