ARM64: Don't update currentRoundingFunc unless necessary.

This commit is contained in:
Henrik Rydgard 2015-10-10 14:32:34 +02:00
parent 70239f1611
commit 65ee3723d3
2 changed files with 16 additions and 12 deletions

View file

@ -151,24 +151,14 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) {
SUBI2R(SCRATCH2, SCRATCH2, 1);
SetJumpTarget(skipsub);
// Actually change the system FPCR register
MRS(SCRATCH1_64, FIELD_FPCR);
// Clear both flush-to-zero and rounding before re-setting them.
ANDI2R(SCRATCH1, SCRATCH1, ~((4 | 3) << 22));
ORR(SCRATCH1, SCRATCH1, SCRATCH2, ArithOption(SCRATCH2, ST_LSL, 22));
_MSR(FIELD_FPCR, SCRATCH1_64);
SetJumpTarget(skip);
// !! Can't skip this part at all, unless we restore it in restoreRoundingMode (which would not really be cheaper)
// Let's update js.currentRoundingFunc with the right convertS0ToSCRATCH1 func.
MOVP2R(SCRATCH1_64, convertS0ToSCRATCH1);
// We already index this array including the FZ bit. Easy.
LSL(SCRATCH2, SCRATCH2, 3);
LDR(SCRATCH2_64, SCRATCH1_64, SCRATCH2);
MOVP2R(SCRATCH1_64, &js.currentRoundingFunc);
STR(INDEX_UNSIGNED, SCRATCH2_64, SCRATCH1_64, 0);
RET();
}
@ -181,6 +171,7 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) {
ADDI2R(SCRATCH2, SCRATCH2, 4);
SetJumpTarget(skip);
PUSH(SCRATCH2);
// We can only skip if the rounding mode is zero and flush is not set.
// TODO: This actually seems to compare against 3??
CMPI2R(SCRATCH2, 0);
@ -189,6 +180,14 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) {
MOVP2R(SCRATCH1_64, &js.hasSetRounding);
STRB(INDEX_UNSIGNED, SCRATCH2, SCRATCH1_64, 0);
SetJumpTarget(skip2);
POP(SCRATCH2);
// Let's update js.currentRoundingFunc with the right convertS0ToSCRATCH1 func.
MOVP2R(SCRATCH1_64, convertS0ToSCRATCH1);
LSL(SCRATCH2, SCRATCH2, 3);
LDR(SCRATCH2_64, SCRATCH1_64, SCRATCH2);
MOVP2R(SCRATCH1_64, &js.currentRoundingFunc);
STR(INDEX_UNSIGNED, SCRATCH2_64, SCRATCH1_64, 0);
RET();
}
@ -292,7 +291,8 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) {
RET();
// Generate some integer conversion funcs.
static const RoundingMode roundModes[8] = {ROUND_N, ROUND_P, ROUND_M, ROUND_Z, ROUND_N, ROUND_P, ROUND_M, ROUND_Z,};
// MIPS order!
static const RoundingMode roundModes[8] = { ROUND_N, ROUND_Z, ROUND_P, ROUND_M, ROUND_N, ROUND_Z, ROUND_P, ROUND_M };
for (size_t i = 0; i < ARRAY_SIZE(roundModes); ++i) {
convertS0ToSCRATCH1[i] = AlignCode16();

View file

@ -89,6 +89,10 @@ void Arm64Jit::DoState(PointerWrap &p) {
} else {
js.hasSetRounding = 1;
}
if (p.GetMode() == PointerWrap::MODE_READ) {
js.currentRoundingFunc = convertS0ToSCRATCH1[(mips_->fcr31) & 3];
}
}
// This is here so the savestate matches between jit and non-jit.