We bracket each translated instruction with calls to pre- and
post-verify routines. The pre-verify routine makes a copy of the
current core state and the contents of any affected memory, and the
post-verify routine runs the associated interpreter function on the
initial core state (and memory contents), then compares the result to
the state produced by the JIT code and reports any differences.
(FPSCR is ignored since the JIT translators don't update it yet.)
To avoid false failures caused by other cores storing to the same
memory region referenced by an instruction while the instruction is
being verified, we force all load and store instructions subject to
verification to go through a mutex, ensuring that only one core can
access memory at any time.
The kc, lwarx, and stwcx instructions are not verified since they are
not repeatable. (lwarx and stwcx do not obey the memory access mutex
since they do not go through the verifier, but simultaneous access to
memory with lwarx/stwcx and other load/store instructions is
unreliable anyway and real-world code should never do it, so we don't
worry about that case.)
Also rename the related configuration option from "debug" to "verify"
to better reflect its purpose.
Sound is off by default (to avoid destroying speakers in case the
logic is incorrect for some case); pass the --sound option to enable.
Sound data can be dumped by setting the sound::dump_sounds option in
the configuration file to true.
This is a extremely large change that includes the following:
- The main executable is our default front-end: decaf-cli
- GLFW/SDL is moved from platform to the front-end
- Configuration handling is now moved to front-end
- The library now has a 'public binding' via decaf/decaf.h
- Input is now handled by the front-end through callbacks.
- GPU thread startup is now handled by the front-end.
- Rendering of the scan buffers to the screen is now handled by the front-end.