Fix for 32-bit ARM

This commit is contained in:
Henrik Rydgard 2015-10-08 23:11:57 +02:00
parent 7fee5abf9f
commit b2b5f3424f
3 changed files with 17 additions and 11 deletions

View file

@ -74,15 +74,21 @@ using namespace ArmJitConstants;
void ArmJit::GenerateFixedCode() {
const u8 *start = GetCodePtr();
// LR == SCRATCHREG2.... Maybe we could find some other register to use to avoid having to
// push LR?
restoreRoundingMode = AlignCode16(); {
PUSH(1, R_LR);
VMRS(SCRATCHREG2);
// Assume we're always in round-to-nearest mode beforehand. Flush-to-zero is off.
BIC(SCRATCHREG2, SCRATCHREG2, AssumeMakeOperand2((3 | 4) << 22));
VMSR(SCRATCHREG2);
B(R_LR);
POP(1, R_PC);
}
// Must preserve SCRATCHREG1 (R0)
applyRoundingMode = AlignCode16(); {
PUSH(2, SCRATCHREG1, R_LR);
LDR(SCRATCHREG2, CTXREG, offsetof(MIPSState, fcr31));
TST(SCRATCHREG2, AssumeMakeOperand2(1 << 24));
@ -93,9 +99,8 @@ void ArmJit::GenerateFixedCode() {
// We can only skip if the rounding mode is zero and flush is not set.
CMP(SCRATCHREG2, Operand2(3));
// At this point, if it was zero, we can skip the rest.
// At this point, if it was zero, we can skip the rest. (could even return)
FixupBranch skip = B_CC(CC_EQ);
PUSH(1, SCRATCHREG1);
// MIPS Rounding Mode: ARM Rounding Mode
// 0: Round nearest 0
@ -116,12 +121,13 @@ void ArmJit::GenerateFixedCode() {
ORR(SCRATCHREG1, SCRATCHREG1, Operand2(SCRATCHREG2, ST_LSL, 22));
VMSR(SCRATCHREG1);
POP(1, SCRATCHREG1);
SetJumpTarget(skip);
B(R_LR);
POP(2, SCRATCHREG1, R_PC);
}
// Must preserve SCRATCHREG1 (R0)
updateRoundingMode = AlignCode16(); {
PUSH(2, SCRATCHREG1, R_LR);
LDR(SCRATCHREG2, CTXREG, offsetof(MIPSState, fcr31));
TST(SCRATCHREG2, AssumeMakeOperand2(1 << 24));
@ -133,15 +139,15 @@ void ArmJit::GenerateFixedCode() {
CMP(SCRATCHREG2, Operand2(3));
FixupBranch skip = B_CC(CC_EQ);
PUSH(1, SCRATCHREG1);
MOVI2R(SCRATCHREG2, 1);
MOVP2R(SCRATCHREG1, &js.hasSetRounding);
STRB(SCRATCHREG2, SCRATCHREG1, 0);
POP(1, SCRATCHREG1);
SetJumpTarget(skip);
B(R_LR);
POP(2, SCRATCHREG1, R_PC);
}
FlushLitPool();
enterDispatcher = AlignCode16();
DEBUG_LOG(JIT, "Base: %08x", (u32)Memory::base);

View file

@ -593,7 +593,7 @@ void ArmJit::RestoreRoundingMode(bool force) {
}
}
// Does not destroy R0 (SCRATCHREG1). Destroys R1 (SCRATCHREG2).
// Does not destroy R0 (SCRATCHREG1). Destroys R14 (SCRATCHREG2).
void ArmJit::ApplyRoundingMode(bool force) {
// If the game has never set an interesting rounding mode, we can safely skip this.
if (force || js.hasSetRounding) {
@ -601,7 +601,7 @@ void ArmJit::ApplyRoundingMode(bool force) {
}
}
// Does (must!) not destroy R0 (SCRATCHREG1). Destroys R1 (SCRATCHREG2).
// Does (must!) not destroy R0 (SCRATCHREG1). Destroys R14 (SCRATCHREG2).
void ArmJit::UpdateRoundingMode() {
QuickCallFunction(R1, updateRoundingMode);
}

View file

@ -251,7 +251,7 @@ void Arm64Jit::GenerateFixedCode(const JitOptions &jo) {
LDR(INDEX_UNSIGNED, SCRATCH1, CTXREG, offsetof(MIPSState, pc));
LDR(SCRATCH1, MEMBASEREG, SCRATCH1_64);
LSR(SCRATCH2, SCRATCH1, 24);
LSR(SCRATCH2, SCRATCH1, 24); // or UBFX(SCRATCH2, SCRATCH1, 24, 8)
ANDI2R(SCRATCH1, SCRATCH1, 0x00FFFFFF);
CMP(SCRATCH2, MIPS_EMUHACK_OPCODE >> 24);
FixupBranch skipJump = B(CC_NEQ);