We currently have a bug when calling Arm64GPRCache::Flush with
FlushMode::MaintainState, zero free host registers, and at least
one guest register containing an immediate. We end up grabbing
a temporary register from the register cache in order to be
able to write the immediate to memory, but grabbing a temporary
register when there are zero free registers causes the least
recently used register to be flushed in a way which does not
maintain the state of the register cache.
To get around this, require callers to pass in a temporary
register in the GPR MaintainState case. In other cases,
passing in a temporary register is not required but can help
avoid spilling a register (if the caller already had a
temporary register at hand anyway, which in particular will
be the case in my upcoming memcheck pull request).
release-ubu-x64 currently fails with "sorry, unimplemented: non-trivial
designated initializers not supported". pr-ubu-x64 doesn't for some
reason, but we might as well remove the designated initializer.
Passing a width of 64 and registers encoded as double to
DUP resulted in an invalid instruction. The registers should
be encoded as quads in this situation.
Fixes https://bugs.dolphin-emu.org/issues/12575.
Manually encoding and decoding logical immediates is error-prone.
Using ORRI2R and friends lets us avoid doing the work manually,
but in exchange, there is a runtime performance penalty. It's
probably rather small, but still, it would be nice if we could
let the compiler do the work at compile-time. And that's exactly
what this commit does, so now I have no excuse for trying to
manually write logical immediates anymore.
If a branch is unconditional, its target should not be in farcode,
since that defeats the purpose of farcode (putting seldom executed
code in farcode to keep it out of the icache when possible).
Fixes a 58698b8380 regression. (The EXCEPTION_EXTERNAL_INT
immediate being wrong meant that we never took the branch,
masking the problem of the MSR.EE immediate being wrong...)
In cases where we already know that there is an exception,
either because we just checked for it or because we were
the ones that generated the exception to begin with,
we can skip the branch inside WriteExceptionExit.
Unlike most constants we emit in JitArm64, these constants are
*not* inherent to the CPU we're emulating, and can have whatever
values we want. Let's handle them more robustly, in case we
decide to change their values in the future.
This partially reverts commit cbc4989095
due to a crash: https://bugs.dolphin-emu.org/issues/12561
I can't debug what the cause of the crash is due to not having an
Android TV device. Let's just revert this for now to fix the crash.
Performance optimization, along with making the code a little
neater. Saves us from performing a single -> double -> single
conversion when calling UpdateFPRFSingle.
If we already have to use a GPR, we might as well take advantage
of the nice immediate encodings provided by GPR ORR. This is
faster, smaller, and saves a register.
The same kind of change as the changes made in the previous
commit, but this change is more involved, in particular because
of how SyncProgramsJobService was using display names as keys.
Now that DOL and ELF files are assigned game IDs, all games have
game IDs. (Unless you intentionally craft an ISO file that has
the first bytes set to null, but if you do that I think you can
live with Dolphin creating a file in GameSettings called ".ini")
Some of the code used when the carry flag is known to be a
constant value is really not much better than just setting
the carry flag and then using the normal code, and with how
rarely this code runs, it isn't well tested either.
Might as well get rid of some of this code and simplify things.
Without this, the code added in ac28b89 misbehaves and considers
AArch64 netplay clients to not have hardware FMA support, telling
all clients to disable FMA support, which causes a desync between
x64 and AArch64 due to JitArm64 not being able to disable FMA support.
fcmpX only updates the FPCC bits, not the C bit.
This was already correctly implemented in the interpreter.
Not known to affect any games, but affects a hardware test.
Not doing this can cause desyncs when TASing. (I don't know
how common such desyncs would be, though. For games that
don't change rounding modes, they shouldn't be a problem.)
When I added the software FMA path in 2c38d64 and made us use
it when determinism is enabled, I was assuming that either the
performance impact of software FMA wouldn't be too large or CPUs
that were too old to have FMA instructions were too slow to run
Dolphin well anyway. This was wrong. To give an example, the
netplay performance went from 60 FPS to 30 FPS in one case.
This change makes netplay clients negotiate whether FMA should
be used. If all clients use an x64 CPU that supports FMA, or
AArch64, then FMA is enabled, and otherwise FMA is disabled.
In other words, we sacrifice accuracy if needed to avoid massive
slowdown, but not otherwise. When not using netplay, whether to
enable FMA is simply based on whether the host CPU supports it.
The only remaining case where the software FMA path gets used
under normal circumstances is when an input recording is created
on a CPU with FMA support and then played back on a CPU without.
This is not an especially common scenario (though it can happen),
and TASers are generally less picky about performance and more
picky about accuracy than other users anyway.
With this change, FMA desyncs are avoided between AArch64 and
modern x64 CPUs (unlike before 2c38d64), but we do get FMA
desyncs between AArch64 and old x64 CPUs (like before 2c38d64).
This desync can be avoided by adding a non-FMA path to JitArm64 as
an option, which I will wait with for another pull request so that
we can get the performance regression fixed as quickly as possible.
https://bugs.dolphin-emu.org/issues/12542
Back when I wrote this code, I believe I set it to use a custom path
so that the cache would end up in a directory which Android considers
to be a cache directory. But nowadays the directory which Dolphin's
C++ code considers to be the cache directory is such a directory,
so there's no longer any reason to override the default path.
progressMessage can have the invalid value of 0. That
progressMessage was being used for the thread name was
a typo anyway – it's supposed to use progressTitle.
This reduces the build time for incremental builds from about
2 minutes to about 20 seconds. Most people never run the
unit tests on Android anyway (I'm not aware of anyone other
than me ever having done it).
When determinism is enabled, we either want all CPUs to use FMA or
we want no CPUs to use FMA. Until now, Jit64 has been been doing
the latter. However, this is inaccurate behavior, all CPUs since
Haswell support FMA, and getting JitArm64 to match the exact
inaccurate rounding used by Jit64 would be a bit annoying. This
commit switches us over to using FMA on all CPUs when determinism
is enabled, with older CPUs calling the std::fma function.
Any local references get cleaned up when returning to the JVM,
but some of the functions in AndroidCommon return to C++ rather
than the JVM, and functions with loops risk running into the
limit of how many simultaneous local references are allowed.
The interpreter implementation of fctiwx was treating rounding
mode 0 as "round to nearest, ties towards zero", which is not
an actual IEEE-754 rounding mode. The IBM document mentioned
in a comment at the top of the function, on the other hand,
treats rounding mode 0 as "round to nearest, ties to even",
which makes more sense.
This fixes one of JMC's console-recorded F-Zero GX replays on
JitArm64. (JitArm64 uses an interpreter fallback for fctiwx.)
Any file which includes scmrev.h must be rebuilt when scmrev.h
is regenerated. By not including scmrev.h from any file other
than Version.cpp, incremental builds become a little faster.
When trying to do a small optimization in 8a0f5ea, I failed to
take into account that WeakFlush and FlushOne update m_query_count.
Only D3D11 and OGL had this problem, not D3D12 and Vulkan.
I was going to rename this to getSysDirectory to make it clearer
what the returned path actually is, but it turns out we're not
actually using this for anything anymore.
The Java implementation of getting the list of post-processing
shaders only looked in the Sys folder and not the User folder.
This could be fixed in the Java implementation, but it's
simpler to just call the C++ implementation instead.
Sorry, the fix I made to the empty string in a29660a was not
actually sufficient, as DolphinQt will call tr on the string
regardless of whether it's marked with _trans. The proper fix
is to use nullptr, which DolphinQt has a special check for.
Sending an empty string to the translation system will not
result in getting an empty string back, but rather a description
of the currently loaded translations file. So empty strings
should not be marked as translatable.
Also adding some i18n comments and rewording a string I thought
was hard to understand.
Settings.SECTION_INI_ANDROID and Settings.SECTION_BINDINGS
both have the value "Android", but we only want the former
to be marked as being handled by the new config system.
This change fixes a problem where controller settings were
not being properly saved to Dolphin.ini.