mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Get rid of the ForceFlushToZero hidden config option
This commit is contained in:
parent
42ce836ba5
commit
6dd86cd843
5 changed files with 63 additions and 108 deletions
|
@ -326,14 +326,6 @@ static ConfigSetting generalSettings[] = {
|
|||
ConfigSetting(false),
|
||||
};
|
||||
|
||||
static bool DefaultForceFlushToZero() {
|
||||
#ifdef ARM
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static ConfigSetting cpuSettings[] = {
|
||||
ReportedConfigSetting("Jit", &g_Config.bJit, &DefaultJit, true, true),
|
||||
ReportedConfigSetting("SeparateCPUThread", &g_Config.bSeparateCPUThread, false, true, true),
|
||||
|
@ -343,7 +335,6 @@ static ConfigSetting cpuSettings[] = {
|
|||
ReportedConfigSetting("FuncReplacements", &g_Config.bFuncReplacements, true, true, true),
|
||||
ReportedConfigSetting("CPUSpeed", &g_Config.iLockedCPUSpeed, 0, true, true),
|
||||
ReportedConfigSetting("SetRoundingMode", &g_Config.bSetRoundingMode, true, true, true),
|
||||
ReportedConfigSetting("ForceFlushToZero", &g_Config.bForceFlushToZero, &DefaultForceFlushToZero, true, true),
|
||||
|
||||
ConfigSetting(false),
|
||||
};
|
||||
|
|
|
@ -117,7 +117,6 @@ public:
|
|||
bool bForceLagSync;
|
||||
bool bFuncReplacements;
|
||||
bool bSetRoundingMode;
|
||||
bool bForceFlushToZero;
|
||||
|
||||
// Definitely cannot be changed while game is running.
|
||||
bool bSeparateCPUThread;
|
||||
|
|
|
@ -587,14 +587,10 @@ void ArmJit::WriteDownCountR(ARMReg reg) {
|
|||
|
||||
void ArmJit::RestoreRoundingMode(bool force) {
|
||||
// If the game has never set an interesting rounding mode, we can safely skip this.
|
||||
if (g_Config.bSetRoundingMode && (force || !g_Config.bForceFlushToZero || js.hasSetRounding)) {
|
||||
if (g_Config.bSetRoundingMode && (force || js.hasSetRounding)) {
|
||||
VMRS(SCRATCHREG2);
|
||||
// Assume we're always in round-to-nearest mode beforehand.
|
||||
// Also on ARM, we're always in flush-to-zero in C++, so stay that way.
|
||||
if (!g_Config.bForceFlushToZero) {
|
||||
ORR(SCRATCHREG2, SCRATCHREG2, AssumeMakeOperand2(4 << 22));
|
||||
}
|
||||
BIC(SCRATCHREG2, SCRATCHREG2, AssumeMakeOperand2(3 << 22));
|
||||
// Assume we're always in round-to-nearest mode beforehand. Flush-to-zero is off.
|
||||
BIC(SCRATCHREG2, SCRATCHREG2, AssumeMakeOperand2((3 | 4) << 22));
|
||||
VMSR(SCRATCHREG2);
|
||||
}
|
||||
}
|
||||
|
@ -602,19 +598,17 @@ void ArmJit::RestoreRoundingMode(bool force) {
|
|||
void ArmJit::ApplyRoundingMode(bool force) {
|
||||
// NOTE: Must not destroy R0.
|
||||
// If the game has never set an interesting rounding mode, we can safely skip this.
|
||||
if (g_Config.bSetRoundingMode && (force || !g_Config.bForceFlushToZero || js.hasSetRounding)) {
|
||||
if (g_Config.bSetRoundingMode && (force || js.hasSetRounding)) {
|
||||
LDR(SCRATCHREG2, CTXREG, offsetof(MIPSState, fcr31));
|
||||
if (!g_Config.bForceFlushToZero) {
|
||||
TST(SCRATCHREG2, AssumeMakeOperand2(1 << 24));
|
||||
AND(SCRATCHREG2, SCRATCHREG2, Operand2(3));
|
||||
SetCC(CC_NEQ);
|
||||
ADD(SCRATCHREG2, SCRATCHREG2, Operand2(4));
|
||||
SetCC(CC_AL);
|
||||
// We can only skip if the rounding mode is zero and flush is set.
|
||||
CMP(SCRATCHREG2, Operand2(4));
|
||||
} else {
|
||||
ANDS(SCRATCHREG2, SCRATCHREG2, Operand2(3));
|
||||
}
|
||||
|
||||
TST(SCRATCHREG2, AssumeMakeOperand2(1 << 24));
|
||||
AND(SCRATCHREG2, SCRATCHREG2, Operand2(3));
|
||||
SetCC(CC_NEQ);
|
||||
ADD(SCRATCHREG2, SCRATCHREG2, Operand2(4));
|
||||
SetCC(CC_AL);
|
||||
// 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.
|
||||
FixupBranch skip = B_CC(CC_EQ);
|
||||
PUSH(1, SCRATCHREG1);
|
||||
|
@ -624,12 +618,8 @@ void ArmJit::ApplyRoundingMode(bool force) {
|
|||
// 1: Round to zero 3
|
||||
// 2: Round up (ceil) 1
|
||||
// 3: Round down (floor) 2
|
||||
if (!g_Config.bForceFlushToZero) {
|
||||
AND(SCRATCHREG1, SCRATCHREG2, Operand2(3));
|
||||
CMP(SCRATCHREG1, Operand2(1));
|
||||
} else {
|
||||
CMP(SCRATCHREG2, Operand2(1));
|
||||
}
|
||||
AND(SCRATCHREG1, SCRATCHREG2, Operand2(3));
|
||||
CMP(SCRATCHREG1, Operand2(1));
|
||||
|
||||
SetCC(CC_EQ); ADD(SCRATCHREG2, SCRATCHREG2, Operand2(2));
|
||||
SetCC(CC_GT); SUB(SCRATCHREG2, SCRATCHREG2, Operand2(1));
|
||||
|
@ -637,10 +627,8 @@ void ArmJit::ApplyRoundingMode(bool force) {
|
|||
|
||||
VMRS(SCRATCHREG1);
|
||||
// Assume we're always in round-to-nearest mode beforehand.
|
||||
if (!g_Config.bForceFlushToZero) {
|
||||
// But we need to clear flush to zero in this case anyway.
|
||||
BIC(SCRATCHREG1, SCRATCHREG1, AssumeMakeOperand2(7 << 22));
|
||||
}
|
||||
// But we need to clear flush to zero in this case anyway.
|
||||
BIC(SCRATCHREG1, SCRATCHREG1, AssumeMakeOperand2((3 | 4) << 22));
|
||||
ORR(SCRATCHREG1, SCRATCHREG1, Operand2(SCRATCHREG2, ST_LSL, 22));
|
||||
VMSR(SCRATCHREG1);
|
||||
|
||||
|
@ -650,20 +638,17 @@ void ArmJit::ApplyRoundingMode(bool force) {
|
|||
}
|
||||
|
||||
void ArmJit::UpdateRoundingMode() {
|
||||
// NOTE: Must not destory R0.
|
||||
// NOTE: Must not destroy R0.
|
||||
if (g_Config.bSetRoundingMode) {
|
||||
LDR(SCRATCHREG2, CTXREG, offsetof(MIPSState, fcr31));
|
||||
if (!g_Config.bForceFlushToZero) {
|
||||
TST(SCRATCHREG2, AssumeMakeOperand2(1 << 24));
|
||||
AND(SCRATCHREG2, SCRATCHREG2, Operand2(3));
|
||||
SetCC(CC_NEQ);
|
||||
ADD(SCRATCHREG2, SCRATCHREG2, Operand2(4));
|
||||
SetCC(CC_AL);
|
||||
// We can only skip if the rounding mode is zero and flush is set.
|
||||
CMP(SCRATCHREG2, Operand2(4));
|
||||
} else {
|
||||
ANDS(SCRATCHREG2, SCRATCHREG2, Operand2(3));
|
||||
}
|
||||
|
||||
TST(SCRATCHREG2, AssumeMakeOperand2(1 << 24));
|
||||
AND(SCRATCHREG2, SCRATCHREG2, Operand2(3));
|
||||
SetCC(CC_NEQ);
|
||||
ADD(SCRATCHREG2, SCRATCHREG2, Operand2(4));
|
||||
SetCC(CC_AL);
|
||||
// We can only skip if the rounding mode is zero and flush is not set.
|
||||
CMP(SCRATCHREG2, Operand2(3));
|
||||
|
||||
FixupBranch skip = B_CC(CC_EQ);
|
||||
PUSH(1, SCRATCHREG1);
|
||||
|
|
|
@ -526,14 +526,13 @@ void Arm64Jit::WriteDownCountR(ARM64Reg reg, bool updateFlags) {
|
|||
|
||||
void Arm64Jit::RestoreRoundingMode(bool force) {
|
||||
// If the game has never set an interesting rounding mode, we can safely skip this.
|
||||
if (g_Config.bSetRoundingMode && (force || !g_Config.bForceFlushToZero || js.hasSetRounding)) {
|
||||
if (g_Config.bSetRoundingMode && (force || js.hasSetRounding)) {
|
||||
MRS(SCRATCH2_64, FIELD_FPCR);
|
||||
// We are not in flush-to-zero mode outside the JIT, so let's turn it off.
|
||||
uint32_t mask = ~(4 << 22);
|
||||
// Assume we're always in round-to-nearest mode beforehand.
|
||||
// Also on ARM, we're always in flush-to-zero in C++, so stay that way.
|
||||
if (!g_Config.bForceFlushToZero) {
|
||||
ORRI2R(SCRATCH2, SCRATCH2, 4 << 22);
|
||||
}
|
||||
ANDI2R(SCRATCH2, SCRATCH2, ~(3 << 22));
|
||||
mask &= ~(3 << 22);
|
||||
ANDI2R(SCRATCH2, SCRATCH2, mask);
|
||||
_MSR(FIELD_FPCR, SCRATCH2_64);
|
||||
}
|
||||
}
|
||||
|
@ -541,19 +540,15 @@ void Arm64Jit::RestoreRoundingMode(bool force) {
|
|||
void Arm64Jit::ApplyRoundingMode(bool force) {
|
||||
// NOTE: Must not destroy SCRATCH1.
|
||||
// If the game has never set an interesting rounding mode, we can safely skip this.
|
||||
if (g_Config.bSetRoundingMode && (force || !g_Config.bForceFlushToZero || js.hasSetRounding)) {
|
||||
if (g_Config.bSetRoundingMode && (force || js.hasSetRounding)) {
|
||||
LDR(INDEX_UNSIGNED, SCRATCH2, CTXREG, offsetof(MIPSState, fcr31));
|
||||
if (!g_Config.bForceFlushToZero) {
|
||||
TSTI2R(SCRATCH2, 1 << 24);
|
||||
ANDI2R(SCRATCH2, SCRATCH2, 3);
|
||||
FixupBranch skip1 = B(CC_EQ);
|
||||
ADDI2R(SCRATCH2, SCRATCH2, 4);
|
||||
SetJumpTarget(skip1);
|
||||
// We can only skip if the rounding mode is zero and flush is set.
|
||||
CMPI2R(SCRATCH2, 4);
|
||||
} else {
|
||||
ANDSI2R(SCRATCH2, SCRATCH2, 3);
|
||||
}
|
||||
TSTI2R(SCRATCH2, 1 << 24);
|
||||
ANDI2R(SCRATCH2, SCRATCH2, 3);
|
||||
FixupBranch skip1 = B(CC_EQ);
|
||||
ADDI2R(SCRATCH2, SCRATCH2, 4);
|
||||
SetJumpTarget(skip1);
|
||||
// We can only skip if the rounding mode is zero and flush is set.
|
||||
CMPI2R(SCRATCH2, 4);
|
||||
// At this point, if it was zero, we can skip the rest.
|
||||
FixupBranch skip = B(CC_EQ);
|
||||
PUSH(SCRATCH1);
|
||||
|
@ -563,12 +558,8 @@ void Arm64Jit::ApplyRoundingMode(bool force) {
|
|||
// 1: Round to zero 3
|
||||
// 2: Round up (ceil) 1
|
||||
// 3: Round down (floor) 2
|
||||
if (!g_Config.bForceFlushToZero) {
|
||||
ANDI2R(SCRATCH1, SCRATCH2, 3);
|
||||
CMPI2R(SCRATCH1, 1);
|
||||
} else {
|
||||
CMPI2R(SCRATCH2, 1);
|
||||
}
|
||||
ANDI2R(SCRATCH1, SCRATCH2, 3);
|
||||
CMPI2R(SCRATCH1, 1);
|
||||
|
||||
FixupBranch skipadd = B(CC_NEQ);
|
||||
ADDI2R(SCRATCH2, SCRATCH2, 2);
|
||||
|
@ -578,11 +569,10 @@ void Arm64Jit::ApplyRoundingMode(bool force) {
|
|||
SetJumpTarget(skipsub);
|
||||
|
||||
MRS(SCRATCH1_64, FIELD_FPCR);
|
||||
// Assume we're always in round-to-nearest mode beforehand.
|
||||
if (!g_Config.bForceFlushToZero) {
|
||||
// But we need to clear flush to zero in this case anyway.
|
||||
ANDI2R(SCRATCH1, SCRATCH1, ~(7 << 22));
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
|
@ -603,25 +593,23 @@ void Arm64Jit::UpdateRoundingMode() {
|
|||
// NOTE: Must not destroy SCRATCH1.
|
||||
if (g_Config.bSetRoundingMode) {
|
||||
LDR(INDEX_UNSIGNED, SCRATCH2, CTXREG, offsetof(MIPSState, fcr31));
|
||||
if (!g_Config.bForceFlushToZero) {
|
||||
TSTI2R(SCRATCH2, 1 << 24);
|
||||
ANDI2R(SCRATCH2, SCRATCH2, 3);
|
||||
FixupBranch skip = B(CC_EQ);
|
||||
ADDI2R(SCRATCH2, SCRATCH2, 4);
|
||||
SetJumpTarget(skip);
|
||||
// We can only skip if the rounding mode is zero and flush is set.
|
||||
CMPI2R(SCRATCH2, 4);
|
||||
} else {
|
||||
ANDSI2R(SCRATCH2, SCRATCH2, 3);
|
||||
}
|
||||
|
||||
TSTI2R(SCRATCH2, 1 << 24);
|
||||
ANDI2R(SCRATCH2, SCRATCH2, 3);
|
||||
FixupBranch skip = B(CC_EQ);
|
||||
ADDI2R(SCRATCH2, SCRATCH2, 4);
|
||||
SetJumpTarget(skip);
|
||||
|
||||
// We can only skip if the rounding mode is zero and flush is not set.
|
||||
CMPI2R(SCRATCH2, 3);
|
||||
|
||||
FixupBranch skip2 = B(CC_EQ);
|
||||
PUSH(SCRATCH1_64);
|
||||
MOVI2R(SCRATCH2, 1);
|
||||
MOVP2R(SCRATCH1_64, &js.hasSetRounding);
|
||||
STRB(INDEX_UNSIGNED, SCRATCH2, SCRATCH1_64, 0);
|
||||
POP(SCRATCH1_64);
|
||||
SetJumpTarget(skip);
|
||||
SetJumpTarget(skip2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@ void Jit::WriteDowncount(int offset)
|
|||
void Jit::RestoreRoundingMode(bool force, XEmitter *emitter)
|
||||
{
|
||||
// If the game has never set an interesting rounding mode, we can safely skip this.
|
||||
if (g_Config.bSetRoundingMode && (force || g_Config.bForceFlushToZero || js.hasSetRounding))
|
||||
if (g_Config.bSetRoundingMode && (force || js.hasSetRounding))
|
||||
{
|
||||
if (emitter == NULL)
|
||||
emitter = this;
|
||||
|
@ -237,7 +237,7 @@ void Jit::RestoreRoundingMode(bool force, XEmitter *emitter)
|
|||
void Jit::ApplyRoundingMode(bool force, XEmitter *emitter)
|
||||
{
|
||||
// If the game has never set an interesting rounding mode, we can safely skip this.
|
||||
if (g_Config.bSetRoundingMode && (force || g_Config.bForceFlushToZero || js.hasSetRounding))
|
||||
if (g_Config.bSetRoundingMode && (force || js.hasSetRounding))
|
||||
{
|
||||
if (emitter == NULL)
|
||||
emitter = this;
|
||||
|
@ -247,9 +247,7 @@ void Jit::ApplyRoundingMode(bool force, XEmitter *emitter)
|
|||
// If it's 0, we don't actually bother setting. This is the most common.
|
||||
// We always use nearest as the default rounding mode with
|
||||
// flush-to-zero disabled.
|
||||
FixupBranch skip;
|
||||
if (!g_Config.bForceFlushToZero)
|
||||
skip = emitter->J_CC(CC_Z);
|
||||
FixupBranch skip = emitter->J_CC(CC_Z);
|
||||
|
||||
emitter->STMXCSR(M(&mips_->temp));
|
||||
|
||||
|
@ -263,19 +261,13 @@ void Jit::ApplyRoundingMode(bool force, XEmitter *emitter)
|
|||
emitter->SHL(32, R(EAX), Imm8(13));
|
||||
emitter->OR(32, M(&mips_->temp), R(EAX));
|
||||
|
||||
if (g_Config.bForceFlushToZero) {
|
||||
emitter->OR(32, M(&mips_->temp), Imm32(1 << 15));
|
||||
} else {
|
||||
emitter->TEST(32, M(&mips_->fcr31), Imm32(1 << 24));
|
||||
FixupBranch skip3 = emitter->J_CC(CC_Z);
|
||||
emitter->OR(32, M(&mips_->temp), Imm32(1 << 15));
|
||||
emitter->SetJumpTarget(skip3);
|
||||
}
|
||||
emitter->TEST(32, M(&mips_->fcr31), Imm32(1 << 24));
|
||||
FixupBranch skip3 = emitter->J_CC(CC_Z);
|
||||
emitter->OR(32, M(&mips_->temp), Imm32(1 << 15));
|
||||
emitter->SetJumpTarget(skip3);
|
||||
|
||||
emitter->LDMXCSR(M(&mips_->temp));
|
||||
|
||||
if (!g_Config.bForceFlushToZero)
|
||||
emitter->SetJumpTarget(skip);
|
||||
emitter->SetJumpTarget(skip);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue