The extension needs to happen in SetLongAcc, not GetLongAcc, as the extension needs to always be reflected in acS.h.
There is no functional difference with the write handler for acS.h, but it is more readable than 4 casts in a row.
`IsLess` would incorrectly return true if both `SR_OVERFLOW` and `SR_SIGN` are set, as `(sr & SR_OVERFLOW) != (sr & SR_SIGN)` becomes `SR_OVERFLOW != SR_SIGN` which is true as the two masks are different. This broke in e651592ef5.
This issue only affected the DSP LLE Interpreter, and not the DSP LLE JIT.
I've also included a simple test case for this. `ax0.l` (on the top left) is set to 0 if the instruction following `IFL` does not execute and to 1 if it is executed.
For several reasons:
- It pegs the CPU at 95% for scanning even when Dolphin is idle
- WiimoteScannerHidapi works fine on macOS
- Less macOS code to maintain
When making 92d1d60, I checked whether the ~0x1f masking in dcbx
actually was necessary. I came to the conclusion that it wasn't,
so I removed it. However, I hadn't checked the second half of
InvalidateICache closely enough - the masking is actually needed.
This commit re-adds the masking, but this time in C++ code instead
of in jitted code in order to save icache. Though I suppose the
difference doesn't matter all that much, since this is in farcode
and all...
Hopefully fixes https://bugs.dolphin-emu.org/issues/12612.
This implements the behavior described in
https://bugs.dolphin-emu.org/issues/12565.
Thank you to eigenform, delroth, phire, marcan, segher, and Extrems
for all helping in one way or another with the efforts to reverse
engineer this behavior, and to Rylie for reporting the issue.
Write_U16_Swap leaves the upper 32 bits alone. Reimplementing this
correctly in the JIT would require more than one instruction,
so let's just call Write_U16_Swap instead, like Jit64 does.
One of the following commits will add emulation of a quirk
that only happens when writing to memory which is mapped as
write-through or cache-inhibited, so let's keep track of
which memory is mapped in this way.
This adds about a frame of latency, and since most games don't change
VI registers during scanout, we can get away with outputting the XFB at
the start of scanout. WWE Crush Hour is the (only currently known)
exception, which has flickering problems when doing it this way.
This adds a path to perform the output at the end of scanout, and gates
it behind an option which defaults to using the latency-reducing
pre-scanout path.
Originally, 1479 (for example) would disassemble as `lsr $ACC0, #-7`. At some point (likely the conversion to fmt), this regressed to `lsr $ACC0, #4294967289`. Now, it disassembles as `lsr $ACC0, #7`.
The CPU-side AX library enables it by default and uses hardcoded parameters.
CMD_COMPRESSOR_TABLE_ADDR (0x0A) was incorrect. It's always a nop on the
GameCube and was probably confused with the Wii version.
It was believed that this only mattered when the rounding mode was
set to round to infinity, which games generally don't do, but it
can also affect the sign of the output when the inputs are all zero.
So it turns out you have to pass XMM0 as the clobber register
to HandleNaNs, because HandleNaNs uses BLENDVPD and BLENDVPD
implicitly uses XMM0, and nobody noticed when I broke this in
2c38d64 because nobody plays the one game that needs accurate NaNs.
This reverts commit 66b992cfe4.
A new (additional) correctness issue was revealed in the old
AArch64 code when applying it on top of modern JitArm64:
LSR was being used when LSRV was intended. This commit uses LSRV.
This actually eliminates any setting pertaining to SD cards from the
NetPlay dialog, as it would effectively just be a duplicate of the
setting in the Wii pane, potentially causing confusion.
This also enables save data writing by default, as this is probably
what most players want, and should avoid them losing hours of progress
because they forgot to tick a checkbox.
This implementation is pretty efficient in my opinion. And "As
long as we aren't falling back to interpreter we're winning a lot"
applies to basically every instruction to some degree anyway.
The dcbz instruction needs to lock W30 so that the slowmem code will
push and pop it when calling into C++. Also, the slowmem code expects
that the address is present in W0, so replace the use of W0 as a scratch
register in the fastmem code with the now locked W30.
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.
A voice is considered running if and only if `running` equals 1,
not if `running` is not equal to 0.
This fixes https://bugs.dolphin-emu.org/issues/12508 because for some
reason *The Sims 2 - Castaway* sets `running` to 8 when a stream
finishes playing; previously our AX HLE would just loop the voice
and eventually crash after accessing invalid memory addresses.
Thanks to JMC47 and delroth's help, I've verified that this is the
correct check for the following ucodes:
GC:
* 0x3ad3b7ac
* 0x3daf59b9
* 0x4e8a8b21
* 0x07f88145
* 0xe2136399
* 0x3389a79e
Wii:
* 0x347112ba
* 0xfa450138
* 0xadbc06bd
And while I was fixing the running check, I noticed that the is_stream
field was also being handled incorrectly, so I've fixed that as well.
Putting AX functions from AXVoice.h in an anonymous namespace does
successfully prevent compilers from merging those functions and
allows us to avoid ODR violations.
However, tools such as gdb still mix up AX GC and AX Wii functions
and variables because those have the exact same symbol names.
This can be fixed by using inline namespaces which are transparent
at the source code level but forces AX GC and AX Wii symbols to be
different.
The fast path of using CVTSD2SS/FCVTN rounds the significand if it
can't be exactly represented as a single, whereas the accurate path
instead truncates the significand. So we should only use the fast
path if we know that the lower bits of the significand are not set.
This is not known to affect any games.
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.
SPDX standardizes how source code conveys its copyright and licensing
information. See https://spdx.github.io/spdx-spec/1-rationale/ . SPDX
tags are adopted in many large projects, including things like the Linux
kernel.
This broke ejecting Wii discs while the game is running, as the drive state was set to Ready even when no disc was present, but other code still reported the missing disc, which confused games as you can't be both ready to read and have no disc. That would cause games to show an unrecoverable error screen, instead of a "please insert the game disc" screen.
This only affected Wii games; the GameCube games used regular disc reads which worked fine.
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.
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.
These optimizations were already present, but only when d == a. They
also make sense when this condition does not hold.
- imm == 0
Before:
41 BB 00 00 00 00 mov r11d,0
45 2B DF sub r11d,r15d
After:
45 8B DF mov r11d,r15d
41 F7 DB neg r11d
- imm == -1
Before:
41 BD FF FF FF FF mov r13d,0FFFFFFFFh
44 2B EE sub r13d,esi
0F 93 45 68 setae byte ptr [rbp+68h]
After:
44 8B EE mov r13d,esi
41 F7 D5 not r13d
C6 45 68 01 mov byte ptr [rbp+68h],1
Fixes a regression from 5.0-12066, where setting the GFXBackend variable
to one other than the current global backend would crash Dolphin upon
launching the game.
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
The SDK seems to write "default" bounding box values before every draw
(1023 0 1023 0 are the only values encountered so far, which happen to
be the extents allowed by the BP registers) to reset the registers for
comparison in the pixel engine, and presumably to detect whether GX has
updated the registers with real values. Handling these writes and
returning them on read when bounding box emulation is disabled or
unsupported, even without computing real values from rendering, seems
to prevent games from corrupting memory or crashing.
This obviously does not fix any effects that rely on bounding box
emulation, but having the game not clobber its own code/data or just
outright crash is a definite improvement.
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.
Added RAII wrapper around the the JITPageWriteEnableExecuteDisable() and
JITPageWriteDisableExecuteEnable() to make it so that it is harder to forget to
pair the calls in all code branches as suggested by leoetlino.
Removed the unavailable CPU core dialog box that asked users to change their
selected CPU core to one that is available. Instead, Dolphin now just overrides
the core to the default, and logs that it performed the override.
Analytics:
- Incorporated fix to allow the full set of analytics that was recommended by
spotlightishere
BuildMacOSUniversalBinary:
- The x86_64 slice for a universal binary is now built for 10.12
- The universal binary build script now can be configured though command line
options instead of modifying the script itself.
- os.system calls were replaced with equivalent subprocess calls
- Formatting was reworked to be more PEP 8 compliant
- The script was refactored to make it more modular
- The com.apple.security.cs.disable-library-validation entitlement was removed
Memory Management:
- Changed the JITPageWrite*Execute*() functions to incorporate support for
nesting
Other:
- Fixed several small lint errors
- Fixed doc and formatting mistakes
- Several small refactors to make things clearer
This commit adds support for compiling Dolphin for ARM on MacOS so that it can
run natively on the M1 processors without running through Rosseta2 emulation
providing a 30-50% performance speedup and less hitches from Rosseta2.
It consists of several key changes:
- Adding support for W^X allocation(MAP_JIT) for the ARM JIT
- Adding the machine context and config info to identify the M1 processor
- Additions to the build system and docs to support building universal binaries
- Adding code signing entitlements to access the MAP_JIT functionality
- Updating the MoltenVK libvulkan.dylib to a newer version with M1 support