Gets rid of the need to set up memcpy boilerplate to reinterpret between
floating-point and integers.
While we're at it, also do a minor bit of tidying.
Given this is what occurs in both constructors (as one just passes
through to another), we can just initialize the member directly.
While we're at it, amend the struct to follow the general ordering
convention of:
<new types>
<functions>
<variables>
Switching to blank NAND when emulation is running is an extremely bad
idea. It's akin to opening up a Wii and replacing the NAND chip while
you're playing a game on it.
Except we're not even replacing it with a NAND that has the same
contents. The blank NAND has nothing in it except the save file for
the current game, which is likely to result in the emulated software
getting inconsistent results and possibly even crashing depending on
how it caches title information.
An example of games that check the saves for other games is
Mario Kart Wii -- it checks the filesystem for Super Mario Galaxy saves
to decide whether to unlock characters. With this 'switch NAND
while emulation is active' misfeature, this will likely break.
And that's the main problem: it encourages sloppy emulation and no one
really knows how many things it can break.
Just don't let the user do horrible things like that during emulation.
If they want to use a blank NAND, they can do so by starting input
recording before launching a game. It's likely they will want to do
this if they plan to share their DTM anyway.
Another bit of behavior that we weren't performing correctly is the
unsetting of FPSCR.FI and FPSCR.FR when FPSCR.ZX is supposed to be set.
This is supported in PEM's section 3.3.6.1 where the following is
stated:
"
When a zero divide condition occurs, the following actions are taken:
- Zero divide exception condition bit is set FPSCR[ZX] = 1.
- FPSCR[FR, FI] are cleared.
"
And so, this fixes that behavior.
FPSCR[ZX] is the bit defined to represent the zero divide exception
condition bit, and is defined as (according to PowerPC Microprocessor
Family: The Programming Environments Manual for 32 and 64-bit
Microprocessors, which will be referred to as "PEM" for the rest of this
commit message) at section 3.3.6.1:
"
A zero divide exception condition occurs when a divide instructions is
executed with a zero divisor value and a finite, nonzero dividend value
or when a floating reciprocal estimate single (fres) or a floating
reciprocal square root estimate (frsqrte) instruction is executed with a
zero operand value.
"
Note that it states the divisor must be zero and the dividend must be
nonzero in order for ZX to be set. This means that the interpreter was
performing the wrong behavior for the case where 0/0 (with any sign on
the zeros) is performed. We would incorrectly set the ZX bit when only
the VXZDZ bit should be set.
It's also worth pointing out that N/0 (where N is any finite nonzero
value) and 0/0 are not within the same exception class. N/0 is a zero
divide exception case, while 0/0 is considered an invalid operation
exception case, which is also indicated in the PEM section 3.3.6.1 as
well where it lists the criteria for invalid operation exceptions.
Therefore we should only be setting the VXZDZ bit in the 0/0 case, not
VXZDZ and ZX. This was also verified via hardware tests to ensure that
this behavior indeed holds.
Fairly trivial to resolve, we just initialize the std::array with two
sets of braces (one set to create the array, the other to start and end the
aggregate data that we'll end up returning)
Given this is actually a part of the Host interface, this should be
placed with it.
While we're at it, turn it into an enum class so that we don't dump its
contained values into the surrounding scope. We can also make
Host_Message take the enum type itself directly instead of taking a
general int value.
After this, it'll be trivial to divide out the rest of Common.h and
remove the header from the repository entirely
If invalid operation exceptions are enabled and an invalid operation
occurs, then the destination value remains untouched. This fixes issues
that may arise when using these two instructions where the destination
gets steamrolled by an infinity or NaN value.
If a NaN of any type is passed as the operand to either of these
instructions, we shouldn't go down the regular code path, as we end up
potentially setting the wrong flags. For example, we wouldn't set the
FPSCR.VXCVI bit properly. We'd also set FPSCR.FI, when in actuality it
should be unset.
If an SNaN is passed as an operand, we also need to set the FPSCR.VXSNAN
bit as well.
The flag setting behavior for these can be found in Appendix C.4.2 in
PowerPC Microprocessor Family: The Programming Environments Manual for
32 and 64-bit Microprocessors.
fctiwz functions in the same manner as fctiw, with the difference being
that fctiwz always assumes the rounding mode being towards zero. Because
of this, we can implement fctiwz in terms of fctiw's code, but modify it
to accept a rounding mode, allowing us to preserve proper behavior for
both instructions.
We also move Helper_UpdateCR1 to a temporary home in
Interpreter_FPUtils.h for the time being. It would be more desirable to
move it to a new common header for all the helpers, so that even JITs
can use them if they so wish, however, this and the following changes
are intended to only touch the interpreter to keep changes minimal for
fixing instruction behavior.
JitCommon already duplicates the Helper_Mask function within
JitBase.cpp/.h, and the ARM JIT includes the Interpreter header in order
to call Helper_Carry. So a follow up is best suited here, as this
touches two other CPU backends.
We can just memcpy the data instead of pointer-casting data, which is
alignment-safe and doesn't run afoul of aliasing rules.
Previously it also made it seem as if data itself pointed to valid
usable data, but it doesn't, it simply functions as an out parameter
where we push data built up from the GetState() functions into it.
This was added in 4bdb4aa0d1 back in
2009-02-27. The only usage spot of this macro involves the same checks
that were used to define that preprocessor macro, so we can simply
remove the macro
If any operand is a signaling NaN, we need to signify this by setting
the VXSNAN bit.
Fixes NaN flag setting for fmsub, fmsubs, fnmsub, fnmsubs, ps_msub, and
ps_nmsub instructions.
If any operand is a signaling NaN, we need to signify this by setting
the VXSNAN bit.
Fixes NaN flag setting for fmadd, fmadds, fnmadd, fnmadds, ps_madd,
ps_nmadd, ps_madds0, and ps_madds1
If either operand is a signaling NaN, we need to signify this by setting
the VXSNAN bit.
This fixes NaN flag setting for fsub, fsubs, and ps_sub instructions.
If either operand is a signaling NaN, we need to signify that by setting
the VXSNAN bit.
This fixes NaN flag setting for fdiv, fdivs and ps_div instructions.
These aren't used to modify the data they point to, so make that
explicit. Also while we're at it, add const to any nearby variables that
can be made so.
This might happen if someone moves settings between e.g. a PC and
an Android device, or if someone was using JITIL and updates Dolphin.
I also made the panic alert a bit more explanatory.
It's not used anywhere other than in DolphinQt2, where the usage is
incorrect and stupid since we shouldn't be trying to stop the core
and 'restore config' that was changed by the core at app exit time,
but immediately when the core is being shut down.
Makes all of the naming consistent with our code style, and makes
parameters match their header equivalents.
Essentially just a clean-up of things that weren't migrated over
already.
If either of the operands are signaling NaNs, then an invalid operation
exception needs to be indicated within the FPSCR.
This corrects SNaN flag setting for fmul, fmuls, ps_mul, ps_muls0, and
ps_muls1.
In old GCC versions, capturing 'this' does not work for some lambdas.
The workaround is to not use auto for the parameter (even though the
type is obvious). This can be dropped once we require GCC 7.
If the input is a signaling NaN, then we need to signal that via setting
the FPSCR.VXSNAN bit. We also shouldn't update the FPRF flags if
FPSCR.VE is set.
If the FPSCR.VE bit is set and an invalid operand is passed in, then the FPRF
shouldn't be updated. Similarly this is also the case when the FPSCR.ZE bit
is set and negative or positive zero is passed in as the operand.
If FPSCR.ZE is set and a divide by zero exception is signaled, then the
FPRF shouldn't be updated with a result. Similarly, if the input is an
SNaN and FPSCR.VE is set, then the FPRF shouldn't be updated.
The VX bit is intended to be a summary bit indicating the occurrence of
any kind of invalid operation. Therefore, whenever an invalid operation
exception is set, also set VX.
This corrects our CR flag setting for multiple instructions in certain
scenarios. This corrects flag setting cases in fadd, fadds, fctiw, fctiwz, fdiv,
frsp, frsqrte, fsub, and fsubs (and technically every floating-point
instruction that we make more accurate in the future with regards to
flag setting).
This ports the Wii filesystem root, Wii SD card path and dump path
settings to the new config system (OnionConfig).
My initial plan was to wait until DolphinWX was removed before porting
most of the Main (Core, DSP, General) settings to onion config, but
I've decided to submit a small part of those changes to fix
[issue 10566](https://bugs.dolphin-emu.org/issues/10566).
Removes the need to manually set the FileUtil path in the UI frontends
and gets rid of some more members that don't really belong in SConfig.
Also fixes a bug which would cause the dump path not to get created
after change.
Only invoke config changed callbacks from Config::Save, not
Layer::Save. The latter results in callbacks being called
once per layer, up to 7 times per save.
These disc images are only used on dev units and not retail units.
There are two important differences compared to normal Wii disc images:
- The data starts 0x8000 bytes into each partition instead of 0x20000
- The data of a partition is stored unencrypted and contains no hashes
Our old implementation was just guesswork and doesn't work at all.
According to testing by GerbilSoft, this commit's implementation
is able to read and extract files in the filesystem correctly,
but the tested game still isn't able to boot. (It's thanks to their
info about unencrypted disc images that I was able to make this commit.)
Initialising Wii filesystem contents should be done after Boot and
not in HW to ensure that we operate with the correct title context
and to make sure required title directories exist (so that Movie and
Netplay code can copy data from and to the temporary NAND).
Previously, given cases such as 0x80000000 / 0xFFFFFFFF we'd incorrectly
set the destination register value to zero. If the dividend is negative,
then the destination should be set to -1 (0xFFFFFFFF), however if the
dividend is positive, then the destination should be set to 0.
Note that the 750CL documents state that:
"If an attempt is made to perform either of the divisions --
0x80000000 / -1 or <anything> / 0, then the contents of rD are
undefined, as are the contents of the LT, GT, and EQ bits of the CR0
field (if Rc = 1). In this case, if OE = 1 then OV is set."
So this is a particular behavior of the hardware itself.