diff options
author | Yuri Kunde Schlesner <yuriks@yuriks.net> | 2016-09-21 20:29:48 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-09-21 20:29:48 +0200 |
commit | d5d2ca8058a0f1c00ab7ca9fe2c058ba47546c0a (patch) | |
tree | 8a22ca73ff838f3f0090b29a548ae81087fc90ed | |
parent | README: Specify master branch for Travis CI badge (diff) | |
parent | Fix Travis clang-format check (diff) | |
download | yuzu-d5d2ca8058a0f1c00ab7ca9fe2c058ba47546c0a.tar yuzu-d5d2ca8058a0f1c00ab7ca9fe2c058ba47546c0a.tar.gz yuzu-d5d2ca8058a0f1c00ab7ca9fe2c058ba47546c0a.tar.bz2 yuzu-d5d2ca8058a0f1c00ab7ca9fe2c058ba47546c0a.tar.lz yuzu-d5d2ca8058a0f1c00ab7ca9fe2c058ba47546c0a.tar.xz yuzu-d5d2ca8058a0f1c00ab7ca9fe2c058ba47546c0a.tar.zst yuzu-d5d2ca8058a0f1c00ab7ca9fe2c058ba47546c0a.zip |
Diffstat (limited to '')
401 files changed, 19275 insertions, 18173 deletions
diff --git a/.travis-build.sh b/.travis-build.sh index 80361ddaf..b8562cb02 100755 --- a/.travis-build.sh +++ b/.travis-build.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash set -e set -x @@ -9,6 +9,39 @@ if grep -nr '\s$' src *.yml *.txt *.md Doxyfile .gitignore .gitmodules .travis* exit 1 fi +# Only run clang-format on Linux because we don't have 4.0 on OS X images +if [ "$TRAVIS_OS_NAME" = "linux" ]; then + # Default clang-format points to default 3.5 version one + CLANG_FORMAT=clang-format-4.0 + $CLANG_FORMAT --version + + if [ "$TRAVIS_EVENT_TYPE" = "pull_request" ]; then + # Get list of every file modified in this pull request + files_to_lint="$(git diff --name-only --diff-filter=ACMRTUXB $TRAVIS_COMMIT_RANGE | grep '^src/[^.]*[.]\(cpp\|h\)$')" + else + # Check everything for branch pushes + files_to_lint="$(find src/ -name '*.cpp' -or -name '*.h')" + fi + + # Turn off tracing for this because it's too verbose + set +x + + for f in $files_to_lint; do + d=$(diff -u "$f" <($CLANG_FORMAT "$f")) + if ! [ -z "$d" ]; then + echo "!!! $f not compliant to coding style, here is the fix:" + echo "$d" + fail=1 + fi + done + + set -x + + if [ "$fail" = 1 ]; then + exit 1 + fi +fi + #if OS is linux or is not set if [ "$TRAVIS_OS_NAME" = "linux" -o -z "$TRAVIS_OS_NAME" ]; then export CC=gcc-6 diff --git a/.travis.yml b/.travis.yml index 69f9ef273..ea99be2c4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,7 @@ addons: apt: sources: - ubuntu-toolchain-r-test + - llvm-toolchain-precise packages: - gcc-6 - g++-6 @@ -25,6 +26,7 @@ addons: - xorg-dev - lib32stdc++6 # For CMake - lftp # To upload builds + - clang-format-4.0 cache: directories: diff --git a/hooks/pre-commit b/hooks/pre-commit index c100bb634..6dd281c4a 100755 --- a/hooks/pre-commit +++ b/hooks/pre-commit @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # Enforce citra's whitespace policy git config --local core.whitespace tab-in-indent,trailing-space @@ -7,7 +7,7 @@ paths_to_check="src/ CMakeLists.txt" # If there are whitespace errors, print the offending file names and fail. if ! git diff --cached --check -- $paths_to_check ; then - cat<<END; + cat<<END Error: This commit would contain trailing spaces or tabs, which is against this repo's policy. Please correct those issues before commiting. (Use 'git diff --check' for more details) @@ -18,9 +18,26 @@ fi # Check for tabs, since tab-in-indent catches only those at the beginning of a line if git diff --cached -- $paths_to_check | egrep '^\+.* '; then - cat<<END; + cat<<END Error: This commit would contain a tab, which is against this repo's policy. If you know what you are doing, you can try 'git commit --no-verify' to bypass the check. END exit 1 fi + +for f in $(git diff --name-only --diff-filter=ACMRTUXB --cached); do + if ! echo "$f" | egrep -q "[.](cpp|h)$"; then + continue + fi + if ! echo "$f" | egrep -q "^src/"; then + continue + fi + d=$(diff -u "$f" <(clang-format "$f")) + if ! [ -z "$d" ]; then + echo "!!! $f not compliant to coding style, here is the fix:" + echo "$d" + fail=1 + fi +done + +exit "$fail" diff --git a/src/.clang-format b/src/.clang-format new file mode 100644 index 000000000..1c6b71b2e --- /dev/null +++ b/src/.clang-format @@ -0,0 +1,88 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: false +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 100 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IncludeCategories: + - Regex: '^\<[^Q][^/.>]*\>' + Priority: -2 + - Regex: '^\<' + Priority: -1 + - Regex: '^\"' + Priority: 0 +IndentCaseLabels: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 150 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Never +... diff --git a/src/audio_core/audio_core.cpp b/src/audio_core/audio_core.cpp index 8e19ec0c4..49260de7c 100644 --- a/src/audio_core/audio_core.cpp +++ b/src/audio_core/audio_core.cpp @@ -4,14 +4,12 @@ #include <memory> #include <string> - #include "audio_core/audio_core.h" #include "audio_core/hle/dsp.h" #include "audio_core/hle/pipe.h" #include "audio_core/null_sink.h" #include "audio_core/sink.h" #include "audio_core/sink_details.h" - #include "core/core_timing.h" #include "core/hle/kernel/vm_manager.h" #include "core/hle/service/dsp_dsp.h" @@ -42,10 +40,18 @@ void Init() { } void AddAddressSpace(Kernel::VMManager& address_space) { - auto r0_vma = address_space.MapBackingMemory(DSP::HLE::region0_base, reinterpret_cast<u8*>(&DSP::HLE::g_regions[0]), sizeof(DSP::HLE::SharedMemory), Kernel::MemoryState::IO).MoveFrom(); + auto r0_vma = address_space + .MapBackingMemory(DSP::HLE::region0_base, + reinterpret_cast<u8*>(&DSP::HLE::g_regions[0]), + sizeof(DSP::HLE::SharedMemory), Kernel::MemoryState::IO) + .MoveFrom(); address_space.Reprotect(r0_vma, Kernel::VMAPermission::ReadWrite); - auto r1_vma = address_space.MapBackingMemory(DSP::HLE::region1_base, reinterpret_cast<u8*>(&DSP::HLE::g_regions[1]), sizeof(DSP::HLE::SharedMemory), Kernel::MemoryState::IO).MoveFrom(); + auto r1_vma = address_space + .MapBackingMemory(DSP::HLE::region1_base, + reinterpret_cast<u8*>(&DSP::HLE::g_regions[1]), + sizeof(DSP::HLE::SharedMemory), Kernel::MemoryState::IO) + .MoveFrom(); address_space.Reprotect(r1_vma, Kernel::VMAPermission::ReadWrite); } @@ -58,9 +64,9 @@ void SelectSink(std::string sink_id) { return; } - auto iter = std::find_if(g_sink_details.begin(), g_sink_details.end(), [sink_id](const auto& sink_detail) { - return sink_detail.id == sink_id; - }); + auto iter = + std::find_if(g_sink_details.begin(), g_sink_details.end(), + [sink_id](const auto& sink_detail) { return sink_detail.id == sink_id; }); if (iter == g_sink_details.end()) { LOG_ERROR(Audio, "AudioCore::SelectSink given invalid sink_id"); diff --git a/src/audio_core/audio_core.h b/src/audio_core/audio_core.h index 7e678aba5..0edf6dd15 100644 --- a/src/audio_core/audio_core.h +++ b/src/audio_core/audio_core.h @@ -12,7 +12,7 @@ class VMManager; namespace AudioCore { -constexpr int native_sample_rate = 32728; ///< 32kHz +constexpr int native_sample_rate = 32728; ///< 32kHz /// Initialise Audio Core void Init(); diff --git a/src/audio_core/codec.cpp b/src/audio_core/codec.cpp index 3e23323f1..7a3bd7eb3 100644 --- a/src/audio_core/codec.cpp +++ b/src/audio_core/codec.cpp @@ -6,31 +6,32 @@ #include <cstddef> #include <cstring> #include <vector> - #include "audio_core/codec.h" - #include "common/assert.h" #include "common/common_types.h" #include "common/math_util.h" namespace Codec { -StereoBuffer16 DecodeADPCM(const u8* const data, const size_t sample_count, const std::array<s16, 16>& adpcm_coeff, ADPCMState& state) { +StereoBuffer16 DecodeADPCM(const u8* const data, const size_t sample_count, + const std::array<s16, 16>& adpcm_coeff, ADPCMState& state) { // GC-ADPCM with scale factor and variable coefficients. // Frames are 8 bytes long containing 14 samples each. // Samples are 4 bits (one nibble) long. constexpr size_t FRAME_LEN = 8; constexpr size_t SAMPLES_PER_FRAME = 14; - constexpr std::array<int, 16> SIGNED_NIBBLES {{ 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1 }}; + constexpr std::array<int, 16> SIGNED_NIBBLES = { + {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}}; - const size_t ret_size = sample_count % 2 == 0 ? sample_count : sample_count + 1; // Ensure multiple of two. + const size_t ret_size = + sample_count % 2 == 0 ? sample_count : sample_count + 1; // Ensure multiple of two. StereoBuffer16 ret(ret_size); - int yn1 = state.yn1, - yn2 = state.yn2; + int yn1 = state.yn1, yn2 = state.yn2; - const size_t NUM_FRAMES = (sample_count + (SAMPLES_PER_FRAME - 1)) / SAMPLES_PER_FRAME; // Round up. + const size_t NUM_FRAMES = + (sample_count + (SAMPLES_PER_FRAME - 1)) / SAMPLES_PER_FRAME; // Round up. for (size_t framei = 0; framei < NUM_FRAMES; framei++) { const int frame_header = data[framei * FRAME_LEN]; const int scale = 1 << (frame_header & 0xF); @@ -43,7 +44,8 @@ StereoBuffer16 DecodeADPCM(const u8* const data, const size_t sample_count, cons // Decodes an audio sample. One nibble produces one sample. const auto decode_sample = [&](const int nibble) -> s16 { const int xn = nibble * scale; - // We first transform everything into 11 bit fixed point, perform the second order digital filter, then transform back. + // We first transform everything into 11 bit fixed point, perform the second order + // digital filter, then transform back. // 0x400 == 0.5 in 11 bit fixed point. // Filter: y[n] = x[n] + 0.5 + c1 * y[n-1] + c2 * y[n-2] int val = ((xn << 11) + 0x400 + coef1 * yn1 + coef2 * yn2) >> 11; @@ -82,7 +84,8 @@ static s16 SignExtendS8(u8 x) { return static_cast<s16>(static_cast<s8>(x)); } -StereoBuffer16 DecodePCM8(const unsigned num_channels, const u8* const data, const size_t sample_count) { +StereoBuffer16 DecodePCM8(const unsigned num_channels, const u8* const data, + const size_t sample_count) { ASSERT(num_channels == 1 || num_channels == 2); StereoBuffer16 ret(sample_count); @@ -101,7 +104,8 @@ StereoBuffer16 DecodePCM8(const unsigned num_channels, const u8* const data, con return ret; } -StereoBuffer16 DecodePCM16(const unsigned num_channels, const u8* const data, const size_t sample_count) { +StereoBuffer16 DecodePCM16(const unsigned num_channels, const u8* const data, + const size_t sample_count) { ASSERT(num_channels == 1 || num_channels == 2); StereoBuffer16 ret(sample_count); @@ -118,5 +122,4 @@ StereoBuffer16 DecodePCM16(const unsigned num_channels, const u8* const data, co return ret; } - }; diff --git a/src/audio_core/codec.h b/src/audio_core/codec.h index e695f2edc..2b0c395e6 100644 --- a/src/audio_core/codec.h +++ b/src/audio_core/codec.h @@ -6,7 +6,6 @@ #include <array> #include <vector> - #include "common/common_types.h" namespace Codec { @@ -29,7 +28,8 @@ struct ADPCMState { * @param state ADPCM state, this is updated with new state * @return Decoded stereo signed PCM16 data, sample_count in length */ -StereoBuffer16 DecodeADPCM(const u8* const data, const size_t sample_count, const std::array<s16, 16>& adpcm_coeff, ADPCMState& state); +StereoBuffer16 DecodeADPCM(const u8* const data, const size_t sample_count, + const std::array<s16, 16>& adpcm_coeff, ADPCMState& state); /** * @param num_channels Number of channels @@ -37,7 +37,8 @@ StereoBuffer16 DecodeADPCM(const u8* const data, const size_t sample_count, cons * @param sample_count Length of buffer in terms of number of samples * @return Decoded stereo signed PCM16 data, sample_count in length */ -StereoBuffer16 DecodePCM8(const unsigned num_channels, const u8* const data, const size_t sample_count); +StereoBuffer16 DecodePCM8(const unsigned num_channels, const u8* const data, + const size_t sample_count); /** * @param num_channels Number of channels @@ -45,6 +46,6 @@ StereoBuffer16 DecodePCM8(const unsigned num_channels, const u8* const data, con * @param sample_count Length of buffer in terms of number of samples * @return Decoded stereo signed PCM16 data, sample_count in length */ -StereoBuffer16 DecodePCM16(const unsigned num_channels, const u8* const data, const size_t sample_count); - +StereoBuffer16 DecodePCM16(const unsigned num_channels, const u8* const data, + const size_t sample_count); }; diff --git a/src/audio_core/hle/common.h b/src/audio_core/hle/common.h index 596b67eaf..7fbc3ad9a 100644 --- a/src/audio_core/hle/common.h +++ b/src/audio_core/hle/common.h @@ -6,30 +6,28 @@ #include <algorithm> #include <array> - #include "common/common_types.h" namespace DSP { namespace HLE { constexpr int num_sources = 24; -constexpr int samples_per_frame = 160; ///< Samples per audio frame at native sample rate +constexpr int samples_per_frame = 160; ///< Samples per audio frame at native sample rate /// The final output to the speakers is stereo. Preprocessing output in Source is also stereo. using StereoFrame16 = std::array<std::array<s16, 2>, samples_per_frame>; /// The DSP is quadraphonic internally. -using QuadFrame32 = std::array<std::array<s32, 4>, samples_per_frame>; +using QuadFrame32 = std::array<std::array<s32, 4>, samples_per_frame>; /** * This performs the filter operation defined by FilterT::ProcessSample on the frame in-place. * FilterT::ProcessSample is called sequentially on the samples. */ -template<typename FrameT, typename FilterT> +template <typename FrameT, typename FilterT> void FilterFrame(FrameT& frame, FilterT& filter) { - std::transform(frame.begin(), frame.end(), frame.begin(), [&filter](const auto& sample) { - return filter.ProcessSample(sample); - }); + std::transform(frame.begin(), frame.end(), frame.begin(), + [&filter](const auto& sample) { return filter.ProcessSample(sample); }); } } // namespace HLE diff --git a/src/audio_core/hle/dsp.cpp b/src/audio_core/hle/dsp.cpp index 1420bf2dd..58690970a 100644 --- a/src/audio_core/hle/dsp.cpp +++ b/src/audio_core/hle/dsp.cpp @@ -4,7 +4,6 @@ #include <array> #include <memory> - #include "audio_core/hle/dsp.h" #include "audio_core/hle/mixers.h" #include "audio_core/hle/pipe.h" @@ -47,10 +46,9 @@ static SharedMemory& WriteRegion() { // Audio processing and mixing static std::array<Source, num_sources> sources = { - Source(0), Source(1), Source(2), Source(3), Source(4), Source(5), - Source(6), Source(7), Source(8), Source(9), Source(10), Source(11), - Source(12), Source(13), Source(14), Source(15), Source(16), Source(17), - Source(18), Source(19), Source(20), Source(21), Source(22), Source(23) + Source(0), Source(1), Source(2), Source(3), Source(4), Source(5), Source(6), Source(7), + Source(8), Source(9), Source(10), Source(11), Source(12), Source(13), Source(14), Source(15), + Source(16), Source(17), Source(18), Source(19), Source(20), Source(21), Source(22), Source(23), }; static Mixers mixers; @@ -62,14 +60,16 @@ static StereoFrame16 GenerateCurrentFrame() { // Generate intermediate mixes for (size_t i = 0; i < num_sources; i++) { - write.source_statuses.status[i] = sources[i].Tick(read.source_configurations.config[i], read.adpcm_coefficients.coeff[i]); + write.source_statuses.status[i] = + sources[i].Tick(read.source_configurations.config[i], read.adpcm_coefficients.coeff[i]); for (size_t mix = 0; mix < 3; mix++) { sources[i].MixInto(intermediate_mixes[mix], mix); } } // Generate final mix - write.dsp_status = mixers.Tick(read.dsp_configuration, read.intermediate_mix_samples, write.intermediate_mix_samples, intermediate_mixes); + write.dsp_status = mixers.Tick(read.dsp_configuration, read.intermediate_mix_samples, + write.intermediate_mix_samples, intermediate_mixes); StereoFrame16 output_frame = mixers.GetOutput(); @@ -152,7 +152,8 @@ void Shutdown() { bool Tick() { StereoFrame16 current_frame = {}; - // TODO: Check dsp::DSP semaphore (which indicates emulated application has finished writing to shared memory region) + // TODO: Check dsp::DSP semaphore (which indicates emulated application has finished writing to + // shared memory region) current_frame = GenerateCurrentFrame(); OutputCurrentFrame(current_frame); diff --git a/src/audio_core/hle/dsp.h b/src/audio_core/hle/dsp.h index 565f20b6f..0a0f60ac1 100644 --- a/src/audio_core/hle/dsp.h +++ b/src/audio_core/hle/dsp.h @@ -8,9 +8,7 @@ #include <cstddef> #include <memory> #include <type_traits> - #include "audio_core/hle/common.h" - #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" @@ -23,15 +21,15 @@ class Sink; namespace DSP { namespace HLE { -// The application-accessible region of DSP memory consists of two parts. -// Both are marked as IO and have Read/Write permissions. +// The application-accessible region of DSP memory consists of two parts. Both are marked as IO and +// have Read/Write permissions. // // First Region: 0x1FF50000 (Size: 0x8000) // Second Region: 0x1FF70000 (Size: 0x8000) // // The DSP reads from each region alternately based on the frame counter for each region much like a -// double-buffer. The frame counter is located as the very last u16 of each region and is incremented -// each audio tick. +// double-buffer. The frame counter is located as the very last u16 of each region and is +// incremented each audio tick. constexpr VAddr region0_base = 0x1FF50000; constexpr VAddr region1_base = 0x1FF70000; @@ -56,6 +54,7 @@ struct u32_dsp { void operator=(u32 new_value) { storage = Convert(new_value); } + private: static constexpr u32 Convert(u32 value) { return (value << 16) | (value >> 16); @@ -89,13 +88,13 @@ static_assert(std::is_trivially_copyable<u32_dsp>::value, "u32_dsp isn't trivial // #: This refers to the order in which they appear in the DspPipe::Audio DSP pipe. // See also: DSP::HLE::PipeRead. // -// Note that the above addresses do vary slightly between audio firmwares observed; the addresses are -// not fixed in stone. The addresses above are only an examplar; they're what this implementation -// does and provides to applications. +// Note that the above addresses do vary slightly between audio firmwares observed; the addresses +// are not fixed in stone. The addresses above are only an examplar; they're what this +// implementation does and provides to applications. // -// Application requests the DSP service to convert DSP addresses into ARM11 virtual addresses using the -// ConvertProcessAddressFromDspDram service call. Applications seem to derive the addresses for the -// second region via: +// Application requests the DSP service to convert DSP addresses into ARM11 virtual addresses using +// the ConvertProcessAddressFromDspDram service call. Applications seem to derive the addresses for +// the second region via: // second_region_dsp_addr = first_region_dsp_addr | 0x10000 // // Applications maintain most of its own audio state, the memory region is used mainly for @@ -103,21 +102,24 @@ static_assert(std::is_trivially_copyable<u32_dsp>::value, "u32_dsp isn't trivial // // In the documentation below, filter and effect transfer functions are specified in the z domain. // (If you are more familiar with the Laplace transform, z = exp(sT). The z domain is the digital -// frequency domain, just like how the s domain is the analog frequency domain.) +// frequency domain, just like how the s domain is the analog frequency domain.) #define INSERT_PADDING_DSPWORDS(num_words) INSERT_PADDING_BYTES(2 * (num_words)) // GCC versions < 5.0 do not implement std::is_trivially_copyable. // Excluding MSVC because it has weird behaviour for std::is_trivially_copyable. #if (__GNUC__ >= 5) || defined(__clang__) - #define ASSERT_DSP_STRUCT(name, size) \ - static_assert(std::is_standard_layout<name>::value, "DSP structure " #name " doesn't use standard layout"); \ - static_assert(std::is_trivially_copyable<name>::value, "DSP structure " #name " isn't trivially copyable"); \ - static_assert(sizeof(name) == (size), "Unexpected struct size for DSP structure " #name) +#define ASSERT_DSP_STRUCT(name, size) \ + static_assert(std::is_standard_layout<name>::value, \ + "DSP structure " #name " doesn't use standard layout"); \ + static_assert(std::is_trivially_copyable<name>::value, \ + "DSP structure " #name " isn't trivially copyable"); \ + static_assert(sizeof(name) == (size), "Unexpected struct size for DSP structure " #name) #else - #define ASSERT_DSP_STRUCT(name, size) \ - static_assert(std::is_standard_layout<name>::value, "DSP structure " #name " doesn't use standard layout"); \ - static_assert(sizeof(name) == (size), "Unexpected struct size for DSP structure " #name) +#define ASSERT_DSP_STRUCT(name, size) \ + static_assert(std::is_standard_layout<name>::value, \ + "DSP structure " #name " doesn't use standard layout"); \ + static_assert(sizeof(name) == (size), "Unexpected struct size for DSP structure " #name) #endif struct SourceConfiguration { @@ -130,7 +132,8 @@ struct SourceConfiguration { BitField<0, 1, u32_le> format_dirty; BitField<1, 1, u32_le> mono_or_stereo_dirty; BitField<2, 1, u32_le> adpcm_coefficients_dirty; - BitField<3, 1, u32_le> partial_embedded_buffer_dirty; ///< Tends to be set when a looped buffer is queued. + /// Tends to be set when a looped buffer is queued. + BitField<3, 1, u32_le> partial_embedded_buffer_dirty; BitField<4, 1, u32_le> partial_reset_flag; BitField<16, 1, u32_le> enable_dirty; @@ -138,7 +141,8 @@ struct SourceConfiguration { BitField<18, 1, u32_le> rate_multiplier_dirty; BitField<19, 1, u32_le> buffer_queue_dirty; BitField<20, 1, u32_le> loop_related_dirty; - BitField<21, 1, u32_le> play_position_dirty; ///< Tends to also be set when embedded buffer is updated. + /// Tends to also be set when embedded buffer is updated. + BitField<21, 1, u32_le> play_position_dirty; BitField<22, 1, u32_le> filters_enabled_dirty; BitField<23, 1, u32_le> simple_filter_dirty; BitField<24, 1, u32_le> biquad_filter_dirty; @@ -153,9 +157,9 @@ struct SourceConfiguration { // Gain control /** - * Gain is between 0.0-1.0. This determines how much will this source appear on - * each of the 12 channels that feed into the intermediate mixers. - * Each of the three intermediate mixers is fed two left and two right channels. + * Gain is between 0.0-1.0. This determines how much will this source appear on each of the + * 12 channels that feed into the intermediate mixers. Each of the three intermediate mixers + * is fed two left and two right channels. */ float_le gain[3][4]; @@ -167,7 +171,7 @@ struct SourceConfiguration { enum class InterpolationMode : u8 { Polyphase = 0, Linear = 1, - None = 2 + None = 2, }; InterpolationMode interpolation_mode; @@ -191,8 +195,8 @@ struct SourceConfiguration { * This is a normalised biquad filter (second-order). * The transfer function of this filter is: * H(z) = (b0 + b1 z^-1 + b2 z^-2) / (1 - a1 z^-1 - a2 z^-2) - * Nintendo chose to negate the feedbackward coefficients. This differs from standard notation - * as in: https://ccrma.stanford.edu/~jos/filters/Direct_Form_I.html + * Nintendo chose to negate the feedbackward coefficients. This differs from standard + * notation as in: https://ccrma.stanford.edu/~jos/filters/Direct_Form_I.html * Values are signed fixed point with 14 fractional bits. */ struct BiquadFilter { @@ -239,23 +243,24 @@ struct SourceConfiguration { /// Is a looping buffer. u8 is_looping; - /// This value is shown in SourceStatus::previous_buffer_id when this buffer has finished. - /// This allows the emulated application to tell what buffer is currently playing + /// This value is shown in SourceStatus::previous_buffer_id when this buffer has + /// finished. This allows the emulated application to tell what buffer is currently + /// playing. u16_le buffer_id; INSERT_PADDING_DSPWORDS(1); }; - u16_le buffers_dirty; ///< Bitmap indicating which buffers are dirty (bit i -> buffers[i]) - Buffer buffers[4]; ///< Queued Buffers + u16_le buffers_dirty; ///< Bitmap indicating which buffers are dirty (bit i -> buffers[i]) + Buffer buffers[4]; ///< Queued Buffers // Playback controls u32_dsp loop_related; u8 enable; INSERT_PADDING_BYTES(1); - u16_le sync; ///< Application-side sync (See also: SourceStatus::sync) - u32_dsp play_position; ///< Position. (Units: number of samples) + u16_le sync; ///< Application-side sync (See also: SourceStatus::sync) + u32_dsp play_position; ///< Position. (Units: number of samples) INSERT_PADDING_DSPWORDS(2); // Embedded Buffer @@ -270,13 +275,13 @@ struct SourceConfiguration { enum class MonoOrStereo : u16_le { Mono = 1, - Stereo = 2 + Stereo = 2, }; enum class Format : u16_le { PCM8 = 0, PCM16 = 1, - ADPCM = 2 + ADPCM = 2, }; union { @@ -299,10 +304,11 @@ struct SourceConfiguration { union { u16_le flags2_raw; BitField<0, 1, u16_le> adpcm_dirty; ///< Has the ADPCM info above been changed? - BitField<1, 1, u16_le> is_looping; ///< Is this a looping buffer? + BitField<1, 1, u16_le> is_looping; ///< Is this a looping buffer? }; - /// Buffer id of embedded buffer (used as a buffer id in SourceStatus to reference this buffer). + /// Buffer id of embedded buffer (used as a buffer id in SourceStatus to reference this + /// buffer). u16_le buffer_id; }; @@ -313,11 +319,11 @@ ASSERT_DSP_STRUCT(SourceConfiguration::Configuration::Buffer, 20); struct SourceStatus { struct Status { - u8 is_enabled; ///< Is this channel enabled? (Doesn't have to be playing anything.) - u8 current_buffer_id_dirty; ///< Non-zero when current_buffer_id changes - u16_le sync; ///< Is set by the DSP to the value of SourceConfiguration::sync - u32_dsp buffer_position; ///< Number of samples into the current buffer - u16_le current_buffer_id; ///< Updated when a buffer finishes playing + u8 is_enabled; ///< Is this channel enabled? (Doesn't have to be playing anything.) + u8 current_buffer_id_dirty; ///< Non-zero when current_buffer_id changes + u16_le sync; ///< Is set by the DSP to the value of SourceConfiguration::sync + u32_dsp buffer_position; ///< Number of samples into the current buffer + u16_le current_buffer_id; ///< Updated when a buffer finishes playing INSERT_PADDING_DSPWORDS(1); }; @@ -347,7 +353,8 @@ struct DspConfiguration { BitField<28, 1, u32_le> headphones_connected_dirty; }; - /// The DSP has three intermediate audio mixers. This controls the volume level (0.0-1.0) for each at the final mixer + /// The DSP has three intermediate audio mixers. This controls the volume level (0.0-1.0) for + /// each at the final mixer. float_le volume[3]; INSERT_PADDING_DSPWORDS(3); @@ -355,7 +362,7 @@ struct DspConfiguration { enum class OutputFormat : u16_le { Mono = 0, Stereo = 1, - Surround = 2 + Surround = 2, }; OutputFormat output_format; @@ -388,8 +395,10 @@ struct DspConfiguration { u16_le enable; INSERT_PADDING_DSPWORDS(1); u16_le outputs; - u32_dsp work_buffer_address; ///< The application allocates a block of memory for the DSP to use as a work buffer. - u16_le frame_count; ///< Frames to delay by + /// The application allocates a block of memory for the DSP to use as a work buffer. + u32_dsp work_buffer_address; + /// Frames to delay by + u16_le frame_count; // Coefficients s16_le g; ///< Fixed point with 7 fractional bits @@ -506,21 +515,36 @@ ASSERT_DSP_STRUCT(SharedMemory, 0x8000); extern std::array<SharedMemory, 2> g_regions; // Structures must have an offset that is a multiple of two. -static_assert(offsetof(SharedMemory, frame_counter) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); -static_assert(offsetof(SharedMemory, source_configurations) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); -static_assert(offsetof(SharedMemory, source_statuses) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); -static_assert(offsetof(SharedMemory, adpcm_coefficients) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); -static_assert(offsetof(SharedMemory, dsp_configuration) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); -static_assert(offsetof(SharedMemory, dsp_status) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); -static_assert(offsetof(SharedMemory, final_samples) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); -static_assert(offsetof(SharedMemory, intermediate_mix_samples) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); -static_assert(offsetof(SharedMemory, compressor) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); -static_assert(offsetof(SharedMemory, dsp_debug) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); -static_assert(offsetof(SharedMemory, unknown10) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); -static_assert(offsetof(SharedMemory, unknown11) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); -static_assert(offsetof(SharedMemory, unknown12) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); -static_assert(offsetof(SharedMemory, unknown13) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); -static_assert(offsetof(SharedMemory, unknown14) % 2 == 0, "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); +static_assert(offsetof(SharedMemory, frame_counter) % 2 == 0, + "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); +static_assert(offsetof(SharedMemory, source_configurations) % 2 == 0, + "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); +static_assert(offsetof(SharedMemory, source_statuses) % 2 == 0, + "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); +static_assert(offsetof(SharedMemory, adpcm_coefficients) % 2 == 0, + "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); +static_assert(offsetof(SharedMemory, dsp_configuration) % 2 == 0, + "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); +static_assert(offsetof(SharedMemory, dsp_status) % 2 == 0, + "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); +static_assert(offsetof(SharedMemory, final_samples) % 2 == 0, + "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); +static_assert(offsetof(SharedMemory, intermediate_mix_samples) % 2 == 0, + "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); +static_assert(offsetof(SharedMemory, compressor) % 2 == 0, + "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); +static_assert(offsetof(SharedMemory, dsp_debug) % 2 == 0, + "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); +static_assert(offsetof(SharedMemory, unknown10) % 2 == 0, + "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); +static_assert(offsetof(SharedMemory, unknown11) % 2 == 0, + "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); +static_assert(offsetof(SharedMemory, unknown12) % 2 == 0, + "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); +static_assert(offsetof(SharedMemory, unknown13) % 2 == 0, + "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); +static_assert(offsetof(SharedMemory, unknown14) % 2 == 0, + "Structures in DSP::HLE::SharedMemory must be 2-byte aligned"); #undef INSERT_PADDING_DSPWORDS #undef ASSERT_DSP_STRUCT diff --git a/src/audio_core/hle/filter.cpp b/src/audio_core/hle/filter.cpp index 2c65ef026..b24a79b89 100644 --- a/src/audio_core/hle/filter.cpp +++ b/src/audio_core/hle/filter.cpp @@ -4,11 +4,9 @@ #include <array> #include <cstddef> - #include "audio_core/hle/common.h" #include "audio_core/hle/dsp.h" #include "audio_core/hle/filter.h" - #include "common/common_types.h" #include "common/math_util.h" @@ -59,7 +57,9 @@ void SourceFilters::SimpleFilter::Reset() { b0 = 1 << 15; } -void SourceFilters::SimpleFilter::Configure(SourceConfiguration::Configuration::SimpleFilter config) { +void SourceFilters::SimpleFilter::Configure( + SourceConfiguration::Configuration::SimpleFilter config) { + a1 = config.a1; b0 = config.b0; } @@ -88,7 +88,9 @@ void SourceFilters::BiquadFilter::Reset() { b0 = 1 << 14; } -void SourceFilters::BiquadFilter::Configure(SourceConfiguration::Configuration::BiquadFilter config) { +void SourceFilters::BiquadFilter::Configure( + SourceConfiguration::Configuration::BiquadFilter config) { + a1 = config.a1; a2 = config.a2; b0 = config.b0; diff --git a/src/audio_core/hle/filter.h b/src/audio_core/hle/filter.h index 43d2035cd..4281a5898 100644 --- a/src/audio_core/hle/filter.h +++ b/src/audio_core/hle/filter.h @@ -5,10 +5,8 @@ #pragma once #include <array> - #include "audio_core/hle/common.h" #include "audio_core/hle/dsp.h" - #include "common/common_types.h" namespace DSP { @@ -17,7 +15,9 @@ namespace HLE { /// Preprocessing filters. There is an independent set of filters for each Source. class SourceFilters final { public: - SourceFilters() { Reset(); } + SourceFilters() { + Reset(); + } /// Reset internal state. void Reset(); @@ -54,7 +54,9 @@ private: bool biquad_filter_enabled; struct SimpleFilter { - SimpleFilter() { Reset(); } + SimpleFilter() { + Reset(); + } /// Resets internal state. void Reset(); @@ -80,7 +82,9 @@ private: } simple_filter; struct BiquadFilter { - BiquadFilter() { Reset(); } + BiquadFilter() { + Reset(); + } /// Resets internal state. void Reset(); diff --git a/src/audio_core/hle/mixers.cpp b/src/audio_core/hle/mixers.cpp index 18335f7f0..6cc81dfca 100644 --- a/src/audio_core/hle/mixers.cpp +++ b/src/audio_core/hle/mixers.cpp @@ -7,7 +7,6 @@ #include "audio_core/hle/common.h" #include "audio_core/hle/dsp.h" #include "audio_core/hle/mixers.h" - #include "common/assert.h" #include "common/logging/log.h" #include "common/math_util.h" @@ -20,11 +19,9 @@ void Mixers::Reset() { state = {}; } -DspStatus Mixers::Tick(DspConfiguration& config, - const IntermediateMixSamples& read_samples, - IntermediateMixSamples& write_samples, - const std::array<QuadFrame32, 3>& input) -{ +DspStatus Mixers::Tick(DspConfiguration& config, const IntermediateMixSamples& read_samples, + IntermediateMixSamples& write_samples, + const std::array<QuadFrame32, 3>& input) { ParseConfig(config); AuxReturn(read_samples); @@ -73,13 +70,14 @@ void Mixers::ParseConfig(DspConfiguration& config) { if (config.output_format_dirty) { config.output_format_dirty.Assign(0); state.output_format = config.output_format; - LOG_TRACE(Audio_DSP, "mixers output_format = %zu", static_cast<size_t>(config.output_format)); + LOG_TRACE(Audio_DSP, "mixers output_format = %zu", + static_cast<size_t>(config.output_format)); } if (config.headphones_connected_dirty) { config.headphones_connected_dirty.Assign(0); - // Do nothing. - // (Note: Whether headphones are connected does affect coefficients used for surround sound.) + // Do nothing. (Note: Whether headphones are connected does affect coefficients used for + // surround sound.) LOG_TRACE(Audio_DSP, "mixers headphones_connected=%hu", config.headphones_connected); } @@ -94,11 +92,10 @@ static s16 ClampToS16(s32 value) { return static_cast<s16>(MathUtil::Clamp(value, -32768, 32767)); } -static std::array<s16, 2> AddAndClampToS16(const std::array<s16, 2>& a, const std::array<s16, 2>& b) { - return { - ClampToS16(static_cast<s32>(a[0]) + static_cast<s32>(b[0])), - ClampToS16(static_cast<s32>(a[1]) + static_cast<s32>(b[1])) - }; +static std::array<s16, 2> AddAndClampToS16(const std::array<s16, 2>& a, + const std::array<s16, 2>& b) { + return {ClampToS16(static_cast<s32>(a[0]) + static_cast<s32>(b[0])), + ClampToS16(static_cast<s32>(a[1]) + static_cast<s32>(b[1]))}; } void Mixers::DownmixAndMixIntoCurrentFrame(float gain, const QuadFrame32& samples) { @@ -106,27 +103,33 @@ void Mixers::DownmixAndMixIntoCurrentFrame(float gain, const QuadFrame32& sample switch (state.output_format) { case OutputFormat::Mono: - std::transform(current_frame.begin(), current_frame.end(), samples.begin(), current_frame.begin(), - [gain](const std::array<s16, 2>& accumulator, const std::array<s32, 4>& sample) -> std::array<s16, 2> { + std::transform( + current_frame.begin(), current_frame.end(), samples.begin(), current_frame.begin(), + [gain](const std::array<s16, 2>& accumulator, + const std::array<s32, 4>& sample) -> std::array<s16, 2> { // Downmix to mono - s16 mono = ClampToS16(static_cast<s32>((gain * sample[0] + gain * sample[1] + gain * sample[2] + gain * sample[3]) / 2)); + s16 mono = ClampToS16(static_cast<s32>( + (gain * sample[0] + gain * sample[1] + gain * sample[2] + gain * sample[3]) / + 2)); // Mix into current frame - return AddAndClampToS16(accumulator, { mono, mono }); + return AddAndClampToS16(accumulator, {mono, mono}); }); return; case OutputFormat::Surround: - // TODO(merry): Implement surround sound. - // fallthrough + // TODO(merry): Implement surround sound. + // fallthrough case OutputFormat::Stereo: - std::transform(current_frame.begin(), current_frame.end(), samples.begin(), current_frame.begin(), - [gain](const std::array<s16, 2>& accumulator, const std::array<s32, 4>& sample) -> std::array<s16, 2> { + std::transform( + current_frame.begin(), current_frame.end(), samples.begin(), current_frame.begin(), + [gain](const std::array<s16, 2>& accumulator, + const std::array<s32, 4>& sample) -> std::array<s16, 2> { // Downmix to stereo s16 left = ClampToS16(static_cast<s32>(gain * sample[0] + gain * sample[2])); s16 right = ClampToS16(static_cast<s32>(gain * sample[1] + gain * sample[3])); // Mix into current frame - return AddAndClampToS16(accumulator, { left, right }); + return AddAndClampToS16(accumulator, {left, right}); }); return; } @@ -135,12 +138,14 @@ void Mixers::DownmixAndMixIntoCurrentFrame(float gain, const QuadFrame32& sample } void Mixers::AuxReturn(const IntermediateMixSamples& read_samples) { - // NOTE: read_samples.mix{1,2}.pcm32 annoyingly have their dimensions in reverse order to QuadFrame32. + // NOTE: read_samples.mix{1,2}.pcm32 annoyingly have their dimensions in reverse order to + // QuadFrame32. if (state.mixer1_enabled) { for (size_t sample = 0; sample < samples_per_frame; sample++) { for (size_t channel = 0; channel < 4; channel++) { - state.intermediate_mix_buffer[1][sample][channel] = read_samples.mix1.pcm32[channel][sample]; + state.intermediate_mix_buffer[1][sample][channel] = + read_samples.mix1.pcm32[channel][sample]; } } } @@ -148,14 +153,17 @@ void Mixers::AuxReturn(const IntermediateMixSamples& read_samples) { if (state.mixer2_enabled) { for (size_t sample = 0; sample < samples_per_frame; sample++) { for (size_t channel = 0; channel < 4; channel++) { - state.intermediate_mix_buffer[2][sample][channel] = read_samples.mix2.pcm32[channel][sample]; + state.intermediate_mix_buffer[2][sample][channel] = + read_samples.mix2.pcm32[channel][sample]; } } } } -void Mixers::AuxSend(IntermediateMixSamples& write_samples, const std::array<QuadFrame32, 3>& input) { - // NOTE: read_samples.mix{1,2}.pcm32 annoyingly have their dimensions in reverse order to QuadFrame32. +void Mixers::AuxSend(IntermediateMixSamples& write_samples, + const std::array<QuadFrame32, 3>& input) { + // NOTE: read_samples.mix{1,2}.pcm32 annoyingly have their dimensions in reverse order to + // QuadFrame32. state.intermediate_mix_buffer[0] = input[0]; @@ -184,7 +192,8 @@ void Mixers::MixCurrentFrame() { current_frame.fill({}); for (size_t mix = 0; mix < 3; mix++) { - DownmixAndMixIntoCurrentFrame(state.intermediate_mixer_volume[mix], state.intermediate_mix_buffer[mix]); + DownmixAndMixIntoCurrentFrame(state.intermediate_mixer_volume[mix], + state.intermediate_mix_buffer[mix]); } // TODO(merry): Compressor. (We currently assume a disabled compressor.) diff --git a/src/audio_core/hle/mixers.h b/src/audio_core/hle/mixers.h index b52952eb5..bf4e865ae 100644 --- a/src/audio_core/hle/mixers.h +++ b/src/audio_core/hle/mixers.h @@ -5,7 +5,6 @@ #pragma once #include <array> - #include "audio_core/hle/common.h" #include "audio_core/hle/dsp.h" @@ -20,10 +19,8 @@ public: void Reset(); - DspStatus Tick(DspConfiguration& config, - const IntermediateMixSamples& read_samples, - IntermediateMixSamples& write_samples, - const std::array<QuadFrame32, 3>& input); + DspStatus Tick(DspConfiguration& config, const IntermediateMixSamples& read_samples, + IntermediateMixSamples& write_samples, const std::array<QuadFrame32, 3>& input); StereoFrame16 GetOutput() const { return current_frame; @@ -53,7 +50,8 @@ private: void AuxSend(IntermediateMixSamples& write_samples, const std::array<QuadFrame32, 3>& input); /// INTERNAL: Mix current_frame. void MixCurrentFrame(); - /// INTERNAL: Downmix from quadraphonic to stereo based on status.output_format and accumulate into current_frame. + /// INTERNAL: Downmix from quadraphonic to stereo based on status.output_format and accumulate + /// into current_frame. void DownmixAndMixIntoCurrentFrame(float gain, const QuadFrame32& samples); /// INTERNAL: Generate DspStatus based on internal state. DspStatus GetCurrentStatus() const; diff --git a/src/audio_core/hle/pipe.cpp b/src/audio_core/hle/pipe.cpp index 44dff1345..b472c81d8 100644 --- a/src/audio_core/hle/pipe.cpp +++ b/src/audio_core/hle/pipe.cpp @@ -4,14 +4,11 @@ #include <array> #include <vector> - #include "audio_core/hle/dsp.h" #include "audio_core/hle/pipe.h" - #include "common/assert.h" #include "common/common_types.h" #include "common/logging/log.h" - #include "core/hle/service/dsp_dsp.h" namespace DSP { @@ -44,8 +41,10 @@ std::vector<u8> PipeRead(DspPipe pipe_number, u32 length) { std::vector<u8>& data = pipe_data[pipe_index]; if (length > data.size()) { - LOG_WARNING(Audio_DSP, "pipe_number = %zu is out of data, application requested read of %u but %zu remain", - pipe_index, length, data.size()); + LOG_WARNING( + Audio_DSP, + "pipe_number = %zu is out of data, application requested read of %u but %zu remain", + pipe_index, length, data.size()); length = static_cast<u32>(data.size()); } @@ -95,7 +94,7 @@ static void AudioPipeWriteStructAddresses() { 0x8000 + offsetof(SharedMemory, unknown11) / 2, 0x8000 + offsetof(SharedMemory, unknown12) / 2, 0x8000 + offsetof(SharedMemory, unknown13) / 2, - 0x8000 + offsetof(SharedMemory, unknown14) / 2 + 0x8000 + offsetof(SharedMemory, unknown14) / 2, }; // Begin with a u16 denoting the number of structs. @@ -112,7 +111,8 @@ void PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer) { switch (pipe_number) { case DspPipe::Audio: { if (buffer.size() != 4) { - LOG_ERROR(Audio_DSP, "DspPipe::Audio: Unexpected buffer length %zu was written", buffer.size()); + LOG_ERROR(Audio_DSP, "DspPipe::Audio: Unexpected buffer length %zu was written", + buffer.size()); return; } @@ -120,7 +120,7 @@ void PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer) { Initalize = 0, Shutdown = 1, Wakeup = 2, - Sleep = 3 + Sleep = 3, }; // The difference between Initialize and Wakeup is that Input state is maintained @@ -152,7 +152,9 @@ void PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer) { dsp_state = DspState::Sleeping; break; default: - LOG_ERROR(Audio_DSP, "Application has requested unknown state transition of DSP hardware %hhu", buffer[0]); + LOG_ERROR(Audio_DSP, + "Application has requested unknown state transition of DSP hardware %hhu", + buffer[0]); dsp_state = DspState::Off; break; } @@ -160,7 +162,8 @@ void PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer) { return; } default: - LOG_CRITICAL(Audio_DSP, "pipe_number = %zu unimplemented", static_cast<size_t>(pipe_number)); + LOG_CRITICAL(Audio_DSP, "pipe_number = %zu unimplemented", + static_cast<size_t>(pipe_number)); UNIMPLEMENTED(); return; } diff --git a/src/audio_core/hle/pipe.h b/src/audio_core/hle/pipe.h index b714c0496..ac053c029 100644 --- a/src/audio_core/hle/pipe.h +++ b/src/audio_core/hle/pipe.h @@ -6,7 +6,6 @@ #include <cstddef> #include <vector> - #include "common/common_types.h" namespace DSP { @@ -19,16 +18,18 @@ enum class DspPipe { Debug = 0, Dma = 1, Audio = 2, - Binary = 3 + Binary = 3, }; constexpr size_t NUM_DSP_PIPE = 8; /** * Reads `length` bytes from the DSP pipe identified with `pipe_number`. * @note Can read up to the maximum value of a u16 in bytes (65,535). - * @note IF an error is encoutered with either an invalid `pipe_number` or `length` value, an empty vector will be returned. + * @note IF an error is encoutered with either an invalid `pipe_number` or `length` value, an empty + * vector will be returned. * @note IF `length` is set to 0, an empty vector will be returned. - * @note IF `length` is greater than the amount of data available, this function will only read the available amount. + * @note IF `length` is greater than the amount of data available, this function will only read the + * available amount. * @param pipe_number a `DspPipe` * @param length the number of bytes to read. The max is 65,535 (max of u16). * @returns a vector of bytes from the specified pipe. On error, will be empty. @@ -52,8 +53,9 @@ void PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer); enum class DspState { Off, On, - Sleeping + Sleeping, }; + /// Get the state of the DSP DspState GetDspState(); diff --git a/src/audio_core/hle/source.cpp b/src/audio_core/hle/source.cpp index 30552fe26..2bbf7146e 100644 --- a/src/audio_core/hle/source.cpp +++ b/src/audio_core/hle/source.cpp @@ -4,21 +4,19 @@ #include <algorithm> #include <array> - #include "audio_core/codec.h" #include "audio_core/hle/common.h" #include "audio_core/hle/source.h" #include "audio_core/interpolate.h" - #include "common/assert.h" #include "common/logging/log.h" - #include "core/memory.h" namespace DSP { namespace HLE { -SourceStatus::Status Source::Tick(SourceConfiguration::Configuration& config, const s16_le (&adpcm_coeffs)[16]) { +SourceStatus::Status Source::Tick(SourceConfiguration::Configuration& config, + const s16_le (&adpcm_coeffs)[16]) { ParseConfig(config, adpcm_coeffs); if (state.enabled) { @@ -47,7 +45,8 @@ void Source::Reset() { state = {}; } -void Source::ParseConfig(SourceConfiguration::Configuration& config, const s16_le (&adpcm_coeffs)[16]) { +void Source::ParseConfig(SourceConfiguration::Configuration& config, + const s16_le (&adpcm_coeffs)[16]) { if (!config.dirty_raw) { return; } @@ -82,7 +81,8 @@ void Source::ParseConfig(SourceConfiguration::Configuration& config, const s16_l LOG_TRACE(Audio_DSP, "source_id=%zu rate=%f", source_id, state.rate_multiplier); if (state.rate_multiplier <= 0) { - LOG_ERROR(Audio_DSP, "Was given an invalid rate multiplier: source_id=%zu rate=%f", source_id, state.rate_multiplier); + LOG_ERROR(Audio_DSP, "Was given an invalid rate multiplier: source_id=%zu rate=%f", + source_id, state.rate_multiplier); state.rate_multiplier = 1.0f; // Note: Actual firmware starts producing garbage if this occurs. } @@ -90,37 +90,39 @@ void Source::ParseConfig(SourceConfiguration::Configuration& config, const s16_l if (config.adpcm_coefficients_dirty) { config.adpcm_coefficients_dirty.Assign(0); - std::transform(adpcm_coeffs, adpcm_coeffs + state.adpcm_coeffs.size(), state.adpcm_coeffs.begin(), - [](const auto& coeff) { return static_cast<s16>(coeff); }); + std::transform(adpcm_coeffs, adpcm_coeffs + state.adpcm_coeffs.size(), + state.adpcm_coeffs.begin(), + [](const auto& coeff) { return static_cast<s16>(coeff); }); LOG_TRACE(Audio_DSP, "source_id=%zu adpcm update", source_id); } if (config.gain_0_dirty) { config.gain_0_dirty.Assign(0); std::transform(config.gain[0], config.gain[0] + state.gain[0].size(), state.gain[0].begin(), - [](const auto& coeff) { return static_cast<float>(coeff); }); + [](const auto& coeff) { return static_cast<float>(coeff); }); LOG_TRACE(Audio_DSP, "source_id=%zu gain 0 update", source_id); } if (config.gain_1_dirty) { config.gain_1_dirty.Assign(0); std::transform(config.gain[1], config.gain[1] + state.gain[1].size(), state.gain[1].begin(), - [](const auto& coeff) { return static_cast<float>(coeff); }); + [](const auto& coeff) { return static_cast<float>(coeff); }); LOG_TRACE(Audio_DSP, "source_id=%zu gain 1 update", source_id); } if (config.gain_2_dirty) { config.gain_2_dirty.Assign(0); std::transform(config.gain[2], config.gain[2] + state.gain[2].size(), state.gain[2].begin(), - [](const auto& coeff) { return static_cast<float>(coeff); }); + [](const auto& coeff) { return static_cast<float>(coeff); }); LOG_TRACE(Audio_DSP, "source_id=%zu gain 2 update", source_id); } if (config.filters_enabled_dirty) { config.filters_enabled_dirty.Assign(0); - state.filters.Enable(config.simple_filter_enabled.ToBool(), config.biquad_filter_enabled.ToBool()); - LOG_TRACE(Audio_DSP, "source_id=%zu enable_simple=%hu enable_biquad=%hu", - source_id, config.simple_filter_enabled.Value(), config.biquad_filter_enabled.Value()); + state.filters.Enable(config.simple_filter_enabled.ToBool(), + config.biquad_filter_enabled.ToBool()); + LOG_TRACE(Audio_DSP, "source_id=%zu enable_simple=%hu enable_biquad=%hu", source_id, + config.simple_filter_enabled.Value(), config.biquad_filter_enabled.Value()); } if (config.simple_filter_dirty) { @@ -138,19 +140,22 @@ void Source::ParseConfig(SourceConfiguration::Configuration& config, const s16_l if (config.interpolation_dirty) { config.interpolation_dirty.Assign(0); state.interpolation_mode = config.interpolation_mode; - LOG_TRACE(Audio_DSP, "source_id=%zu interpolation_mode=%zu", source_id, static_cast<size_t>(state.interpolation_mode)); + LOG_TRACE(Audio_DSP, "source_id=%zu interpolation_mode=%zu", source_id, + static_cast<size_t>(state.interpolation_mode)); } if (config.format_dirty || config.embedded_buffer_dirty) { config.format_dirty.Assign(0); state.format = config.format; - LOG_TRACE(Audio_DSP, "source_id=%zu format=%zu", source_id, static_cast<size_t>(state.format)); + LOG_TRACE(Audio_DSP, "source_id=%zu format=%zu", source_id, + static_cast<size_t>(state.format)); } if (config.mono_or_stereo_dirty || config.embedded_buffer_dirty) { config.mono_or_stereo_dirty.Assign(0); state.mono_or_stereo = config.mono_or_stereo; - LOG_TRACE(Audio_DSP, "source_id=%zu mono_or_stereo=%zu", source_id, static_cast<size_t>(state.mono_or_stereo)); + LOG_TRACE(Audio_DSP, "source_id=%zu mono_or_stereo=%zu", source_id, + static_cast<size_t>(state.mono_or_stereo)); } if (config.embedded_buffer_dirty) { @@ -159,15 +164,16 @@ void Source::ParseConfig(SourceConfiguration::Configuration& config, const s16_l config.physical_address, config.length, static_cast<u8>(config.adpcm_ps), - { config.adpcm_yn[0], config.adpcm_yn[1] }, + {config.adpcm_yn[0], config.adpcm_yn[1]}, config.adpcm_dirty.ToBool(), config.is_looping.ToBool(), config.buffer_id, state.mono_or_stereo, state.format, - false + false, }); - LOG_TRACE(Audio_DSP, "enqueuing embedded addr=0x%08x len=%u id=%hu", config.physical_address, config.length, config.buffer_id); + LOG_TRACE(Audio_DSP, "enqueuing embedded addr=0x%08x len=%u id=%hu", + config.physical_address, config.length, config.buffer_id); } if (config.buffer_queue_dirty) { @@ -179,15 +185,16 @@ void Source::ParseConfig(SourceConfiguration::Configuration& config, const s16_l b.physical_address, b.length, static_cast<u8>(b.adpcm_ps), - { b.adpcm_yn[0], b.adpcm_yn[1] }, + {b.adpcm_yn[0], b.adpcm_yn[1]}, b.adpcm_dirty != 0, b.is_looping != 0, b.buffer_id, state.mono_or_stereo, state.format, - true + true, }); - LOG_TRACE(Audio_DSP, "enqueuing queued %zu addr=0x%08x len=%u id=%hu", i, b.physical_address, b.length, b.buffer_id); + LOG_TRACE(Audio_DSP, "enqueuing queued %zu addr=0x%08x len=%u id=%hu", i, + b.physical_address, b.length, b.buffer_id); } } config.buffers_dirty = 0; @@ -218,10 +225,13 @@ void Source::GenerateFrame() { break; } - const size_t size_to_copy = std::min(state.current_buffer.size(), current_frame.size() - frame_position); + const size_t size_to_copy = + std::min(state.current_buffer.size(), current_frame.size() - frame_position); - std::copy(state.current_buffer.begin(), state.current_buffer.begin() + size_to_copy, current_frame.begin() + frame_position); - state.current_buffer.erase(state.current_buffer.begin(), state.current_buffer.begin() + size_to_copy); + std::copy(state.current_buffer.begin(), state.current_buffer.begin() + size_to_copy, + current_frame.begin() + frame_position); + state.current_buffer.erase(state.current_buffer.begin(), + state.current_buffer.begin() + size_to_copy); frame_position += size_to_copy; state.next_sample_number += static_cast<u32>(size_to_copy); @@ -230,9 +240,9 @@ void Source::GenerateFrame() { state.filters.ProcessFrame(current_frame); } - bool Source::DequeueBuffer() { - ASSERT_MSG(state.current_buffer.empty(), "Shouldn't dequeue; we still have data in current_buffer"); + ASSERT_MSG(state.current_buffer.empty(), + "Shouldn't dequeue; we still have data in current_buffer"); if (state.input_queue.empty()) return false; @@ -261,29 +271,34 @@ bool Source::DequeueBuffer() { break; case Format::ADPCM: DEBUG_ASSERT(num_channels == 1); - state.current_buffer = Codec::DecodeADPCM(memory, buf.length, state.adpcm_coeffs, state.adpcm_state); + state.current_buffer = + Codec::DecodeADPCM(memory, buf.length, state.adpcm_coeffs, state.adpcm_state); break; default: UNIMPLEMENTED(); break; } } else { - LOG_WARNING(Audio_DSP, "source_id=%zu buffer_id=%hu length=%u: Invalid physical address 0x%08X", - source_id, buf.buffer_id, buf.length, buf.physical_address); + LOG_WARNING(Audio_DSP, + "source_id=%zu buffer_id=%hu length=%u: Invalid physical address 0x%08X", + source_id, buf.buffer_id, buf.length, buf.physical_address); state.current_buffer.clear(); return true; } switch (state.interpolation_mode) { case InterpolationMode::None: - state.current_buffer = AudioInterp::None(state.interp_state, state.current_buffer, state.rate_multiplier); + state.current_buffer = + AudioInterp::None(state.interp_state, state.current_buffer, state.rate_multiplier); break; case InterpolationMode::Linear: - state.current_buffer = AudioInterp::Linear(state.interp_state, state.current_buffer, state.rate_multiplier); + state.current_buffer = + AudioInterp::Linear(state.interp_state, state.current_buffer, state.rate_multiplier); break; case InterpolationMode::Polyphase: // TODO(merry): Implement polyphase interpolation - state.current_buffer = AudioInterp::Linear(state.interp_state, state.current_buffer, state.rate_multiplier); + state.current_buffer = + AudioInterp::Linear(state.interp_state, state.current_buffer, state.rate_multiplier); break; default: UNIMPLEMENTED(); @@ -296,7 +311,8 @@ bool Source::DequeueBuffer() { state.buffer_update = buf.from_queue; LOG_TRACE(Audio_DSP, "source_id=%zu buffer_id=%hu from_queue=%s current_buffer.size()=%zu", - source_id, buf.buffer_id, buf.from_queue ? "true" : "false", state.current_buffer.size()); + source_id, buf.buffer_id, buf.from_queue ? "true" : "false", + state.current_buffer.size()); return true; } diff --git a/src/audio_core/hle/source.h b/src/audio_core/hle/source.h index 7ee08d424..3d725f2a3 100644 --- a/src/audio_core/hle/source.h +++ b/src/audio_core/hle/source.h @@ -7,13 +7,11 @@ #include <array> #include <queue> #include <vector> - #include "audio_core/codec.h" #include "audio_core/hle/common.h" #include "audio_core/hle/dsp.h" #include "audio_core/hle/filter.h" #include "audio_core/interpolate.h" - #include "common/common_types.h" namespace DSP { @@ -40,13 +38,17 @@ public: /** * This is called once every audio frame. This performs per-source processing every frame. * @param config The new configuration we've got for this Source from the application. - * @param adpcm_coeffs ADPCM coefficients to use if config tells us to use them (may contain invalid values otherwise). - * @return The current status of this Source. This is given back to the emulated application via SharedMemory. + * @param adpcm_coeffs ADPCM coefficients to use if config tells us to use them (may contain + * invalid values otherwise). + * @return The current status of this Source. This is given back to the emulated application via + * SharedMemory. */ - SourceStatus::Status Tick(SourceConfiguration::Configuration& config, const s16_le (&adpcm_coeffs)[16]); + SourceStatus::Status Tick(SourceConfiguration::Configuration& config, + const s16_le (&adpcm_coeffs)[16]); /** - * Mix this source's output into dest, using the gains for the `intermediate_mix_id`-th intermediate mixer. + * Mix this source's output into dest, using the gains for the `intermediate_mix_id`-th + * intermediate mixer. * @param dest The QuadFrame32 to mix into. * @param intermediate_mix_id The id of the intermediate mix whose gains we are using. */ @@ -77,7 +79,7 @@ private: }; struct BufferOrder { - bool operator() (const Buffer& a, const Buffer& b) const { + bool operator()(const Buffer& a, const Buffer& b) const { // Lower buffer_id comes first. return a.buffer_id > b.buffer_id; } @@ -134,7 +136,8 @@ private: void ParseConfig(SourceConfiguration::Configuration& config, const s16_le (&adpcm_coeffs)[16]); /// INTERNAL: Generate the current audio output for this frame based on our internal state. void GenerateFrame(); - /// INTERNAL: Dequeues a buffer and does preprocessing on it (decoding, resampling). Puts it into current_buffer. + /// INTERNAL: Dequeues a buffer and does preprocessing on it (decoding, resampling). Puts it + /// into current_buffer. bool DequeueBuffer(); /// INTERNAL: Generates a SourceStatus::Status based on our internal state. SourceStatus::Status GetCurrentStatus(); diff --git a/src/audio_core/interpolate.cpp b/src/audio_core/interpolate.cpp index fcd3aa066..8a5d4181a 100644 --- a/src/audio_core/interpolate.cpp +++ b/src/audio_core/interpolate.cpp @@ -3,7 +3,6 @@ // Refer to the license.txt file included. #include "audio_core/interpolate.h" - #include "common/assert.h" #include "common/math_util.h" @@ -17,7 +16,8 @@ constexpr u64 scale_mask = scale_factor - 1; /// Here we step over the input in steps of rate_multiplier, until we consume all of the input. /// Three adjacent samples are passed to fn each step. template <typename Function> -static StereoBuffer16 StepOverSamples(State& state, const StereoBuffer16& input, float rate_multiplier, Function fn) { +static StereoBuffer16 StepOverSamples(State& state, const StereoBuffer16& input, + float rate_multiplier, Function fn) { ASSERT(rate_multiplier > 0); if (input.size() < 2) @@ -63,23 +63,24 @@ static StereoBuffer16 StepOverSamples(State& state, const StereoBuffer16& input, } StereoBuffer16 None(State& state, const StereoBuffer16& input, float rate_multiplier) { - return StepOverSamples(state, input, rate_multiplier, [](u64 fraction, const auto& x0, const auto& x1, const auto& x2) { - return x0; - }); + return StepOverSamples( + state, input, rate_multiplier, + [](u64 fraction, const auto& x0, const auto& x1, const auto& x2) { return x0; }); } StereoBuffer16 Linear(State& state, const StereoBuffer16& input, float rate_multiplier) { // Note on accuracy: Some values that this produces are +/- 1 from the actual firmware. - return StepOverSamples(state, input, rate_multiplier, [](u64 fraction, const auto& x0, const auto& x1, const auto& x2) { - // This is a saturated subtraction. (Verified by black-box fuzzing.) - s64 delta0 = MathUtil::Clamp<s64>(x1[0] - x0[0], -32768, 32767); - s64 delta1 = MathUtil::Clamp<s64>(x1[1] - x0[1], -32768, 32767); - - return std::array<s16, 2> { - static_cast<s16>(x0[0] + fraction * delta0 / scale_factor), - static_cast<s16>(x0[1] + fraction * delta1 / scale_factor) - }; - }); + return StepOverSamples(state, input, rate_multiplier, + [](u64 fraction, const auto& x0, const auto& x1, const auto& x2) { + // This is a saturated subtraction. (Verified by black-box fuzzing.) + s64 delta0 = MathUtil::Clamp<s64>(x1[0] - x0[0], -32768, 32767); + s64 delta1 = MathUtil::Clamp<s64>(x1[1] - x0[1], -32768, 32767); + + return std::array<s16, 2>{ + static_cast<s16>(x0[0] + fraction * delta0 / scale_factor), + static_cast<s16>(x0[1] + fraction * delta1 / scale_factor), + }; + }); } } // namespace AudioInterp diff --git a/src/audio_core/interpolate.h b/src/audio_core/interpolate.h index a4c0a453d..dd06fdda9 100644 --- a/src/audio_core/interpolate.h +++ b/src/audio_core/interpolate.h @@ -6,7 +6,6 @@ #include <array> #include <vector> - #include "common/common_types.h" namespace AudioInterp { @@ -24,7 +23,8 @@ struct State { * No interpolation. This is equivalent to a zero-order hold. There is a two-sample predelay. * @param input Input buffer. * @param rate_multiplier Stretch factor. Must be a positive non-zero value. - * rate_multiplier > 1.0 performs decimation and rate_multipler < 1.0 performs upsampling. + * rate_multiplier > 1.0 performs decimation and rate_multipler < 1.0 + * performs upsampling. * @return The resampled audio buffer. */ StereoBuffer16 None(State& state, const StereoBuffer16& input, float rate_multiplier); @@ -33,7 +33,8 @@ StereoBuffer16 None(State& state, const StereoBuffer16& input, float rate_multip * Linear interpolation. This is equivalent to a first-order hold. There is a two-sample predelay. * @param input Input buffer. * @param rate_multiplier Stretch factor. Must be a positive non-zero value. - * rate_multiplier > 1.0 performs decimation and rate_multipler < 1.0 performs upsampling. + * rate_multiplier > 1.0 performs decimation and rate_multipler < 1.0 + * performs upsampling. * @return The resampled audio buffer. */ StereoBuffer16 Linear(State& state, const StereoBuffer16& input, float rate_multiplier); diff --git a/src/audio_core/null_sink.h b/src/audio_core/null_sink.h index 9931c4778..e7668438c 100644 --- a/src/audio_core/null_sink.h +++ b/src/audio_core/null_sink.h @@ -5,7 +5,6 @@ #pragma once #include <cstddef> - #include "audio_core/audio_core.h" #include "audio_core/sink.h" diff --git a/src/audio_core/sdl2_sink.cpp b/src/audio_core/sdl2_sink.cpp index 1d7912715..75cc0d6dd 100644 --- a/src/audio_core/sdl2_sink.cpp +++ b/src/audio_core/sdl2_sink.cpp @@ -3,16 +3,13 @@ // Refer to the license.txt file included. #include <list> +#include <numeric> #include <vector> - #include <SDL.h> - #include "audio_core/audio_core.h" #include "audio_core/sdl2_sink.h" - #include "common/assert.h" #include "common/logging/log.h" -#include <numeric> namespace AudioCore { @@ -45,7 +42,8 @@ SDL2Sink::SDL2Sink() : impl(std::make_unique<Impl>()) { SDL_AudioSpec obtained_audiospec; SDL_zero(obtained_audiospec); - impl->audio_device_id = SDL_OpenAudioDevice(nullptr, false, &desired_audiospec, &obtained_audiospec, 0); + impl->audio_device_id = + SDL_OpenAudioDevice(nullptr, false, &desired_audiospec, &obtained_audiospec, 0); if (impl->audio_device_id <= 0) { LOG_CRITICAL(Audio_Sink, "SDL_OpenAudioDevice failed"); return; @@ -86,11 +84,12 @@ size_t SDL2Sink::SamplesInQueue() const { SDL_LockAudioDevice(impl->audio_device_id); - size_t total_size = std::accumulate(impl->queue.begin(), impl->queue.end(), static_cast<size_t>(0), - [](size_t sum, const auto& buffer) { - // Division by two because each stereo sample is made of two s16. - return sum + buffer.size() / 2; - }); + size_t total_size = std::accumulate(impl->queue.begin(), impl->queue.end(), + static_cast<size_t>(0), [](size_t sum, const auto& buffer) { + // Division by two because each stereo sample is made of + // two s16. + return sum + buffer.size() / 2; + }); SDL_UnlockAudioDevice(impl->audio_device_id); @@ -100,7 +99,8 @@ size_t SDL2Sink::SamplesInQueue() const { void SDL2Sink::Impl::Callback(void* impl_, u8* buffer, int buffer_size_in_bytes) { Impl* impl = reinterpret_cast<Impl*>(impl_); - size_t remaining_size = static_cast<size_t>(buffer_size_in_bytes) / sizeof(s16); // Keep track of size in 16-bit increments. + size_t remaining_size = static_cast<size_t>(buffer_size_in_bytes) / + sizeof(s16); // Keep track of size in 16-bit increments. while (remaining_size > 0 && !impl->queue.empty()) { if (impl->queue.front().size() <= remaining_size) { @@ -111,7 +111,8 @@ void SDL2Sink::Impl::Callback(void* impl_, u8* buffer, int buffer_size_in_bytes) } else { memcpy(buffer, impl->queue.front().data(), remaining_size * sizeof(s16)); buffer += remaining_size * sizeof(s16); - impl->queue.front().erase(impl->queue.front().begin(), impl->queue.front().begin() + remaining_size); + impl->queue.front().erase(impl->queue.front().begin(), + impl->queue.front().begin() + remaining_size); remaining_size = 0; } } diff --git a/src/audio_core/sdl2_sink.h b/src/audio_core/sdl2_sink.h index b13827214..ccd0f7c7e 100644 --- a/src/audio_core/sdl2_sink.h +++ b/src/audio_core/sdl2_sink.h @@ -6,7 +6,6 @@ #include <cstddef> #include <memory> - #include "audio_core/sink.h" namespace AudioCore { diff --git a/src/audio_core/sink.h b/src/audio_core/sink.h index a06fc3dcc..08f3bab5b 100644 --- a/src/audio_core/sink.h +++ b/src/audio_core/sink.h @@ -5,20 +5,21 @@ #pragma once #include <vector> - #include "common/common_types.h" namespace AudioCore { /** - * This class is an interface for an audio sink. An audio sink accepts samples in stereo signed PCM16 format to be output. - * Sinks *do not* handle resampling and expect the correct sample rate. They are dumb outputs. + * This class is an interface for an audio sink. An audio sink accepts samples in stereo signed + * PCM16 format to be output. Sinks *do not* handle resampling and expect the correct sample rate. + * They are dumb outputs. */ class Sink { public: virtual ~Sink() = default; - /// The native rate of this sink. The sink expects to be fed samples that respect this. (Units: samples/sec) + /// The native rate of this sink. The sink expects to be fed samples that respect this. (Units: + /// samples/sec) virtual unsigned int GetNativeSampleRate() const = 0; /** diff --git a/src/audio_core/sink_details.cpp b/src/audio_core/sink_details.cpp index ba5e83d17..95ccc9e9d 100644 --- a/src/audio_core/sink_details.cpp +++ b/src/audio_core/sink_details.cpp @@ -4,10 +4,8 @@ #include <memory> #include <vector> - #include "audio_core/null_sink.h" #include "audio_core/sink_details.h" - #ifdef HAVE_SDL2 #include "audio_core/sdl2_sink.h" #endif @@ -17,9 +15,9 @@ namespace AudioCore { // g_sink_details is ordered in terms of desirability, with the best choice at the top. const std::vector<SinkDetails> g_sink_details = { #ifdef HAVE_SDL2 - { "sdl2", []() { return std::make_unique<SDL2Sink>(); } }, + {"sdl2", []() { return std::make_unique<SDL2Sink>(); }}, #endif - { "null", []() { return std::make_unique<NullSink>(); } }, + {"null", []() { return std::make_unique<NullSink>(); }}, }; } // namespace AudioCore diff --git a/src/audio_core/time_stretch.cpp b/src/audio_core/time_stretch.cpp index ea38f40d0..53cb64655 100644 --- a/src/audio_core/time_stretch.cpp +++ b/src/audio_core/time_stretch.cpp @@ -5,12 +5,9 @@ #include <chrono> #include <cmath> #include <vector> - #include <SoundTouch.h> - #include "audio_core/audio_core.h" #include "audio_core/time_stretch.h" - #include "common/common_types.h" #include "common/logging/log.h" #include "common/math_util.h" @@ -26,8 +23,8 @@ static double ClampRatio(double ratio) { return MathUtil::Clamp(ratio, MIN_RATIO, MAX_RATIO); } -constexpr double MIN_DELAY_TIME = 0.05; // Units: seconds -constexpr double MAX_DELAY_TIME = 0.25; // Units: seconds +constexpr double MIN_DELAY_TIME = 0.05; // Units: seconds +constexpr double MAX_DELAY_TIME = 0.25; // Units: seconds constexpr size_t DROP_FRAMES_SAMPLE_DELAY = 16000; // Units: samples constexpr double SMOOTHING_FACTOR = 0.007; @@ -48,7 +45,8 @@ std::vector<s16> TimeStretcher::Process(size_t samples_in_queue) { double ratio = CalculateCurrentRatio(); ratio = CorrectForUnderAndOverflow(ratio, samples_in_queue); - impl->smoothed_ratio = (1.0 - SMOOTHING_FACTOR) * impl->smoothed_ratio + SMOOTHING_FACTOR * ratio; + impl->smoothed_ratio = + (1.0 - SMOOTHING_FACTOR) * impl->smoothed_ratio + SMOOTHING_FACTOR * ratio; impl->smoothed_ratio = ClampRatio(impl->smoothed_ratio); // SoundTouch's tempo definition the inverse of our ratio definition. @@ -100,7 +98,8 @@ double TimeStretcher::CalculateCurrentRatio() { const steady_clock::time_point now = steady_clock::now(); const std::chrono::duration<double> duration = now - impl->frame_timer; - const double expected_time = static_cast<double>(impl->samples_queued) / static_cast<double>(native_sample_rate); + const double expected_time = + static_cast<double>(impl->samples_queued) / static_cast<double>(native_sample_rate); const double actual_time = duration.count(); double ratio; diff --git a/src/audio_core/time_stretch.h b/src/audio_core/time_stretch.h index 1fde3f72a..fa81718ed 100644 --- a/src/audio_core/time_stretch.h +++ b/src/audio_core/time_stretch.h @@ -5,7 +5,6 @@ #include <cstddef> #include <memory> #include <vector> - #include "common/common_types.h" namespace AudioCore { @@ -37,7 +36,8 @@ public: /** * Does audio stretching and produces the time-stretched samples. * Timer calculations use sample_delay to determine how much of a margin we have. - * @param sample_delay How many samples are buffered downstream of this module and haven't been played yet. + * @param sample_delay How many samples are buffered downstream of this module and haven't been + * played yet. * @return Samples to play in interleaved stereo PCM16 format. */ std::vector<s16> Process(size_t sample_delay); @@ -48,7 +48,8 @@ private: /// INTERNAL: ratio = wallclock time / emulated time double CalculateCurrentRatio(); - /// INTERNAL: If we have too many or too few samples downstream, nudge ratio in the appropriate direction. + /// INTERNAL: If we have too many or too few samples downstream, nudge ratio in the appropriate + /// direction. double CorrectForUnderAndOverflow(double ratio, size_t sample_delay) const; /// INTERNAL: Gets the time-stretched samples from SoundTouch. std::vector<s16> GetSamples(); diff --git a/src/citra/citra.cpp b/src/citra/citra.cpp index 128b9a16d..e47375f88 100644 --- a/src/citra/citra.cpp +++ b/src/citra/citra.cpp @@ -2,10 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include <string> -#include <thread> #include <iostream> #include <memory> +#include <string> +#include <thread> // This needs to be included before getopt.h because the latter #defines symbols used by it #include "common/microprofile.h" @@ -13,53 +13,48 @@ #ifdef _MSC_VER #include <getopt.h> #else -#include <unistd.h> #include <getopt.h> +#include <unistd.h> #endif #ifdef _WIN32 #include <Windows.h> #endif -#include "common/logging/log.h" +#include "citra/config.h" +#include "citra/emu_window/emu_window_sdl2.h" #include "common/logging/backend.h" #include "common/logging/filter.h" +#include "common/logging/log.h" #include "common/scm_rev.h" #include "common/scope_exit.h" #include "common/string_util.h" - -#include "core/settings.h" -#include "core/system.h" #include "core/core.h" #include "core/gdbstub/gdbstub.h" #include "core/loader/loader.h" - -#include "citra/config.h" -#include "citra/emu_window/emu_window_sdl2.h" - +#include "core/settings.h" +#include "core/system.h" #include "video_core/video_core.h" - -static void PrintHelp(const char *argv0) -{ - std::cout << "Usage: " << argv0 << " [options] <filename>\n" +static void PrintHelp(const char* argv0) { + std::cout << "Usage: " << argv0 + << " [options] <filename>\n" "-g, --gdbport=NUMBER Enable gdb stub on port NUMBER\n" "-h, --help Display this help and exit\n" "-v, --version Output version information and exit\n"; } -static void PrintVersion() -{ +static void PrintVersion() { std::cout << "Citra " << Common::g_scm_branch << " " << Common::g_scm_desc << std::endl; } /// Application entry point -int main(int argc, char **argv) { +int main(int argc, char** argv) { Config config; int option_index = 0; bool use_gdbstub = Settings::values.use_gdbstub; u32 gdb_port = static_cast<u32>(Settings::values.gdbstub_port); - char *endarg; + char* endarg; #ifdef _WIN32 int argc_w; auto argv_w = CommandLineToArgvW(GetCommandLineW(), &argc_w); @@ -72,10 +67,10 @@ int main(int argc, char **argv) { std::string boot_filename; static struct option long_options[] = { - { "gdbport", required_argument, 0, 'g' }, - { "help", no_argument, 0, 'h' }, - { "version", no_argument, 0, 'v' }, - { 0, 0, 0, 0 } + {"gdbport", required_argument, 0, 'g'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'v'}, + {0, 0, 0, 0}, }; while (optind < argc) { @@ -86,7 +81,8 @@ int main(int argc, char **argv) { errno = 0; gdb_port = strtoul(optarg, &endarg, 0); use_gdbstub = true; - if (endarg == optarg) errno = EINVAL; + if (endarg == optarg) + errno = EINVAL; if (errno != 0) { perror("--gdbport"); exit(1); diff --git a/src/citra/config.cpp b/src/citra/config.cpp index 1a09f0e55..05eabfa3d 100644 --- a/src/citra/config.cpp +++ b/src/citra/config.cpp @@ -3,19 +3,13 @@ // Refer to the license.txt file included. #include <memory> - -#include <inih/cpp/INIReader.h> - #include <SDL.h> - +#include <inih/cpp/INIReader.h> #include "citra/default_ini.h" - #include "common/file_util.h" #include "common/logging/log.h" - -#include "core/settings.h" - #include "config.h" +#include "core/settings.h" Config::Config() { // TODO: Don't hardcode the path; let the frontend decide where to put the config files. @@ -45,15 +39,13 @@ bool Config::LoadINI(const std::string& default_contents, bool retry) { static const std::array<int, Settings::NativeInput::NUM_INPUTS> defaults = { // directly mapped keys - SDL_SCANCODE_A, SDL_SCANCODE_S, SDL_SCANCODE_Z, SDL_SCANCODE_X, - SDL_SCANCODE_Q, SDL_SCANCODE_W, SDL_SCANCODE_1, SDL_SCANCODE_2, - SDL_SCANCODE_M, SDL_SCANCODE_N, SDL_SCANCODE_B, - SDL_SCANCODE_T, SDL_SCANCODE_G, SDL_SCANCODE_F, SDL_SCANCODE_H, - SDL_SCANCODE_I, SDL_SCANCODE_K, SDL_SCANCODE_J, SDL_SCANCODE_L, + SDL_SCANCODE_A, SDL_SCANCODE_S, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_Q, SDL_SCANCODE_W, + SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_M, SDL_SCANCODE_N, SDL_SCANCODE_B, SDL_SCANCODE_T, + SDL_SCANCODE_G, SDL_SCANCODE_F, SDL_SCANCODE_H, SDL_SCANCODE_I, SDL_SCANCODE_K, SDL_SCANCODE_J, + SDL_SCANCODE_L, // indirectly mapped keys - SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, - SDL_SCANCODE_D, + SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_D, }; void Config::ReadValues() { @@ -62,7 +54,8 @@ void Config::ReadValues() { Settings::values.input_mappings[Settings::NativeInput::All[i]] = sdl2_config->GetInteger("Controls", Settings::NativeInput::Mapping[i], defaults[i]); } - Settings::values.pad_circle_modifier_scale = (float)sdl2_config->GetReal("Controls", "pad_circle_modifier_scale", 0.5); + Settings::values.pad_circle_modifier_scale = + (float)sdl2_config->GetReal("Controls", "pad_circle_modifier_scale", 0.5); // Core Settings::values.use_cpu_jit = sdl2_config->GetBoolean("Core", "use_cpu_jit", true); @@ -71,19 +64,22 @@ void Config::ReadValues() { // Renderer Settings::values.use_hw_renderer = sdl2_config->GetBoolean("Renderer", "use_hw_renderer", true); Settings::values.use_shader_jit = sdl2_config->GetBoolean("Renderer", "use_shader_jit", true); - Settings::values.use_scaled_resolution = sdl2_config->GetBoolean("Renderer", "use_scaled_resolution", false); + Settings::values.use_scaled_resolution = + sdl2_config->GetBoolean("Renderer", "use_scaled_resolution", false); Settings::values.use_vsync = sdl2_config->GetBoolean("Renderer", "use_vsync", false); - Settings::values.bg_red = (float)sdl2_config->GetReal("Renderer", "bg_red", 1.0); + Settings::values.bg_red = (float)sdl2_config->GetReal("Renderer", "bg_red", 1.0); Settings::values.bg_green = (float)sdl2_config->GetReal("Renderer", "bg_green", 1.0); - Settings::values.bg_blue = (float)sdl2_config->GetReal("Renderer", "bg_blue", 1.0); + Settings::values.bg_blue = (float)sdl2_config->GetReal("Renderer", "bg_blue", 1.0); // Audio Settings::values.sink_id = sdl2_config->Get("Audio", "output_engine", "auto"); - Settings::values.enable_audio_stretching = sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true); + Settings::values.enable_audio_stretching = + sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true); // Data Storage - Settings::values.use_virtual_sd = sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true); + Settings::values.use_virtual_sd = + sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true); // System Settings::values.is_new_3ds = sdl2_config->GetBoolean("System", "is_new_3ds", false); @@ -94,7 +90,8 @@ void Config::ReadValues() { // Debugging Settings::values.use_gdbstub = sdl2_config->GetBoolean("Debugging", "use_gdbstub", false); - Settings::values.gdbstub_port = static_cast<u16>(sdl2_config->GetInteger("Debugging", "gdbstub_port", 24689)); + Settings::values.gdbstub_port = + static_cast<u16>(sdl2_config->GetInteger("Debugging", "gdbstub_port", 24689)); } void Config::Reload() { diff --git a/src/citra/config.h b/src/citra/config.h index 52a478146..b1c31f59c 100644 --- a/src/citra/config.h +++ b/src/citra/config.h @@ -6,15 +6,15 @@ #include <memory> #include <string> - #include <inih/cpp/INIReader.h> class Config { std::unique_ptr<INIReader> sdl2_config; std::string sdl2_config_loc; - bool LoadINI(const std::string& default_contents="", bool retry=true); + bool LoadINI(const std::string& default_contents = "", bool retry = true); void ReadValues(); + public: Config(); diff --git a/src/citra/default_ini.h b/src/citra/default_ini.h index 788174508..0b49e0230 100644 --- a/src/citra/default_ini.h +++ b/src/citra/default_ini.h @@ -104,5 +104,4 @@ log_filter = *:Info use_gdbstub=false gdbstub_port=24689 )"; - } diff --git a/src/citra/emu_window/emu_window_sdl2.cpp b/src/citra/emu_window/emu_window_sdl2.cpp index da12307b7..7df054208 100644 --- a/src/citra/emu_window/emu_window_sdl2.cpp +++ b/src/citra/emu_window/emu_window_sdl2.cpp @@ -5,22 +5,16 @@ #include <algorithm> #include <cstdlib> #include <string> - #define SDL_MAIN_HANDLED #include <SDL.h> - #include <glad/glad.h> - +#include "citra/emu_window/emu_window_sdl2.h" #include "common/key_map.h" #include "common/logging/log.h" #include "common/scm_rev.h" #include "common/string_util.h" - -#include "core/settings.h" #include "core/hle/service/hid/hid.h" - -#include "citra/emu_window/emu_window_sdl2.h" - +#include "core/settings.h" #include "video_core/video_core.h" void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { @@ -40,9 +34,9 @@ void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) { void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) { if (state == SDL_PRESSED) { - KeyMap::PressKey(*this, { key, keyboard_id }); + KeyMap::PressKey(*this, {key, keyboard_id}); } else if (state == SDL_RELEASED) { - KeyMap::ReleaseKey(*this, { key, keyboard_id }); + KeyMap::ReleaseKey(*this, {key, keyboard_id}); } } @@ -55,7 +49,8 @@ void EmuWindow_SDL2::OnResize() { SDL_GetWindowSize(render_window, &width, &height); - NotifyFramebufferLayoutChanged(EmuWindow::FramebufferLayout::DefaultScreenLayout(width, height)); + NotifyFramebufferLayoutChanged( + EmuWindow::FramebufferLayout::DefaultScreenLayout(width, height)); } EmuWindow_SDL2::EmuWindow_SDL2() { @@ -80,12 +75,13 @@ EmuWindow_SDL2::EmuWindow_SDL2() { SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0); - std::string window_title = Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); - render_window = SDL_CreateWindow(window_title.c_str(), + std::string window_title = + Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); + render_window = SDL_CreateWindow( + window_title.c_str(), SDL_WINDOWPOS_UNDEFINED, // x position SDL_WINDOWPOS_UNDEFINED, // y position - VideoCore::kScreenTopWidth, - VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight, + VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); if (render_window == nullptr) { @@ -171,10 +167,14 @@ void EmuWindow_SDL2::DoneCurrent() { void EmuWindow_SDL2::ReloadSetKeymaps() { KeyMap::ClearKeyMapping(keyboard_id); for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { - KeyMap::SetKeyMapping({ Settings::values.input_mappings[Settings::NativeInput::All[i]], keyboard_id }, KeyMap::mapping_targets[i]); + KeyMap::SetKeyMapping( + {Settings::values.input_mappings[Settings::NativeInput::All[i]], keyboard_id}, + KeyMap::mapping_targets[i]); } } -void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest(const std::pair<unsigned, unsigned>& minimal_size) { +void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest( + const std::pair<unsigned, unsigned>& minimal_size) { + SDL_SetWindowMinimumSize(render_window, minimal_size.first, minimal_size.second); } diff --git a/src/citra/emu_window/emu_window_sdl2.h b/src/citra/emu_window/emu_window_sdl2.h index 77279f022..e4d14ef12 100644 --- a/src/citra/emu_window/emu_window_sdl2.h +++ b/src/citra/emu_window/emu_window_sdl2.h @@ -5,7 +5,6 @@ #pragma once #include <utility> - #include "common/emu_window.h" struct SDL_Window; @@ -47,7 +46,8 @@ private: void OnResize(); /// Called when a configuration change affects the minimal size of the window - void OnMinimalClientAreaChangeRequest(const std::pair<unsigned, unsigned>& minimal_size) override; + void OnMinimalClientAreaChangeRequest( + const std::pair<unsigned, unsigned>& minimal_size) override; /// Is the window still open? bool is_open = true; @@ -55,7 +55,7 @@ private: /// Internal SDL2 render window SDL_Window* render_window; - using SDL_GLContext = void *; + using SDL_GLContext = void*; /// The OpenGL context associated with the window SDL_GLContext gl_context; diff --git a/src/citra/resource.h b/src/citra/resource.h index 127896424..df8e459e4 100644 --- a/src/citra/resource.h +++ b/src/citra/resource.h @@ -2,15 +2,15 @@ // Microsoft Visual C++ generated include file. // Used by pcafe.rc // -#define IDI_ICON3 103 +#define IDI_ICON3 103 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 105 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 +#define _APS_NEXT_RESOURCE_VALUE 105 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 6dddde9ba..0abae86c3 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -9,27 +9,23 @@ #endif #include "citra_qt/bootmanager.h" - #include "common/key_map.h" #include "common/microprofile.h" #include "common/scm_rev.h" #include "common/string_util.h" - #include "core/core.h" #include "core/settings.h" #include "core/system.h" - #include "video_core/debug_utils/debug_utils.h" #include "video_core/video_core.h" -#define APP_NAME "citra" -#define APP_VERSION "0.1-" VERSION -#define APP_TITLE APP_NAME " " APP_VERSION -#define COPYRIGHT "Copyright (C) 2013-2014 Citra Team" +#define APP_NAME "citra" +#define APP_VERSION "0.1-" VERSION +#define APP_TITLE APP_NAME " " APP_VERSION +#define COPYRIGHT "Copyright (C) 2013-2014 Citra Team" -EmuThread::EmuThread(GRenderWindow* render_window) : - exec_step(false), running(false), stop_run(false), render_window(render_window) { -} +EmuThread::EmuThread(GRenderWindow* render_window) + : exec_step(false), running(false), stop_run(false), render_window(render_window) {} void EmuThread::run() { render_window->MakeCurrent(); @@ -64,7 +60,7 @@ void EmuThread::run() { was_active = false; } else { std::unique_lock<std::mutex> lock(running_mutex); - running_cv.wait(lock, [this]{ return IsRunning() || exec_step || stop_run; }); + running_cv.wait(lock, [this] { return IsRunning() || exec_step || stop_run; }); } } @@ -78,14 +74,13 @@ void EmuThread::run() { render_window->moveContext(); } -// This class overrides paintEvent and resizeEvent to prevent the GUI thread from stealing GL context. +// This class overrides paintEvent and resizeEvent to prevent the GUI thread from stealing GL +// context. // The corresponding functionality is handled in EmuThread instead -class GGLWidgetInternal : public QGLWidget -{ +class GGLWidgetInternal : public QGLWidget { public: GGLWidgetInternal(QGLFormat fmt, GRenderWindow* parent) - : QGLWidget(fmt, parent), parent(parent) { - } + : QGLWidget(fmt, parent), parent(parent) {} void paintEvent(QPaintEvent* ev) override { if (do_painting) { @@ -98,37 +93,43 @@ public: parent->OnFramebufferSizeChanged(); } - void DisablePainting() { do_painting = false; } - void EnablePainting() { do_painting = true; } + void DisablePainting() { + do_painting = false; + } + void EnablePainting() { + do_painting = true; + } private: GRenderWindow* parent; bool do_painting; }; -GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread) : - QWidget(parent), keyboard_id(0), emu_thread(emu_thread), child(nullptr) { +GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread) + : QWidget(parent), keyboard_id(0), emu_thread(emu_thread), child(nullptr) { - std::string window_title = Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); + std::string window_title = + Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); setWindowTitle(QString::fromStdString(window_title)); keyboard_id = KeyMap::NewDeviceId(); ReloadSetKeymaps(); } -void GRenderWindow::moveContext() -{ +void GRenderWindow::moveContext() { DoneCurrent(); - // We need to move GL context to the swapping thread in Qt5 +// We need to move GL context to the swapping thread in Qt5 #if QT_VERSION > QT_VERSION_CHECK(5, 0, 0) - // If the thread started running, move the GL Context to the new thread. Otherwise, move it back. - auto thread = (QThread::currentThread() == qApp->thread() && emu_thread != nullptr) ? emu_thread : qApp->thread(); + // If the thread started running, move the GL Context to the new thread. Otherwise, move it + // back. + auto thread = (QThread::currentThread() == qApp->thread() && emu_thread != nullptr) + ? emu_thread + : qApp->thread(); child->context()->moveToThread(thread); #endif } -void GRenderWindow::SwapBuffers() -{ +void GRenderWindow::SwapBuffers() { #if !defined(QT_NO_DEBUG) // Qt debug runtime prints a bogus warning on the console if you haven't called makeCurrent // since the last time you called swapBuffers. This presumably means something if you're using @@ -139,54 +140,48 @@ void GRenderWindow::SwapBuffers() child->swapBuffers(); } -void GRenderWindow::MakeCurrent() -{ +void GRenderWindow::MakeCurrent() { child->makeCurrent(); } -void GRenderWindow::DoneCurrent() -{ +void GRenderWindow::DoneCurrent() { child->doneCurrent(); } -void GRenderWindow::PollEvents() { -} +void GRenderWindow::PollEvents() {} // On Qt 5.0+, this correctly gets the size of the framebuffer (pixels). // // Older versions get the window size (density independent pixels), // and hence, do not support DPI scaling ("retina" displays). // The result will be a viewport that is smaller than the extent of the window. -void GRenderWindow::OnFramebufferSizeChanged() -{ - // Screen changes potentially incur a change in screen DPI, hence we should update the framebuffer size +void GRenderWindow::OnFramebufferSizeChanged() { + // Screen changes potentially incur a change in screen DPI, hence we should update the + // framebuffer size qreal pixelRatio = windowPixelRatio(); unsigned width = child->QPaintDevice::width() * pixelRatio; unsigned height = child->QPaintDevice::height() * pixelRatio; - NotifyFramebufferLayoutChanged(EmuWindow::FramebufferLayout::DefaultScreenLayout(width, height)); + NotifyFramebufferLayoutChanged( + EmuWindow::FramebufferLayout::DefaultScreenLayout(width, height)); } -void GRenderWindow::BackupGeometry() -{ +void GRenderWindow::BackupGeometry() { geometry = ((QGLWidget*)this)->saveGeometry(); } -void GRenderWindow::RestoreGeometry() -{ +void GRenderWindow::RestoreGeometry() { // We don't want to back up the geometry here (obviously) QWidget::restoreGeometry(geometry); } -void GRenderWindow::restoreGeometry(const QByteArray& geometry) -{ +void GRenderWindow::restoreGeometry(const QByteArray& geometry) { // Make sure users of this class don't need to deal with backing up the geometry themselves QWidget::restoreGeometry(geometry); BackupGeometry(); } -QByteArray GRenderWindow::saveGeometry() -{ +QByteArray GRenderWindow::saveGeometry() { // If we are a top-level widget, store the current geometry // otherwise, store the last backup if (parent() == nullptr) @@ -195,8 +190,7 @@ QByteArray GRenderWindow::saveGeometry() return geometry; } -qreal GRenderWindow::windowPixelRatio() -{ +qreal GRenderWindow::windowPixelRatio() { #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) // windowHandle() might not be accessible until the window is displayed to screen. return windowHandle() ? windowHandle()->screen()->devicePixelRatio() : 1.0f; @@ -210,20 +204,16 @@ void GRenderWindow::closeEvent(QCloseEvent* event) { QWidget::closeEvent(event); } -void GRenderWindow::keyPressEvent(QKeyEvent* event) -{ - KeyMap::PressKey(*this, { event->key(), keyboard_id }); +void GRenderWindow::keyPressEvent(QKeyEvent* event) { + KeyMap::PressKey(*this, {event->key(), keyboard_id}); } -void GRenderWindow::keyReleaseEvent(QKeyEvent* event) -{ - KeyMap::ReleaseKey(*this, { event->key(), keyboard_id }); +void GRenderWindow::keyReleaseEvent(QKeyEvent* event) { + KeyMap::ReleaseKey(*this, {event->key(), keyboard_id}); } -void GRenderWindow::mousePressEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) - { +void GRenderWindow::mousePressEvent(QMouseEvent* event) { + if (event->button() == Qt::LeftButton) { auto pos = event->pos(); qreal pixelRatio = windowPixelRatio(); this->TouchPressed(static_cast<unsigned>(pos.x() * pixelRatio), @@ -231,30 +221,28 @@ void GRenderWindow::mousePressEvent(QMouseEvent *event) } } -void GRenderWindow::mouseMoveEvent(QMouseEvent *event) -{ +void GRenderWindow::mouseMoveEvent(QMouseEvent* event) { auto pos = event->pos(); qreal pixelRatio = windowPixelRatio(); this->TouchMoved(std::max(static_cast<unsigned>(pos.x() * pixelRatio), 0u), std::max(static_cast<unsigned>(pos.y() * pixelRatio), 0u)); } -void GRenderWindow::mouseReleaseEvent(QMouseEvent *event) -{ +void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) { if (event->button() == Qt::LeftButton) this->TouchReleased(); } -void GRenderWindow::ReloadSetKeymaps() -{ +void GRenderWindow::ReloadSetKeymaps() { KeyMap::ClearKeyMapping(keyboard_id); for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { - KeyMap::SetKeyMapping({ Settings::values.input_mappings[Settings::NativeInput::All[i]], keyboard_id }, KeyMap::mapping_targets[i]); + KeyMap::SetKeyMapping( + {Settings::values.input_mappings[Settings::NativeInput::All[i]], keyboard_id}, + KeyMap::mapping_targets[i]); } } -void GRenderWindow::OnClientAreaResized(unsigned width, unsigned height) -{ +void GRenderWindow::OnClientAreaResized(unsigned width, unsigned height) { NotifyClientAreaSizeChanged(std::make_pair(width, height)); } @@ -267,7 +255,8 @@ void GRenderWindow::InitRenderTarget() { delete layout(); } - // TODO: One of these flags might be interesting: WA_OpaquePaintEvent, WA_NoBackground, WA_DontShowOnScreen, WA_DeleteOnClose + // TODO: One of these flags might be interesting: WA_OpaquePaintEvent, WA_NoBackground, + // WA_DontShowOnScreen, WA_DeleteOnClose QGLFormat fmt; fmt.setVersion(3, 3); fmt.setProfile(QGLFormat::CoreProfile); @@ -279,7 +268,8 @@ void GRenderWindow::InitRenderTarget() { child = new GGLWidgetInternal(fmt, this); QBoxLayout* layout = new QHBoxLayout(this); - resize(VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight); + resize(VideoCore::kScreenTopWidth, + VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight); layout->addWidget(child); layout->setMargin(0); setLayout(layout); @@ -292,7 +282,8 @@ void GRenderWindow::InitRenderTarget() { BackupGeometry(); } -void GRenderWindow::OnMinimalClientAreaChangeRequest(const std::pair<unsigned,unsigned>& minimal_size) { +void GRenderWindow::OnMinimalClientAreaChangeRequest( + const std::pair<unsigned, unsigned>& minimal_size) { setMinimumSize(minimal_size.first, minimal_size.second); } @@ -306,11 +297,12 @@ void GRenderWindow::OnEmulationStopping() { child->EnablePainting(); } -void GRenderWindow::showEvent(QShowEvent * event) { +void GRenderWindow::showEvent(QShowEvent* event) { QWidget::showEvent(event); +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) // windowHandle() is not initialized until the Window is shown, so we connect it here. - #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - connect(this->windowHandle(), SIGNAL(screenChanged(QScreen*)), this, SLOT(OnFramebufferSizeChanged()), Qt::UniqueConnection); - #endif + connect(this->windowHandle(), SIGNAL(screenChanged(QScreen*)), this, + SLOT(OnFramebufferSizeChanged()), Qt::UniqueConnection); +#endif } diff --git a/src/citra_qt/bootmanager.h b/src/citra_qt/bootmanager.h index c1da2bc5f..67228b94f 100644 --- a/src/citra_qt/bootmanager.h +++ b/src/citra_qt/bootmanager.h @@ -5,10 +5,8 @@ #include <atomic> #include <condition_variable> #include <mutex> - #include <QGLWidget> #include <QThread> - #include "common/emu_window.h" #include "common/thread.h" @@ -19,8 +17,7 @@ class GGLWidgetInternal; class GMainWindow; class GRenderWindow; -class EmuThread : public QThread -{ +class EmuThread : public QThread { Q_OBJECT public: @@ -58,7 +55,9 @@ public: * @return True if the emulation thread is running, otherwise false * @note This function is thread-safe */ - bool IsRunning() { return running; } + bool IsRunning() { + return running; + } /** * Requests for the emulation thread to stop running @@ -81,20 +80,23 @@ signals: /** * Emitted when the CPU has halted execution * - * @warning When connecting to this signal from other threads, make sure to specify either Qt::QueuedConnection (invoke slot within the destination object's message thread) or even Qt::BlockingQueuedConnection (additionally block source thread until slot returns) + * @warning When connecting to this signal from other threads, make sure to specify either + * Qt::QueuedConnection (invoke slot within the destination object's message thread) or even + * Qt::BlockingQueuedConnection (additionally block source thread until slot returns) */ void DebugModeEntered(); /** * Emitted right before the CPU continues execution * - * @warning When connecting to this signal from other threads, make sure to specify either Qt::QueuedConnection (invoke slot within the destination object's message thread) or even Qt::BlockingQueuedConnection (additionally block source thread until slot returns) + * @warning When connecting to this signal from other threads, make sure to specify either + * Qt::QueuedConnection (invoke slot within the destination object's message thread) or even + * Qt::BlockingQueuedConnection (additionally block source thread until slot returns) */ void DebugModeLeft(); }; -class GRenderWindow : public QWidget, public EmuWindow -{ +class GRenderWindow : public QWidget, public EmuWindow { Q_OBJECT public: @@ -109,7 +111,7 @@ public: void BackupGeometry(); void RestoreGeometry(); void restoreGeometry(const QByteArray& geometry); // overridden - QByteArray saveGeometry(); // overridden + QByteArray saveGeometry(); // overridden qreal windowPixelRatio(); @@ -118,9 +120,9 @@ public: void keyPressEvent(QKeyEvent* event) override; void keyReleaseEvent(QKeyEvent* event) override; - void mousePressEvent(QMouseEvent *event) override; - void mouseMoveEvent(QMouseEvent *event) override; - void mouseReleaseEvent(QMouseEvent *event) override; + void mousePressEvent(QMouseEvent* event) override; + void mouseMoveEvent(QMouseEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; void ReloadSetKeymaps() override; @@ -129,7 +131,7 @@ public: void InitRenderTarget(); public slots: - void moveContext(); // overridden + void moveContext(); // overridden void OnEmulationStarting(EmuThread* emu_thread); void OnEmulationStopping(); @@ -140,7 +142,8 @@ signals: void Closed(); private: - void OnMinimalClientAreaChangeRequest(const std::pair<unsigned,unsigned>& minimal_size) override; + void OnMinimalClientAreaChangeRequest( + const std::pair<unsigned, unsigned>& minimal_size) override; GGLWidgetInternal* child; diff --git a/src/citra_qt/config.cpp b/src/citra_qt/config.cpp index cf1c09930..0b46ca6bb 100644 --- a/src/citra_qt/config.cpp +++ b/src/citra_qt/config.cpp @@ -3,10 +3,8 @@ // Refer to the license.txt file included. #include <QSettings> - #include "citra_qt/config.h" #include "citra_qt/ui_settings.h" - #include "common/file_util.h" Config::Config() { @@ -20,24 +18,23 @@ Config::Config() { const std::array<QVariant, Settings::NativeInput::NUM_INPUTS> Config::defaults = { // directly mapped keys - Qt::Key_A, Qt::Key_S, Qt::Key_Z, Qt::Key_X, - Qt::Key_Q, Qt::Key_W, Qt::Key_1, Qt::Key_2, - Qt::Key_M, Qt::Key_N, Qt::Key_B, - Qt::Key_T, Qt::Key_G, Qt::Key_F, Qt::Key_H, - Qt::Key_I, Qt::Key_K, Qt::Key_J, Qt::Key_L, + Qt::Key_A, Qt::Key_S, Qt::Key_Z, Qt::Key_X, Qt::Key_Q, Qt::Key_W, Qt::Key_1, Qt::Key_2, + Qt::Key_M, Qt::Key_N, Qt::Key_B, Qt::Key_T, Qt::Key_G, Qt::Key_F, Qt::Key_H, Qt::Key_I, + Qt::Key_K, Qt::Key_J, Qt::Key_L, // indirectly mapped keys - Qt::Key_Up, Qt::Key_Down, Qt::Key_Left, Qt::Key_Right, - Qt::Key_D, + Qt::Key_Up, Qt::Key_Down, Qt::Key_Left, Qt::Key_Right, Qt::Key_D, }; void Config::ReadValues() { qt_config->beginGroup("Controls"); for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { Settings::values.input_mappings[Settings::NativeInput::All[i]] = - qt_config->value(QString::fromStdString(Settings::NativeInput::Mapping[i]), defaults[i]).toInt(); + qt_config->value(QString::fromStdString(Settings::NativeInput::Mapping[i]), defaults[i]) + .toInt(); } - Settings::values.pad_circle_modifier_scale = qt_config->value("pad_circle_modifier_scale", 0.5).toFloat(); + Settings::values.pad_circle_modifier_scale = + qt_config->value("pad_circle_modifier_scale", 0.5).toFloat(); qt_config->endGroup(); qt_config->beginGroup("Core"); @@ -48,17 +45,19 @@ void Config::ReadValues() { qt_config->beginGroup("Renderer"); Settings::values.use_hw_renderer = qt_config->value("use_hw_renderer", true).toBool(); Settings::values.use_shader_jit = qt_config->value("use_shader_jit", true).toBool(); - Settings::values.use_scaled_resolution = qt_config->value("use_scaled_resolution", false).toBool(); + Settings::values.use_scaled_resolution = + qt_config->value("use_scaled_resolution", false).toBool(); Settings::values.use_vsync = qt_config->value("use_vsync", false).toBool(); - Settings::values.bg_red = qt_config->value("bg_red", 1.0).toFloat(); + Settings::values.bg_red = qt_config->value("bg_red", 1.0).toFloat(); Settings::values.bg_green = qt_config->value("bg_green", 1.0).toFloat(); - Settings::values.bg_blue = qt_config->value("bg_blue", 1.0).toFloat(); + Settings::values.bg_blue = qt_config->value("bg_blue", 1.0).toFloat(); qt_config->endGroup(); qt_config->beginGroup("Audio"); Settings::values.sink_id = qt_config->value("output_engine", "auto").toString().toStdString(); - Settings::values.enable_audio_stretching = qt_config->value("enable_audio_stretching", true).toBool(); + Settings::values.enable_audio_stretching = + qt_config->value("enable_audio_stretching", true).toBool(); qt_config->endGroup(); qt_config->beginGroup("Data Storage"); @@ -84,10 +83,14 @@ void Config::ReadValues() { qt_config->beginGroup("UILayout"); UISettings::values.geometry = qt_config->value("geometry").toByteArray(); UISettings::values.state = qt_config->value("state").toByteArray(); - UISettings::values.renderwindow_geometry = qt_config->value("geometryRenderWindow").toByteArray(); - UISettings::values.gamelist_header_state = qt_config->value("gameListHeaderState").toByteArray(); - UISettings::values.microprofile_geometry = qt_config->value("microProfileDialogGeometry").toByteArray(); - UISettings::values.microprofile_visible = qt_config->value("microProfileDialogVisible", false).toBool(); + UISettings::values.renderwindow_geometry = + qt_config->value("geometryRenderWindow").toByteArray(); + UISettings::values.gamelist_header_state = + qt_config->value("gameListHeaderState").toByteArray(); + UISettings::values.microprofile_geometry = + qt_config->value("microProfileDialogGeometry").toByteArray(); + UISettings::values.microprofile_visible = + qt_config->value("microProfileDialogVisible", false).toBool(); qt_config->endGroup(); qt_config->beginGroup("Paths"); @@ -106,10 +109,10 @@ void Config::ReadValues() { QStringList hotkeys = qt_config->childGroups(); for (auto hotkey : hotkeys) { qt_config->beginGroup(hotkey); - UISettings::values.shortcuts.emplace_back( - UISettings::Shortcut(group + "/" + hotkey, - UISettings::ContextualShortcut(qt_config->value("KeySeq").toString(), - qt_config->value("Context").toInt()))); + UISettings::values.shortcuts.emplace_back(UISettings::Shortcut( + group + "/" + hotkey, + UISettings::ContextualShortcut(qt_config->value("KeySeq").toString(), + qt_config->value("Context").toInt()))); qt_config->endGroup(); } @@ -119,7 +122,7 @@ void Config::ReadValues() { UISettings::values.single_window_mode = qt_config->value("singleWindowMode", true).toBool(); UISettings::values.display_titlebar = qt_config->value("displayTitleBars", true).toBool(); - UISettings::values.confirm_before_closing = qt_config->value("confirmClose",true).toBool(); + UISettings::values.confirm_before_closing = qt_config->value("confirmClose", true).toBool(); UISettings::values.first_start = qt_config->value("firstStart", true).toBool(); qt_config->endGroup(); @@ -129,9 +132,10 @@ void Config::SaveValues() { qt_config->beginGroup("Controls"); for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) { qt_config->setValue(QString::fromStdString(Settings::NativeInput::Mapping[i]), - Settings::values.input_mappings[Settings::NativeInput::All[i]]); + Settings::values.input_mappings[Settings::NativeInput::All[i]]); } - qt_config->setValue("pad_circle_modifier_scale", (double)Settings::values.pad_circle_modifier_scale); + qt_config->setValue("pad_circle_modifier_scale", + (double)Settings::values.pad_circle_modifier_scale); qt_config->endGroup(); qt_config->beginGroup("Core"); @@ -146,9 +150,9 @@ void Config::SaveValues() { qt_config->setValue("use_vsync", Settings::values.use_vsync); // Cast to double because Qt's written float values are not human-readable - qt_config->setValue("bg_red", (double)Settings::values.bg_red); + qt_config->setValue("bg_red", (double)Settings::values.bg_red); qt_config->setValue("bg_green", (double)Settings::values.bg_green); - qt_config->setValue("bg_blue", (double)Settings::values.bg_blue); + qt_config->setValue("bg_blue", (double)Settings::values.bg_blue); qt_config->endGroup(); qt_config->beginGroup("Audio"); diff --git a/src/citra_qt/config.h b/src/citra_qt/config.h index 0cbdb707f..79c901804 100644 --- a/src/citra_qt/config.h +++ b/src/citra_qt/config.h @@ -6,7 +6,6 @@ #include <string> #include <QVariant> - #include "core/settings.h" class QSettings; @@ -17,6 +16,7 @@ class Config { void ReadValues(); void SaveValues(); + public: Config(); ~Config(); diff --git a/src/citra_qt/configure_audio.cpp b/src/citra_qt/configure_audio.cpp index 7100be158..3cdd4c780 100644 --- a/src/citra_qt/configure_audio.cpp +++ b/src/citra_qt/configure_audio.cpp @@ -3,16 +3,12 @@ // Refer to the license.txt file included. #include "audio_core/sink_details.h" - #include "citra_qt/configure_audio.h" -#include "ui_configure_audio.h" - #include "core/settings.h" +#include "ui_configure_audio.h" -ConfigureAudio::ConfigureAudio(QWidget* parent) : - QWidget(parent), - ui(std::make_unique<Ui::ConfigureAudio>()) -{ +ConfigureAudio::ConfigureAudio(QWidget* parent) + : QWidget(parent), ui(std::make_unique<Ui::ConfigureAudio>()) { ui->setupUi(this); ui->output_sink_combo_box->clear(); @@ -24,8 +20,7 @@ ConfigureAudio::ConfigureAudio(QWidget* parent) : this->setConfiguration(); } -ConfigureAudio::~ConfigureAudio() { -} +ConfigureAudio::~ConfigureAudio() {} void ConfigureAudio::setConfiguration() { int new_sink_index = 0; @@ -41,7 +36,9 @@ void ConfigureAudio::setConfiguration() { } void ConfigureAudio::applyConfiguration() { - Settings::values.sink_id = ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex()).toStdString(); + Settings::values.sink_id = + ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex()) + .toStdString(); Settings::values.enable_audio_stretching = ui->toggle_audio_stretching->isChecked(); Settings::Apply(); } diff --git a/src/citra_qt/configure_debug.cpp b/src/citra_qt/configure_debug.cpp index fa57a7f72..dcc398eee 100644 --- a/src/citra_qt/configure_debug.cpp +++ b/src/citra_qt/configure_debug.cpp @@ -3,20 +3,15 @@ // Refer to the license.txt file included. #include "citra_qt/configure_debug.h" -#include "ui_configure_debug.h" - #include "core/settings.h" +#include "ui_configure_debug.h" -ConfigureDebug::ConfigureDebug(QWidget *parent) : - QWidget(parent), - ui(new Ui::ConfigureDebug) -{ +ConfigureDebug::ConfigureDebug(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureDebug) { ui->setupUi(this); this->setConfiguration(); } -ConfigureDebug::~ConfigureDebug() { -} +ConfigureDebug::~ConfigureDebug() {} void ConfigureDebug::setConfiguration() { ui->toggle_gdbstub->setChecked(Settings::values.use_gdbstub); diff --git a/src/citra_qt/configure_debug.h b/src/citra_qt/configure_debug.h index ab58ebbdc..d167eb996 100644 --- a/src/citra_qt/configure_debug.h +++ b/src/citra_qt/configure_debug.h @@ -11,12 +11,11 @@ namespace Ui { class ConfigureDebug; } -class ConfigureDebug : public QWidget -{ +class ConfigureDebug : public QWidget { Q_OBJECT public: - explicit ConfigureDebug(QWidget *parent = nullptr); + explicit ConfigureDebug(QWidget* parent = nullptr); ~ConfigureDebug(); void applyConfiguration(); diff --git a/src/citra_qt/configure_dialog.cpp b/src/citra_qt/configure_dialog.cpp index 016f201ef..446ad04a1 100644 --- a/src/citra_qt/configure_dialog.cpp +++ b/src/citra_qt/configure_dialog.cpp @@ -4,24 +4,17 @@ #include "citra_qt/config.h" #include "citra_qt/configure_dialog.h" -#include "ui_configure.h" - - #include "core/settings.h" +#include "ui_configure.h" -ConfigureDialog::ConfigureDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::ConfigureDialog) -{ +ConfigureDialog::ConfigureDialog(QWidget* parent) : QDialog(parent), ui(new Ui::ConfigureDialog) { ui->setupUi(this); this->setConfiguration(); } -ConfigureDialog::~ConfigureDialog() { -} +ConfigureDialog::~ConfigureDialog() {} -void ConfigureDialog::setConfiguration() { -} +void ConfigureDialog::setConfiguration() {} void ConfigureDialog::applyConfiguration() { ui->generalTab->applyConfiguration(); diff --git a/src/citra_qt/configure_dialog.h b/src/citra_qt/configure_dialog.h index e232699cd..21fa1f501 100644 --- a/src/citra_qt/configure_dialog.h +++ b/src/citra_qt/configure_dialog.h @@ -11,12 +11,11 @@ namespace Ui { class ConfigureDialog; } -class ConfigureDialog : public QDialog -{ +class ConfigureDialog : public QDialog { Q_OBJECT public: - explicit ConfigureDialog(QWidget *parent); + explicit ConfigureDialog(QWidget* parent); ~ConfigureDialog(); void applyConfiguration(); diff --git a/src/citra_qt/configure_general.cpp b/src/citra_qt/configure_general.cpp index e6832341a..27139fb30 100644 --- a/src/citra_qt/configure_general.cpp +++ b/src/citra_qt/configure_general.cpp @@ -4,23 +4,20 @@ #include "citra_qt/configure_general.h" #include "citra_qt/ui_settings.h" -#include "ui_configure_general.h" - #include "core/settings.h" #include "core/system.h" +#include "ui_configure_general.h" + +ConfigureGeneral::ConfigureGeneral(QWidget* parent) + : QWidget(parent), ui(new Ui::ConfigureGeneral) { -ConfigureGeneral::ConfigureGeneral(QWidget *parent) : - QWidget(parent), - ui(new Ui::ConfigureGeneral) -{ ui->setupUi(this); this->setConfiguration(); ui->toggle_cpu_jit->setEnabled(!System::IsPoweredOn()); } -ConfigureGeneral::~ConfigureGeneral() { -} +ConfigureGeneral::~ConfigureGeneral() {} void ConfigureGeneral::setConfiguration() { ui->toggle_deepscan->setChecked(UISettings::values.gamedir_deepscan); diff --git a/src/citra_qt/configure_general.h b/src/citra_qt/configure_general.h index a6c68e62d..447552d8c 100644 --- a/src/citra_qt/configure_general.h +++ b/src/citra_qt/configure_general.h @@ -11,12 +11,11 @@ namespace Ui { class ConfigureGeneral; } -class ConfigureGeneral : public QWidget -{ +class ConfigureGeneral : public QWidget { Q_OBJECT public: - explicit ConfigureGeneral(QWidget *parent = nullptr); + explicit ConfigureGeneral(QWidget* parent = nullptr); ~ConfigureGeneral(); void applyConfiguration(); diff --git a/src/citra_qt/configure_graphics.cpp b/src/citra_qt/configure_graphics.cpp index 5a8101795..19c1f75c2 100644 --- a/src/citra_qt/configure_graphics.cpp +++ b/src/citra_qt/configure_graphics.cpp @@ -3,23 +3,20 @@ // Refer to the license.txt file included. #include "citra_qt/configure_graphics.h" -#include "ui_configure_graphics.h" - #include "core/settings.h" #include "core/system.h" +#include "ui_configure_graphics.h" + +ConfigureGraphics::ConfigureGraphics(QWidget* parent) + : QWidget(parent), ui(new Ui::ConfigureGraphics) { -ConfigureGraphics::ConfigureGraphics(QWidget *parent) : - QWidget(parent), - ui(new Ui::ConfigureGraphics) -{ ui->setupUi(this); this->setConfiguration(); ui->toggle_vsync->setEnabled(!System::IsPoweredOn()); } -ConfigureGraphics::~ConfigureGraphics() { -} +ConfigureGraphics::~ConfigureGraphics() {} void ConfigureGraphics::setConfiguration() { ui->toggle_hw_renderer->setChecked(Settings::values.use_hw_renderer); diff --git a/src/citra_qt/configure_graphics.h b/src/citra_qt/configure_graphics.h index dfb0c0461..5497a55f7 100644 --- a/src/citra_qt/configure_graphics.h +++ b/src/citra_qt/configure_graphics.h @@ -11,12 +11,11 @@ namespace Ui { class ConfigureGraphics; } -class ConfigureGraphics : public QWidget -{ +class ConfigureGraphics : public QWidget { Q_OBJECT public: - explicit ConfigureGraphics(QWidget *parent = nullptr); + explicit ConfigureGraphics(QWidget* parent = nullptr); ~ConfigureGraphics(); void applyConfiguration(); diff --git a/src/citra_qt/configure_input.cpp b/src/citra_qt/configure_input.cpp index 9c7a67174..d321db71f 100644 --- a/src/citra_qt/configure_input.cpp +++ b/src/citra_qt/configure_input.cpp @@ -5,38 +5,39 @@ #include <memory> #include <utility> #include <QTimer> - #include "citra_qt/configure_input.h" -ConfigureInput::ConfigureInput(QWidget* parent) : QWidget(parent), ui(std::make_unique<Ui::ConfigureInput>()) { +ConfigureInput::ConfigureInput(QWidget* parent) + : QWidget(parent), ui(std::make_unique<Ui::ConfigureInput>()) { + ui->setupUi(this); // Initialize mapping of input enum to UI button. input_mapping = { - { std::make_pair(Settings::NativeInput::Values::A, ui->buttonA) }, - { std::make_pair(Settings::NativeInput::Values::B, ui->buttonB) }, - { std::make_pair(Settings::NativeInput::Values::X, ui->buttonX) }, - { std::make_pair(Settings::NativeInput::Values::Y, ui->buttonY) }, - { std::make_pair(Settings::NativeInput::Values::L, ui->buttonL) }, - { std::make_pair(Settings::NativeInput::Values::R, ui->buttonR) }, - { std::make_pair(Settings::NativeInput::Values::ZL, ui->buttonZL) }, - { std::make_pair(Settings::NativeInput::Values::ZR, ui->buttonZR) }, - { std::make_pair(Settings::NativeInput::Values::START, ui->buttonStart) }, - { std::make_pair(Settings::NativeInput::Values::SELECT, ui->buttonSelect) }, - { std::make_pair(Settings::NativeInput::Values::HOME, ui->buttonHome) }, - { std::make_pair(Settings::NativeInput::Values::DUP, ui->buttonDpadUp) }, - { std::make_pair(Settings::NativeInput::Values::DDOWN, ui->buttonDpadDown) }, - { std::make_pair(Settings::NativeInput::Values::DLEFT, ui->buttonDpadLeft) }, - { std::make_pair(Settings::NativeInput::Values::DRIGHT, ui->buttonDpadRight) }, - { std::make_pair(Settings::NativeInput::Values::CUP, ui->buttonCStickUp) }, - { std::make_pair(Settings::NativeInput::Values::CDOWN, ui->buttonCStickDown) }, - { std::make_pair(Settings::NativeInput::Values::CLEFT, ui->buttonCStickLeft) }, - { std::make_pair(Settings::NativeInput::Values::CRIGHT, ui->buttonCStickRight) }, - { std::make_pair(Settings::NativeInput::Values::CIRCLE_UP, ui->buttonCircleUp) }, - { std::make_pair(Settings::NativeInput::Values::CIRCLE_DOWN, ui->buttonCircleDown) }, - { std::make_pair(Settings::NativeInput::Values::CIRCLE_LEFT, ui->buttonCircleLeft) }, - { std::make_pair(Settings::NativeInput::Values::CIRCLE_RIGHT, ui->buttonCircleRight) }, - { std::make_pair(Settings::NativeInput::Values::CIRCLE_MODIFIER, ui->buttonCircleMod) }, + {Settings::NativeInput::Values::A, ui->buttonA}, + {Settings::NativeInput::Values::B, ui->buttonB}, + {Settings::NativeInput::Values::X, ui->buttonX}, + {Settings::NativeInput::Values::Y, ui->buttonY}, + {Settings::NativeInput::Values::L, ui->buttonL}, + {Settings::NativeInput::Values::R, ui->buttonR}, + {Settings::NativeInput::Values::ZL, ui->buttonZL}, + {Settings::NativeInput::Values::ZR, ui->buttonZR}, + {Settings::NativeInput::Values::START, ui->buttonStart}, + {Settings::NativeInput::Values::SELECT, ui->buttonSelect}, + {Settings::NativeInput::Values::HOME, ui->buttonHome}, + {Settings::NativeInput::Values::DUP, ui->buttonDpadUp}, + {Settings::NativeInput::Values::DDOWN, ui->buttonDpadDown}, + {Settings::NativeInput::Values::DLEFT, ui->buttonDpadLeft}, + {Settings::NativeInput::Values::DRIGHT, ui->buttonDpadRight}, + {Settings::NativeInput::Values::CUP, ui->buttonCStickUp}, + {Settings::NativeInput::Values::CDOWN, ui->buttonCStickDown}, + {Settings::NativeInput::Values::CLEFT, ui->buttonCStickLeft}, + {Settings::NativeInput::Values::CRIGHT, ui->buttonCStickRight}, + {Settings::NativeInput::Values::CIRCLE_UP, ui->buttonCircleUp}, + {Settings::NativeInput::Values::CIRCLE_DOWN, ui->buttonCircleDown}, + {Settings::NativeInput::Values::CIRCLE_LEFT, ui->buttonCircleLeft}, + {Settings::NativeInput::Values::CIRCLE_RIGHT, ui->buttonCircleRight}, + {Settings::NativeInput::Values::CIRCLE_MODIFIER, ui->buttonCircleMod}, }; // Attach handle click method to each button click. @@ -47,7 +48,10 @@ ConfigureInput::ConfigureInput(QWidget* parent) : QWidget(parent), ui(std::make_ setFocusPolicy(Qt::ClickFocus); timer = new QTimer(this); timer->setSingleShot(true); - connect(timer, &QTimer::timeout, this, [&]() { key_pressed = Qt::Key_Escape; setKey(); }); + connect(timer, &QTimer::timeout, this, [&]() { + key_pressed = Qt::Key_Escape; + setKey(); + }); this->setConfiguration(); } @@ -59,7 +63,7 @@ void ConfigureInput::handleClick() { grabKeyboard(); grabMouse(); changing_button = sender; - timer->start(5000); //Cancel after 5 seconds + timer->start(5000); // Cancel after 5 seconds } void ConfigureInput::applyConfiguration() { diff --git a/src/citra_qt/configure_input.h b/src/citra_qt/configure_input.h index fe8ea5580..5183b904d 100644 --- a/src/citra_qt/configure_input.h +++ b/src/citra_qt/configure_input.h @@ -4,9 +4,9 @@ #pragma once -#include <QWidget> +#include <memory> #include <QKeyEvent> - +#include <QWidget> #include "citra_qt/config.h" #include "core/settings.h" #include "ui_configure_input.h" @@ -16,7 +16,7 @@ class QString; class QTimer; namespace Ui { - class ConfigureInput; +class ConfigureInput; } class ConfigureInput : public QWidget { @@ -39,7 +39,8 @@ private: /// Load configuration settings into button text void setConfiguration(); - /// Check all inputs for duplicate keys. Clears out any other button with the same value as this button's new value. + /// Check all inputs for duplicate keys. Clears out any other button with the same value as this + /// button's new value. void removeDuplicates(const QString& newValue); /// Handle key press event for input tab when a button is 'waiting'. diff --git a/src/citra_qt/configure_system.cpp b/src/citra_qt/configure_system.cpp index 5c5d83ff3..873d314ec 100644 --- a/src/citra_qt/configure_system.cpp +++ b/src/citra_qt/configure_system.cpp @@ -4,27 +4,24 @@ #include "citra_qt/configure_system.h" #include "citra_qt/ui_settings.h" -#include "ui_configure_system.h" - -#include "core/hle/service/fs/archive.h" #include "core/hle/service/cfg/cfg.h" +#include "core/hle/service/fs/archive.h" #include "core/system.h" +#include "ui_configure_system.h" static const std::array<int, 12> days_in_month = {{ - 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 + 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, }}; -ConfigureSystem::ConfigureSystem(QWidget *parent) : - QWidget(parent), - ui(new Ui::ConfigureSystem) { +ConfigureSystem::ConfigureSystem(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureSystem) { ui->setupUi(this); - connect(ui->combo_birthmonth, SIGNAL(currentIndexChanged(int)), SLOT(updateBirthdayComboBox(int))); + connect(ui->combo_birthmonth, SIGNAL(currentIndexChanged(int)), + SLOT(updateBirthdayComboBox(int))); this->setConfiguration(); } -ConfigureSystem::~ConfigureSystem() { -} +ConfigureSystem::~ConfigureSystem() {} void ConfigureSystem::setConfiguration() { enabled = !System::IsPoweredOn(); @@ -54,13 +51,17 @@ void ConfigureSystem::setConfiguration() { void ConfigureSystem::ReadSystemSettings() { // set username username = Service::CFG::GetUsername(); - // ui->edit_username->setText(QString::fromStdU16String(username)); // TODO(wwylele): Use this when we move to Qt 5.5 - ui->edit_username->setText(QString::fromUtf16(reinterpret_cast<const ushort*>(username.data()))); + // TODO(wwylele): Use this when we move to Qt 5.5 + // ui->edit_username->setText(QString::fromStdU16String(username)); + ui->edit_username->setText( + QString::fromUtf16(reinterpret_cast<const ushort*>(username.data()))); // set birthday std::tie(birthmonth, birthday) = Service::CFG::GetBirthday(); ui->combo_birthmonth->setCurrentIndex(birthmonth - 1); - updateBirthdayComboBox(birthmonth - 1); // explicitly update it because the signal from setCurrentIndex is not reliable + updateBirthdayComboBox( + birthmonth - + 1); // explicitly update it because the signal from setCurrentIndex is not reliable ui->combo_birthday->setCurrentIndex(birthday - 1); // set system language @@ -79,8 +80,10 @@ void ConfigureSystem::applyConfiguration() { bool modified = false; // apply username - // std::u16string new_username = ui->edit_username->text().toStdU16String(); // TODO(wwylele): Use this when we move to Qt 5.5 - std::u16string new_username(reinterpret_cast<const char16_t*>(ui->edit_username->text().utf16())); + // TODO(wwylele): Use this when we move to Qt 5.5 + // std::u16string new_username = ui->edit_username->text().toStdU16String(); + std::u16string new_username( + reinterpret_cast<const char16_t*>(ui->edit_username->text().utf16())); if (new_username != username) { Service::CFG::SetUsername(new_username); modified = true; diff --git a/src/citra_qt/configure_system.h b/src/citra_qt/configure_system.h index f02d2d949..db0ead13c 100644 --- a/src/citra_qt/configure_system.h +++ b/src/citra_qt/configure_system.h @@ -11,12 +11,11 @@ namespace Ui { class ConfigureSystem; } -class ConfigureSystem : public QWidget -{ +class ConfigureSystem : public QWidget { Q_OBJECT public: - explicit ConfigureSystem(QWidget *parent = nullptr); + explicit ConfigureSystem(QWidget* parent = nullptr); ~ConfigureSystem(); void applyConfiguration(); diff --git a/src/citra_qt/debugger/callstack.cpp b/src/citra_qt/debugger/callstack.cpp index 1a3077495..c66f2b96a 100644 --- a/src/citra_qt/debugger/callstack.cpp +++ b/src/citra_qt/debugger/callstack.cpp @@ -3,19 +3,15 @@ // Refer to the license.txt file included. #include <QStandardItemModel> - #include "citra_qt/debugger/callstack.h" - #include "common/common_types.h" #include "common/symbols.h" - -#include "core/core.h" -#include "core/memory.h" #include "core/arm/arm_interface.h" #include "core/arm/disassembler/arm_disasm.h" +#include "core/core.h" +#include "core/memory.h" -CallstackWidget::CallstackWidget(QWidget* parent): QDockWidget(parent) -{ +CallstackWidget::CallstackWidget(QWidget* parent) : QDockWidget(parent) { ui.setupUi(this); callstack_model = new QStandardItemModel(this); @@ -27,29 +23,26 @@ CallstackWidget::CallstackWidget(QWidget* parent): QDockWidget(parent) ui.treeView->setModel(callstack_model); } -void CallstackWidget::OnDebugModeEntered() -{ +void CallstackWidget::OnDebugModeEntered() { // Stack pointer const u32 sp = Core::g_app_core->GetReg(13); Clear(); int counter = 0; - for (u32 addr = 0x10000000; addr >= sp; addr -= 4) - { + for (u32 addr = 0x10000000; addr >= sp; addr -= 4) { if (!Memory::IsValidVirtualAddress(addr)) break; const u32 ret_addr = Memory::Read32(addr); - const u32 call_addr = ret_addr - 4; //get call address??? + const u32 call_addr = ret_addr - 4; // get call address??? if (!Memory::IsValidVirtualAddress(call_addr)) break; /* TODO (mattvail) clean me, move to debugger interface */ u32 insn = Memory::Read32(call_addr); - if (ARM_Disasm::Decode(insn) == OP_BL) - { + if (ARM_Disasm::Decode(insn) == OP_BL) { std::string name; // ripped from disasm u8 cond = (insn >> 28) & 0xf; @@ -63,26 +56,28 @@ void CallstackWidget::OnDebugModeEntered() i_offset += 8; const u32 func_addr = call_addr + i_offset; - callstack_model->setItem(counter, 0, new QStandardItem(QString("0x%1").arg(addr, 8, 16, QLatin1Char('0')))); - callstack_model->setItem(counter, 1, new QStandardItem(QString("0x%1").arg(ret_addr, 8, 16, QLatin1Char('0')))); - callstack_model->setItem(counter, 2, new QStandardItem(QString("0x%1").arg(call_addr, 8, 16, QLatin1Char('0')))); + callstack_model->setItem( + counter, 0, new QStandardItem(QString("0x%1").arg(addr, 8, 16, QLatin1Char('0')))); + callstack_model->setItem(counter, 1, new QStandardItem(QString("0x%1").arg( + ret_addr, 8, 16, QLatin1Char('0')))); + callstack_model->setItem(counter, 2, new QStandardItem(QString("0x%1").arg( + call_addr, 8, 16, QLatin1Char('0')))); name = Symbols::HasSymbol(func_addr) ? Symbols::GetSymbol(func_addr).name : "unknown"; - callstack_model->setItem(counter, 3, new QStandardItem(QString("%1_%2").arg(QString::fromStdString(name)) - .arg(QString("0x%1").arg(func_addr, 8, 16, QLatin1Char('0'))))); + callstack_model->setItem( + counter, 3, new QStandardItem( + QString("%1_%2") + .arg(QString::fromStdString(name)) + .arg(QString("0x%1").arg(func_addr, 8, 16, QLatin1Char('0'))))); counter++; } } } -void CallstackWidget::OnDebugModeLeft() -{ - -} +void CallstackWidget::OnDebugModeLeft() {} -void CallstackWidget::Clear() -{ +void CallstackWidget::Clear() { for (int row = 0; row < callstack_model->rowCount(); row++) { for (int column = 0; column < callstack_model->columnCount(); column++) { callstack_model->setItem(row, column, new QStandardItem()); diff --git a/src/citra_qt/debugger/callstack.h b/src/citra_qt/debugger/callstack.h index 7aa83db1e..765757986 100644 --- a/src/citra_qt/debugger/callstack.h +++ b/src/citra_qt/debugger/callstack.h @@ -7,8 +7,7 @@ class QStandardItemModel; -class CallstackWidget : public QDockWidget -{ +class CallstackWidget : public QDockWidget { Q_OBJECT public: diff --git a/src/citra_qt/debugger/disassembler.cpp b/src/citra_qt/debugger/disassembler.cpp index d4f72809d..1ee6bbd6a 100644 --- a/src/citra_qt/debugger/disassembler.cpp +++ b/src/citra_qt/debugger/disassembler.cpp @@ -3,23 +3,20 @@ // Refer to the license.txt file included. #include <QShortcut> - #include "citra_qt/bootmanager.h" -#include "citra_qt/hotkeys.h" #include "citra_qt/debugger/disassembler.h" +#include "citra_qt/hotkeys.h" #include "citra_qt/util/util.h" - #include "common/break_points.h" #include "common/symbols.h" - -#include "core/core.h" -#include "core/memory.h" #include "core/arm/arm_interface.h" #include "core/arm/disassembler/arm_disasm.h" +#include "core/core.h" +#include "core/memory.h" -DisassemblerModel::DisassemblerModel(QObject* parent) : - QAbstractListModel(parent), base_address(0), code_size(0), program_counter(0), selection(QModelIndex()) { -} +DisassemblerModel::DisassemblerModel(QObject* parent) + : QAbstractListModel(parent), base_address(0), code_size(0), program_counter(0), + selection(QModelIndex()) {} int DisassemblerModel::columnCount(const QModelIndex& parent) const { return 3; @@ -31,62 +28,60 @@ int DisassemblerModel::rowCount(const QModelIndex& parent) const { QVariant DisassemblerModel::data(const QModelIndex& index, int role) const { switch (role) { - case Qt::DisplayRole: - { - u32 address = base_address + index.row() * 4; - u32 instr = Memory::Read32(address); - std::string disassembly = ARM_Disasm::Disassemble(address, instr); - - if (index.column() == 0) { - return QString("0x%1").arg((uint)(address), 8, 16, QLatin1Char('0')); - } else if (index.column() == 1) { - return QString::fromStdString(disassembly); - } else if (index.column() == 2) { - if(Symbols::HasSymbol(address)) { - TSymbol symbol = Symbols::GetSymbol(address); - return QString("%1 - Size:%2").arg(QString::fromStdString(symbol.name)) - .arg(symbol.size / 4); // divide by 4 to get instruction count - } else if (ARM_Disasm::Decode(instr) == OP_BL) { - u32 offset = instr & 0xFFFFFF; - - // Sign-extend the 24-bit offset - if ((offset >> 23) & 1) - offset |= 0xFF000000; - - // Pre-compute the left-shift and the prefetch offset - offset <<= 2; - offset += 8; - - TSymbol symbol = Symbols::GetSymbol(address + offset); - return QString(" --> %1").arg(QString::fromStdString(symbol.name)); - } + case Qt::DisplayRole: { + u32 address = base_address + index.row() * 4; + u32 instr = Memory::Read32(address); + std::string disassembly = ARM_Disasm::Disassemble(address, instr); + + if (index.column() == 0) { + return QString("0x%1").arg((uint)(address), 8, 16, QLatin1Char('0')); + } else if (index.column() == 1) { + return QString::fromStdString(disassembly); + } else if (index.column() == 2) { + if (Symbols::HasSymbol(address)) { + TSymbol symbol = Symbols::GetSymbol(address); + return QString("%1 - Size:%2") + .arg(QString::fromStdString(symbol.name)) + .arg(symbol.size / 4); // divide by 4 to get instruction count + } else if (ARM_Disasm::Decode(instr) == OP_BL) { + u32 offset = instr & 0xFFFFFF; + + // Sign-extend the 24-bit offset + if ((offset >> 23) & 1) + offset |= 0xFF000000; + + // Pre-compute the left-shift and the prefetch offset + offset <<= 2; + offset += 8; + + TSymbol symbol = Symbols::GetSymbol(address + offset); + return QString(" --> %1").arg(QString::fromStdString(symbol.name)); } - - break; } - case Qt::BackgroundRole: - { - unsigned int address = base_address + 4 * index.row(); + break; + } - if (breakpoints.IsAddressBreakPoint(address)) - return QBrush(QColor(0xFF, 0xC0, 0xC0)); - else if (address == program_counter) - return QBrush(QColor(0xC0, 0xC0, 0xFF)); + case Qt::BackgroundRole: { + unsigned int address = base_address + 4 * index.row(); - break; - } + if (breakpoints.IsAddressBreakPoint(address)) + return QBrush(QColor(0xFF, 0xC0, 0xC0)); + else if (address == program_counter) + return QBrush(QColor(0xC0, 0xC0, 0xFF)); - case Qt::FontRole: - { - if (index.column() == 0 || index.column() == 1) { // 2 is the symbols column - return GetMonospaceFont(); - } - break; + break; + } + + case Qt::FontRole: { + if (index.column() == 0 || index.column() == 1) { // 2 is the symbols column + return GetMonospaceFont(); } + break; + } - default: - break; + default: + break; } return QVariant(); @@ -103,7 +98,7 @@ const BreakPoints& DisassemblerModel::GetBreakPoints() const { void DisassemblerModel::ParseFromAddress(unsigned int address) { // NOTE: A too large value causes lagging when scrolling the disassembly - const unsigned int chunk_size = 1000*500; + const unsigned int chunk_size = 1000 * 500; // If we haven't loaded anything yet, initialize base address to the parameter address if (code_size == 0) @@ -165,23 +160,26 @@ void DisassemblerModel::SetNextInstruction(unsigned int address) { emit dataChanged(prev_index, prev_index); } -DisassemblerWidget::DisassemblerWidget(QWidget* parent, EmuThread* emu_thread) : - QDockWidget(parent), base_addr(0), emu_thread(emu_thread) { +DisassemblerWidget::DisassemblerWidget(QWidget* parent, EmuThread* emu_thread) + : QDockWidget(parent), base_addr(0), emu_thread(emu_thread) { disasm_ui.setupUi(this); RegisterHotkey("Disassembler", "Start/Stop", QKeySequence(Qt::Key_F5), Qt::ApplicationShortcut); RegisterHotkey("Disassembler", "Step", QKeySequence(Qt::Key_F10), Qt::ApplicationShortcut); RegisterHotkey("Disassembler", "Step into", QKeySequence(Qt::Key_F11), Qt::ApplicationShortcut); - RegisterHotkey("Disassembler", "Set Breakpoint", QKeySequence(Qt::Key_F9), Qt::ApplicationShortcut); + RegisterHotkey("Disassembler", "Set Breakpoint", QKeySequence(Qt::Key_F9), + Qt::ApplicationShortcut); connect(disasm_ui.button_step, SIGNAL(clicked()), this, SLOT(OnStep())); connect(disasm_ui.button_pause, SIGNAL(clicked()), this, SLOT(OnPause())); connect(disasm_ui.button_continue, SIGNAL(clicked()), this, SLOT(OnContinue())); - connect(GetHotkey("Disassembler", "Start/Stop", this), SIGNAL(activated()), this, SLOT(OnToggleStartStop())); + connect(GetHotkey("Disassembler", "Start/Stop", this), SIGNAL(activated()), this, + SLOT(OnToggleStartStop())); connect(GetHotkey("Disassembler", "Step", this), SIGNAL(activated()), this, SLOT(OnStep())); - connect(GetHotkey("Disassembler", "Step into", this), SIGNAL(activated()), this, SLOT(OnStepInto())); + connect(GetHotkey("Disassembler", "Step into", this), SIGNAL(activated()), this, + SLOT(OnStepInto())); setEnabled(false); } @@ -195,7 +193,8 @@ void DisassemblerWidget::Init() { QModelIndex model_index = model->IndexFromAbsoluteAddress(Core::g_app_core->GetPC()); disasm_ui.treeView->scrollTo(model_index); - disasm_ui.treeView->selectionModel()->setCurrentIndex(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); + disasm_ui.treeView->selectionModel()->setCurrentIndex( + model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); } void DisassemblerWidget::OnContinue() { @@ -234,11 +233,11 @@ void DisassemblerWidget::OnDebugModeEntered() { QModelIndex model_index = model->IndexFromAbsoluteAddress(next_instr); disasm_ui.treeView->scrollTo(model_index); - disasm_ui.treeView->selectionModel()->setCurrentIndex(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); + disasm_ui.treeView->selectionModel()->setCurrentIndex( + model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); } -void DisassemblerWidget::OnDebugModeLeft() { -} +void DisassemblerWidget::OnDebugModeLeft() {} int DisassemblerWidget::SelectedRow() { QModelIndex index = disasm_ui.treeView->selectionModel()->currentIndex(); @@ -254,10 +253,12 @@ void DisassemblerWidget::OnEmulationStarting(EmuThread* emu_thread) { model = new DisassemblerModel(this); disasm_ui.treeView->setModel(model); - connect(disasm_ui.treeView->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), - model, SLOT(OnSelectionChanged(const QModelIndex&))); + connect(disasm_ui.treeView->selectionModel(), + SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), model, + SLOT(OnSelectionChanged(const QModelIndex&))); connect(disasm_ui.button_breakpoint, SIGNAL(clicked()), model, SLOT(OnSetOrUnsetBreakpoint())); - connect(GetHotkey("Disassembler", "Set Breakpoint", this), SIGNAL(activated()), model, SLOT(OnSetOrUnsetBreakpoint())); + connect(GetHotkey("Disassembler", "Set Breakpoint", this), SIGNAL(activated()), model, + SLOT(OnSetOrUnsetBreakpoint())); Init(); setEnabled(true); diff --git a/src/citra_qt/debugger/disassembler.h b/src/citra_qt/debugger/disassembler.h index 340fb9936..2ca6c2bd4 100644 --- a/src/citra_qt/debugger/disassembler.h +++ b/src/citra_qt/debugger/disassembler.h @@ -6,17 +6,14 @@ #include <QAbstractListModel> #include <QDockWidget> - -#include "ui_disassembler.h" - #include "common/break_points.h" #include "common/common_types.h" +#include "ui_disassembler.h" class QAction; class EmuThread; -class DisassemblerModel : public QAbstractListModel -{ +class DisassemblerModel : public QAbstractListModel { Q_OBJECT public: @@ -46,8 +43,7 @@ private: mutable BreakPoints breakpoints; }; -class DisassemblerWidget : public QDockWidget -{ +class DisassemblerWidget : public QDockWidget { Q_OBJECT public: diff --git a/src/citra_qt/debugger/graphics.cpp b/src/citra_qt/debugger/graphics.cpp index eccd619ba..ef6712bfa 100644 --- a/src/citra_qt/debugger/graphics.cpp +++ b/src/citra_qt/debugger/graphics.cpp @@ -3,75 +3,67 @@ // Refer to the license.txt file included. #include <QListView> - #include "citra_qt/debugger/graphics.h" #include "citra_qt/util/util.h" extern GraphicsDebugger g_debugger; -GPUCommandStreamItemModel::GPUCommandStreamItemModel(QObject* parent) : QAbstractListModel(parent), command_count(0) -{ +GPUCommandStreamItemModel::GPUCommandStreamItemModel(QObject* parent) + : QAbstractListModel(parent), command_count(0) { connect(this, SIGNAL(GXCommandFinished(int)), this, SLOT(OnGXCommandFinishedInternal(int))); } -int GPUCommandStreamItemModel::rowCount(const QModelIndex& parent) const -{ +int GPUCommandStreamItemModel::rowCount(const QModelIndex& parent) const { return command_count; } -QVariant GPUCommandStreamItemModel::data(const QModelIndex& index, int role) const -{ +QVariant GPUCommandStreamItemModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) return QVariant(); int command_index = index.row(); const GSP_GPU::Command& command = GetDebugger()->ReadGXCommandHistory(command_index); - if (role == Qt::DisplayRole) - { + if (role == Qt::DisplayRole) { std::map<GSP_GPU::CommandId, const char*> command_names = { - { GSP_GPU::CommandId::REQUEST_DMA, "REQUEST_DMA" }, - { GSP_GPU::CommandId::SUBMIT_GPU_CMDLIST, "SUBMIT_GPU_CMDLIST" }, - { GSP_GPU::CommandId::SET_MEMORY_FILL, "SET_MEMORY_FILL" }, - { GSP_GPU::CommandId::SET_DISPLAY_TRANSFER, "SET_DISPLAY_TRANSFER" }, - { GSP_GPU::CommandId::SET_TEXTURE_COPY, "SET_TEXTURE_COPY" }, - { GSP_GPU::CommandId::CACHE_FLUSH, "CACHE_FLUSH" }, + {GSP_GPU::CommandId::REQUEST_DMA, "REQUEST_DMA"}, + {GSP_GPU::CommandId::SUBMIT_GPU_CMDLIST, "SUBMIT_GPU_CMDLIST"}, + {GSP_GPU::CommandId::SET_MEMORY_FILL, "SET_MEMORY_FILL"}, + {GSP_GPU::CommandId::SET_DISPLAY_TRANSFER, "SET_DISPLAY_TRANSFER"}, + {GSP_GPU::CommandId::SET_TEXTURE_COPY, "SET_TEXTURE_COPY"}, + {GSP_GPU::CommandId::CACHE_FLUSH, "CACHE_FLUSH"}, }; const u32* command_data = reinterpret_cast<const u32*>(&command); - QString str = QString("%1 %2 %3 %4 %5 %6 %7 %8 %9").arg(command_names[command.id]) - .arg(command_data[0], 8, 16, QLatin1Char('0')) - .arg(command_data[1], 8, 16, QLatin1Char('0')) - .arg(command_data[2], 8, 16, QLatin1Char('0')) - .arg(command_data[3], 8, 16, QLatin1Char('0')) - .arg(command_data[4], 8, 16, QLatin1Char('0')) - .arg(command_data[5], 8, 16, QLatin1Char('0')) - .arg(command_data[6], 8, 16, QLatin1Char('0')) - .arg(command_data[7], 8, 16, QLatin1Char('0')); + QString str = QString("%1 %2 %3 %4 %5 %6 %7 %8 %9") + .arg(command_names[command.id]) + .arg(command_data[0], 8, 16, QLatin1Char('0')) + .arg(command_data[1], 8, 16, QLatin1Char('0')) + .arg(command_data[2], 8, 16, QLatin1Char('0')) + .arg(command_data[3], 8, 16, QLatin1Char('0')) + .arg(command_data[4], 8, 16, QLatin1Char('0')) + .arg(command_data[5], 8, 16, QLatin1Char('0')) + .arg(command_data[6], 8, 16, QLatin1Char('0')) + .arg(command_data[7], 8, 16, QLatin1Char('0')); return QVariant(str); - } - else - { + } else { return QVariant(); } } -void GPUCommandStreamItemModel::GXCommandProcessed(int total_command_count) -{ +void GPUCommandStreamItemModel::GXCommandProcessed(int total_command_count) { emit GXCommandFinished(total_command_count); } -void GPUCommandStreamItemModel::OnGXCommandFinishedInternal(int total_command_count) -{ +void GPUCommandStreamItemModel::OnGXCommandFinishedInternal(int total_command_count) { if (total_command_count == 0) return; int prev_command_count = command_count; command_count = total_command_count; - emit dataChanged(index(prev_command_count,0), index(total_command_count-1,0)); + emit dataChanged(index(prev_command_count, 0), index(total_command_count - 1, 0)); } - -GPUCommandStreamWidget::GPUCommandStreamWidget(QWidget* parent) : QDockWidget(tr("Graphics Debugger"), parent) -{ +GPUCommandStreamWidget::GPUCommandStreamWidget(QWidget* parent) + : QDockWidget(tr("Graphics Debugger"), parent) { setObjectName("GraphicsDebugger"); GPUCommandStreamItemModel* command_model = new GPUCommandStreamItemModel(this); diff --git a/src/citra_qt/debugger/graphics.h b/src/citra_qt/debugger/graphics.h index 36b25b81d..bedf3e596 100644 --- a/src/citra_qt/debugger/graphics.h +++ b/src/citra_qt/debugger/graphics.h @@ -6,11 +6,10 @@ #include <QAbstractListModel> #include <QDockWidget> - #include "video_core/gpu_debugger.h" -class GPUCommandStreamItemModel : public QAbstractListModel, public GraphicsDebugger::DebuggerObserver -{ +class GPUCommandStreamItemModel : public QAbstractListModel, + public GraphicsDebugger::DebuggerObserver { Q_OBJECT public: @@ -32,8 +31,7 @@ private: int command_count; }; -class GPUCommandStreamWidget : public QDockWidget -{ +class GPUCommandStreamWidget : public QDockWidget { Q_OBJECT public: diff --git a/src/citra_qt/debugger/graphics_breakpoint_observer.cpp b/src/citra_qt/debugger/graphics_breakpoint_observer.cpp index f134eef63..e01d3440e 100644 --- a/src/citra_qt/debugger/graphics_breakpoint_observer.cpp +++ b/src/citra_qt/debugger/graphics_breakpoint_observer.cpp @@ -3,30 +3,25 @@ // Refer to the license.txt file included. #include <QMetaType> - #include "citra_qt/debugger/graphics_breakpoint_observer.h" BreakPointObserverDock::BreakPointObserverDock(std::shared_ptr<Pica::DebugContext> debug_context, const QString& title, QWidget* parent) - : QDockWidget(title, parent), BreakPointObserver(debug_context) -{ + : QDockWidget(title, parent), BreakPointObserver(debug_context) { qRegisterMetaType<Pica::DebugContext::Event>("Pica::DebugContext::Event"); connect(this, SIGNAL(Resumed()), this, SLOT(OnResumed())); // NOTE: This signal is emitted from a non-GUI thread, but connect() takes // care of delaying its handling to the GUI thread. - connect(this, SIGNAL(BreakPointHit(Pica::DebugContext::Event,void*)), - this, SLOT(OnBreakPointHit(Pica::DebugContext::Event,void*)), - Qt::BlockingQueuedConnection); + connect(this, SIGNAL(BreakPointHit(Pica::DebugContext::Event, void*)), this, + SLOT(OnBreakPointHit(Pica::DebugContext::Event, void*)), Qt::BlockingQueuedConnection); } -void BreakPointObserverDock::OnPicaBreakPointHit(Pica::DebugContext::Event event, void* data) -{ +void BreakPointObserverDock::OnPicaBreakPointHit(Pica::DebugContext::Event event, void* data) { emit BreakPointHit(event, data); } -void BreakPointObserverDock::OnPicaResume() -{ +void BreakPointObserverDock::OnPicaResume() { emit Resumed(); } diff --git a/src/citra_qt/debugger/graphics_breakpoint_observer.h b/src/citra_qt/debugger/graphics_breakpoint_observer.h index 02a0f4f4f..e77df4f5b 100644 --- a/src/citra_qt/debugger/graphics_breakpoint_observer.h +++ b/src/citra_qt/debugger/graphics_breakpoint_observer.h @@ -5,7 +5,6 @@ #pragma once #include <QDockWidget> - #include "video_core/debug_utils/debug_utils.h" /** @@ -13,7 +12,8 @@ * This is because the Pica breakpoint callbacks are called from a non-GUI thread, while * the widget usually wants to perform reactions in the GUI thread. */ -class BreakPointObserverDock : public QDockWidget, protected Pica::DebugContext::BreakPointObserver { +class BreakPointObserverDock : public QDockWidget, + protected Pica::DebugContext::BreakPointObserver { Q_OBJECT public: diff --git a/src/citra_qt/debugger/graphics_breakpoints.cpp b/src/citra_qt/debugger/graphics_breakpoints.cpp index fe66918a8..d2a036dfa 100644 --- a/src/citra_qt/debugger/graphics_breakpoints.cpp +++ b/src/citra_qt/debugger/graphics_breakpoints.cpp @@ -7,47 +7,39 @@ #include <QPushButton> #include <QTreeView> #include <QVBoxLayout> - #include "citra_qt/debugger/graphics_breakpoints.h" #include "citra_qt/debugger/graphics_breakpoints_p.h" - #include "common/assert.h" BreakPointModel::BreakPointModel(std::shared_ptr<Pica::DebugContext> debug_context, QObject* parent) : QAbstractListModel(parent), context_weak(debug_context), at_breakpoint(debug_context->at_breakpoint), - active_breakpoint(debug_context->active_breakpoint) -{ - -} + active_breakpoint(debug_context->active_breakpoint) {} -int BreakPointModel::columnCount(const QModelIndex& parent) const -{ +int BreakPointModel::columnCount(const QModelIndex& parent) const { return 1; } -int BreakPointModel::rowCount(const QModelIndex& parent) const -{ +int BreakPointModel::rowCount(const QModelIndex& parent) const { return static_cast<int>(Pica::DebugContext::Event::NumEvents); } -QVariant BreakPointModel::data(const QModelIndex& index, int role) const -{ +QVariant BreakPointModel::data(const QModelIndex& index, int role) const { const auto event = static_cast<Pica::DebugContext::Event>(index.row()); switch (role) { - case Qt::DisplayRole: - { + case Qt::DisplayRole: { if (index.column() == 0) { static const std::map<Pica::DebugContext::Event, QString> map = { - { Pica::DebugContext::Event::PicaCommandLoaded, tr("Pica command loaded") }, - { Pica::DebugContext::Event::PicaCommandProcessed, tr("Pica command processed") }, - { Pica::DebugContext::Event::IncomingPrimitiveBatch, tr("Incoming primitive batch") }, - { Pica::DebugContext::Event::FinishedPrimitiveBatch, tr("Finished primitive batch") }, - { Pica::DebugContext::Event::VertexShaderInvocation, tr("Vertex shader invocation") }, - { Pica::DebugContext::Event::IncomingDisplayTransfer, tr("Incoming display transfer") }, - { Pica::DebugContext::Event::GSPCommandProcessed, tr("GSP command processed") }, - { Pica::DebugContext::Event::BufferSwapped, tr("Buffers swapped") } + {Pica::DebugContext::Event::PicaCommandLoaded, tr("Pica command loaded")}, + {Pica::DebugContext::Event::PicaCommandProcessed, tr("Pica command processed")}, + {Pica::DebugContext::Event::IncomingPrimitiveBatch, tr("Incoming primitive batch")}, + {Pica::DebugContext::Event::FinishedPrimitiveBatch, tr("Finished primitive batch")}, + {Pica::DebugContext::Event::VertexShaderInvocation, tr("Vertex shader invocation")}, + {Pica::DebugContext::Event::IncomingDisplayTransfer, + tr("Incoming display transfer")}, + {Pica::DebugContext::Event::GSPCommandProcessed, tr("GSP command processed")}, + {Pica::DebugContext::Event::BufferSwapped, tr("Buffers swapped")}, }; DEBUG_ASSERT(map.size() == static_cast<size_t>(Pica::DebugContext::Event::NumEvents)); @@ -57,23 +49,20 @@ QVariant BreakPointModel::data(const QModelIndex& index, int role) const break; } - case Qt::CheckStateRole: - { + case Qt::CheckStateRole: { if (index.column() == 0) return data(index, Role_IsEnabled).toBool() ? Qt::Checked : Qt::Unchecked; break; } - case Qt::BackgroundRole: - { + case Qt::BackgroundRole: { if (at_breakpoint && index.row() == static_cast<int>(active_breakpoint)) { return QBrush(QColor(0xE0, 0xE0, 0x10)); } break; } - case Role_IsEnabled: - { + case Role_IsEnabled: { auto context = context_weak.lock(); return context && context->breakpoints[(int)event].enabled; } @@ -84,8 +73,7 @@ QVariant BreakPointModel::data(const QModelIndex& index, int role) const return QVariant(); } -Qt::ItemFlags BreakPointModel::flags(const QModelIndex &index) const -{ +Qt::ItemFlags BreakPointModel::flags(const QModelIndex& index) const { if (!index.isValid()) return 0; @@ -95,14 +83,11 @@ Qt::ItemFlags BreakPointModel::flags(const QModelIndex &index) const return flags; } - -bool BreakPointModel::setData(const QModelIndex& index, const QVariant& value, int role) -{ +bool BreakPointModel::setData(const QModelIndex& index, const QVariant& value, int role) { const auto event = static_cast<Pica::DebugContext::Event>(index.row()); switch (role) { - case Qt::CheckStateRole: - { + case Qt::CheckStateRole: { if (index.column() != 0) return false; @@ -120,9 +105,7 @@ bool BreakPointModel::setData(const QModelIndex& index, const QVariant& value, i return false; } - -void BreakPointModel::OnBreakPointHit(Pica::DebugContext::Event event) -{ +void BreakPointModel::OnBreakPointHit(Pica::DebugContext::Event event) { auto context = context_weak.lock(); if (!context) return; @@ -133,8 +116,7 @@ void BreakPointModel::OnBreakPointHit(Pica::DebugContext::Event event) createIndex(static_cast<int>(event), 0)); } -void BreakPointModel::OnResumed() -{ +void BreakPointModel::OnResumed() { auto context = context_weak.lock(); if (!context) return; @@ -145,12 +127,10 @@ void BreakPointModel::OnResumed() active_breakpoint = context->active_breakpoint; } - -GraphicsBreakPointsWidget::GraphicsBreakPointsWidget(std::shared_ptr<Pica::DebugContext> debug_context, - QWidget* parent) +GraphicsBreakPointsWidget::GraphicsBreakPointsWidget( + std::shared_ptr<Pica::DebugContext> debug_context, QWidget* parent) : QDockWidget(tr("Pica Breakpoints"), parent), - Pica::DebugContext::BreakPointObserver(debug_context) -{ + Pica::DebugContext::BreakPointObserver(debug_context) { setObjectName("PicaBreakPointsWidget"); status_text = new QLabel(tr("Emulation running")); @@ -165,23 +145,21 @@ GraphicsBreakPointsWidget::GraphicsBreakPointsWidget(std::shared_ptr<Pica::Debug qRegisterMetaType<Pica::DebugContext::Event>("Pica::DebugContext::Event"); - connect(breakpoint_list, SIGNAL(doubleClicked(const QModelIndex&)), - this, SLOT(OnItemDoubleClicked(const QModelIndex&))); + connect(breakpoint_list, SIGNAL(doubleClicked(const QModelIndex&)), this, + SLOT(OnItemDoubleClicked(const QModelIndex&))); connect(resume_button, SIGNAL(clicked()), this, SLOT(OnResumeRequested())); - connect(this, SIGNAL(BreakPointHit(Pica::DebugContext::Event,void*)), - this, SLOT(OnBreakPointHit(Pica::DebugContext::Event,void*)), - Qt::BlockingQueuedConnection); + connect(this, SIGNAL(BreakPointHit(Pica::DebugContext::Event, void*)), this, + SLOT(OnBreakPointHit(Pica::DebugContext::Event, void*)), Qt::BlockingQueuedConnection); connect(this, SIGNAL(Resumed()), this, SLOT(OnResumed())); - connect(this, SIGNAL(BreakPointHit(Pica::DebugContext::Event,void*)), - breakpoint_model, SLOT(OnBreakPointHit(Pica::DebugContext::Event)), - Qt::BlockingQueuedConnection); + connect(this, SIGNAL(BreakPointHit(Pica::DebugContext::Event, void*)), breakpoint_model, + SLOT(OnBreakPointHit(Pica::DebugContext::Event)), Qt::BlockingQueuedConnection); connect(this, SIGNAL(Resumed()), breakpoint_model, SLOT(OnResumed())); - connect(this, SIGNAL(BreakPointsChanged(const QModelIndex&,const QModelIndex&)), - breakpoint_model, SIGNAL(dataChanged(const QModelIndex&,const QModelIndex&))); + connect(this, SIGNAL(BreakPointsChanged(const QModelIndex&, const QModelIndex&)), + breakpoint_model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&))); QWidget* main_widget = new QWidget; auto main_layout = new QVBoxLayout; @@ -197,38 +175,32 @@ GraphicsBreakPointsWidget::GraphicsBreakPointsWidget(std::shared_ptr<Pica::Debug setWidget(main_widget); } -void GraphicsBreakPointsWidget::OnPicaBreakPointHit(Event event, void* data) -{ +void GraphicsBreakPointsWidget::OnPicaBreakPointHit(Event event, void* data) { // Process in GUI thread emit BreakPointHit(event, data); } -void GraphicsBreakPointsWidget::OnBreakPointHit(Pica::DebugContext::Event event, void* data) -{ +void GraphicsBreakPointsWidget::OnBreakPointHit(Pica::DebugContext::Event event, void* data) { status_text->setText(tr("Emulation halted at breakpoint")); resume_button->setEnabled(true); } -void GraphicsBreakPointsWidget::OnPicaResume() -{ +void GraphicsBreakPointsWidget::OnPicaResume() { // Process in GUI thread emit Resumed(); } -void GraphicsBreakPointsWidget::OnResumed() -{ +void GraphicsBreakPointsWidget::OnResumed() { status_text->setText(tr("Emulation running")); resume_button->setEnabled(false); } -void GraphicsBreakPointsWidget::OnResumeRequested() -{ +void GraphicsBreakPointsWidget::OnResumeRequested() { if (auto context = context_weak.lock()) context->Resume(); } -void GraphicsBreakPointsWidget::OnItemDoubleClicked(const QModelIndex& index) -{ +void GraphicsBreakPointsWidget::OnItemDoubleClicked(const QModelIndex& index) { if (!index.isValid()) return; diff --git a/src/citra_qt/debugger/graphics_breakpoints.h b/src/citra_qt/debugger/graphics_breakpoints.h index 2371b0e39..5fc40c916 100644 --- a/src/citra_qt/debugger/graphics_breakpoints.h +++ b/src/citra_qt/debugger/graphics_breakpoints.h @@ -5,9 +5,7 @@ #pragma once #include <memory> - #include <QDockWidget> - #include "video_core/debug_utils/debug_utils.h" class QLabel; diff --git a/src/citra_qt/debugger/graphics_breakpoints_p.h b/src/citra_qt/debugger/graphics_breakpoints_p.h index 251114d06..dc64706bd 100644 --- a/src/citra_qt/debugger/graphics_breakpoints_p.h +++ b/src/citra_qt/debugger/graphics_breakpoints_p.h @@ -5,9 +5,7 @@ #pragma once #include <memory> - #include <QAbstractListModel> - #include "video_core/debug_utils/debug_utils.h" class BreakPointModel : public QAbstractListModel { @@ -23,7 +21,7 @@ public: int columnCount(const QModelIndex& parent = QModelIndex()) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - Qt::ItemFlags flags(const QModelIndex &index) const override; + Qt::ItemFlags flags(const QModelIndex& index) const override; bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; diff --git a/src/citra_qt/debugger/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics_cmdlists.cpp index 3e0a0a145..8a784d108 100644 --- a/src/citra_qt/debugger/graphics_cmdlists.cpp +++ b/src/citra_qt/debugger/graphics_cmdlists.cpp @@ -13,16 +13,13 @@ #include <QSpinBox> #include <QTreeView> #include <QVBoxLayout> - #include "citra_qt/debugger/graphics_cmdlists.h" #include "citra_qt/util/spinbox.h" #include "citra_qt/util/util.h" - #include "common/vector_math.h" - +#include "video_core/debug_utils/debug_utils.h" #include "video_core/pica.h" #include "video_core/pica_state.h" -#include "video_core/debug_utils/debug_utils.h" QImage LoadTexture(u8* src, const Pica::DebugUtils::TextureInfo& info) { QImage decoded_image(info.width, info.height, QImage::Format_ARGB32); @@ -38,7 +35,8 @@ QImage LoadTexture(u8* src, const Pica::DebugUtils::TextureInfo& info) { class TextureInfoWidget : public QWidget { public: - TextureInfoWidget(u8* src, const Pica::DebugUtils::TextureInfo& info, QWidget* parent = nullptr) : QWidget(parent) { + TextureInfoWidget(u8* src, const Pica::DebugUtils::TextureInfo& info, QWidget* parent = nullptr) + : QWidget(parent) { QLabel* image_widget = new QLabel; QPixmap image_pixmap = QPixmap::fromImage(LoadTexture(src, info)); image_pixmap = image_pixmap.scaled(200, 100, Qt::KeepAspectRatio, Qt::SmoothTransformation); @@ -50,9 +48,7 @@ public: } }; -GPUCommandListModel::GPUCommandListModel(QObject* parent) : QAbstractListModel(parent) { - -} +GPUCommandListModel::GPUCommandListModel(QObject* parent) : QAbstractListModel(parent) {} int GPUCommandListModel::rowCount(const QModelIndex& parent) const { return static_cast<int>(pica_trace.writes.size()); @@ -70,7 +66,7 @@ QVariant GPUCommandListModel::data(const QModelIndex& index, int role) const { if (role == Qt::DisplayRole) { QString content; - switch ( index.column() ) { + switch (index.column()) { case 0: return QString::fromLatin1(Pica::Regs::GetCommandName(write.cmd_id).c_str()); case 1: @@ -88,9 +84,8 @@ QVariant GPUCommandListModel::data(const QModelIndex& index, int role) const { } QVariant GPUCommandListModel::headerData(int section, Qt::Orientation orientation, int role) const { - switch(role) { - case Qt::DisplayRole: - { + switch (role) { + case Qt::DisplayRole: { switch (section) { case 0: return tr("Command Name"); @@ -117,14 +112,14 @@ void GPUCommandListModel::OnPicaTraceFinished(const Pica::DebugUtils::PicaTrace& endResetModel(); } -#define COMMAND_IN_RANGE(cmd_id, reg_name) \ - (cmd_id >= PICA_REG_INDEX(reg_name) && \ +#define COMMAND_IN_RANGE(cmd_id, reg_name) \ + (cmd_id >= PICA_REG_INDEX(reg_name) && \ cmd_id < PICA_REG_INDEX(reg_name) + sizeof(decltype(Pica::g_state.regs.reg_name)) / 4) void GPUCommandListWidget::OnCommandDoubleClicked(const QModelIndex& index) { - const unsigned int command_id = list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toUInt(); - if (COMMAND_IN_RANGE(command_id, texture0) || - COMMAND_IN_RANGE(command_id, texture1) || + const unsigned int command_id = + list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toUInt(); + if (COMMAND_IN_RANGE(command_id, texture0) || COMMAND_IN_RANGE(command_id, texture1) || COMMAND_IN_RANGE(command_id, texture2)) { unsigned index; @@ -148,9 +143,9 @@ void GPUCommandListWidget::OnCommandDoubleClicked(const QModelIndex& index) { void GPUCommandListWidget::SetCommandInfo(const QModelIndex& index) { QWidget* new_info_widget = nullptr; - const unsigned int command_id = list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toUInt(); - if (COMMAND_IN_RANGE(command_id, texture0) || - COMMAND_IN_RANGE(command_id, texture1) || + const unsigned int command_id = + list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toUInt(); + if (COMMAND_IN_RANGE(command_id, texture0) || COMMAND_IN_RANGE(command_id, texture1) || COMMAND_IN_RANGE(command_id, texture2)) { unsigned index; @@ -179,7 +174,8 @@ void GPUCommandListWidget::SetCommandInfo(const QModelIndex& index) { } #undef COMMAND_IN_RANGE -GPUCommandListWidget::GPUCommandListWidget(QWidget* parent) : QDockWidget(tr("Pica Command List"), parent) { +GPUCommandListWidget::GPUCommandListWidget(QWidget* parent) + : QDockWidget(tr("Pica Command List"), parent) { setObjectName("Pica Command List"); GPUCommandListModel* model = new GPUCommandListModel(this); @@ -191,23 +187,24 @@ GPUCommandListWidget::GPUCommandListWidget(QWidget* parent) : QDockWidget(tr("Pi list_widget->setRootIsDecorated(false); list_widget->setUniformRowHeights(true); -#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) list_widget->header()->setSectionResizeMode(QHeaderView::ResizeToContents); #else list_widget->header()->setResizeMode(QHeaderView::ResizeToContents); #endif - connect(list_widget->selectionModel(), SIGNAL(currentChanged(const QModelIndex&,const QModelIndex&)), - this, SLOT(SetCommandInfo(const QModelIndex&))); - connect(list_widget, SIGNAL(doubleClicked(const QModelIndex&)), - this, SLOT(OnCommandDoubleClicked(const QModelIndex&))); + connect(list_widget->selectionModel(), + SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), this, + SLOT(SetCommandInfo(const QModelIndex&))); + connect(list_widget, SIGNAL(doubleClicked(const QModelIndex&)), this, + SLOT(OnCommandDoubleClicked(const QModelIndex&))); toggle_tracing = new QPushButton(tr("Start Tracing")); QPushButton* copy_all = new QPushButton(tr("Copy All")); connect(toggle_tracing, SIGNAL(clicked()), this, SLOT(OnToggleTracing())); - connect(this, SIGNAL(TracingFinished(const Pica::DebugUtils::PicaTrace&)), - model, SLOT(OnPicaTraceFinished(const Pica::DebugUtils::PicaTrace&))); + connect(this, SIGNAL(TracingFinished(const Pica::DebugUtils::PicaTrace&)), model, + SLOT(OnPicaTraceFinished(const Pica::DebugUtils::PicaTrace&))); connect(copy_all, SIGNAL(clicked()), this, SLOT(CopyAllToClipboard())); diff --git a/src/citra_qt/debugger/graphics_cmdlists.h b/src/citra_qt/debugger/graphics_cmdlists.h index 8a2a294b9..fa2b9122b 100644 --- a/src/citra_qt/debugger/graphics_cmdlists.h +++ b/src/citra_qt/debugger/graphics_cmdlists.h @@ -6,15 +6,13 @@ #include <QAbstractListModel> #include <QDockWidget> - -#include "video_core/gpu_debugger.h" #include "video_core/debug_utils/debug_utils.h" +#include "video_core/gpu_debugger.h" class QPushButton; class QTreeView; -class GPUCommandListModel : public QAbstractListModel -{ +class GPUCommandListModel : public QAbstractListModel { Q_OBJECT public: @@ -27,7 +25,8 @@ public: int columnCount(const QModelIndex& parent = QModelIndex()) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const override; public slots: void OnPicaTraceFinished(const Pica::DebugUtils::PicaTrace& trace); @@ -36,8 +35,7 @@ private: Pica::DebugUtils::PicaTrace pica_trace; }; -class GPUCommandListWidget : public QDockWidget -{ +class GPUCommandListWidget : public QDockWidget { Q_OBJECT public: diff --git a/src/citra_qt/debugger/graphics_surface.cpp b/src/citra_qt/debugger/graphics_surface.cpp index ac2d6f89b..906daaa50 100644 --- a/src/citra_qt/debugger/graphics_surface.cpp +++ b/src/citra_qt/debugger/graphics_surface.cpp @@ -11,24 +11,20 @@ #include <QPushButton> #include <QScrollArea> #include <QSpinBox> - #include "citra_qt/debugger/graphics_surface.h" #include "citra_qt/util/spinbox.h" - #include "common/color.h" - -#include "core/memory.h" #include "core/hw/gpu.h" - +#include "core/memory.h" #include "video_core/pica.h" #include "video_core/pica_state.h" #include "video_core/utils.h" -SurfacePicture::SurfacePicture(QWidget* parent, GraphicsSurfaceWidget* surface_widget_) : QLabel(parent), surface_widget(surface_widget_) {} +SurfacePicture::SurfacePicture(QWidget* parent, GraphicsSurfaceWidget* surface_widget_) + : QLabel(parent), surface_widget(surface_widget_) {} SurfacePicture::~SurfacePicture() {} -void SurfacePicture::mousePressEvent(QMouseEvent* event) -{ +void SurfacePicture::mousePressEvent(QMouseEvent* event) { // Only do something while the left mouse button is held down if (!(event->buttons() & Qt::LeftButton)) return; @@ -41,18 +37,15 @@ void SurfacePicture::mousePressEvent(QMouseEvent* event) event->y() * pixmap()->height() / height()); } -void SurfacePicture::mouseMoveEvent(QMouseEvent* event) -{ +void SurfacePicture::mouseMoveEvent(QMouseEvent* event) { // We also want to handle the event if the user moves the mouse while holding down the LMB mousePressEvent(event); } - GraphicsSurfaceWidget::GraphicsSurfaceWidget(std::shared_ptr<Pica::DebugContext> debug_context, - QWidget* parent) + QWidget* parent) : BreakPointObserverDock(debug_context, tr("Pica Surface Viewer"), parent), - surface_source(Source::ColorBuffer) -{ + surface_source(Source::ColorBuffer) { setObjectName("PicaSurface"); surface_source_list = new QComboBox; @@ -124,13 +117,20 @@ GraphicsSurfaceWidget::GraphicsSurfaceWidget(std::shared_ptr<Pica::DebugContext> // Connections connect(this, SIGNAL(Update()), this, SLOT(OnUpdate())); - connect(surface_source_list, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSurfaceSourceChanged(int))); - connect(surface_address_control, SIGNAL(ValueChanged(qint64)), this, SLOT(OnSurfaceAddressChanged(qint64))); - connect(surface_width_control, SIGNAL(valueChanged(int)), this, SLOT(OnSurfaceWidthChanged(int))); - connect(surface_height_control, SIGNAL(valueChanged(int)), this, SLOT(OnSurfaceHeightChanged(int))); - connect(surface_format_control, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSurfaceFormatChanged(int))); - connect(surface_picker_x_control, SIGNAL(valueChanged(int)), this, SLOT(OnSurfacePickerXChanged(int))); - connect(surface_picker_y_control, SIGNAL(valueChanged(int)), this, SLOT(OnSurfacePickerYChanged(int))); + connect(surface_source_list, SIGNAL(currentIndexChanged(int)), this, + SLOT(OnSurfaceSourceChanged(int))); + connect(surface_address_control, SIGNAL(ValueChanged(qint64)), this, + SLOT(OnSurfaceAddressChanged(qint64))); + connect(surface_width_control, SIGNAL(valueChanged(int)), this, + SLOT(OnSurfaceWidthChanged(int))); + connect(surface_height_control, SIGNAL(valueChanged(int)), this, + SLOT(OnSurfaceHeightChanged(int))); + connect(surface_format_control, SIGNAL(currentIndexChanged(int)), this, + SLOT(OnSurfaceFormatChanged(int))); + connect(surface_picker_x_control, SIGNAL(valueChanged(int)), this, + SLOT(OnSurfacePickerXChanged(int))); + connect(surface_picker_y_control, SIGNAL(valueChanged(int)), this, + SLOT(OnSurfacePickerYChanged(int))); connect(save_surface, SIGNAL(clicked()), this, SLOT(SaveSurface())); auto main_widget = new QWidget; @@ -203,25 +203,21 @@ GraphicsSurfaceWidget::GraphicsSurfaceWidget(std::shared_ptr<Pica::DebugContext> } } -void GraphicsSurfaceWidget::OnBreakPointHit(Pica::DebugContext::Event event, void* data) -{ +void GraphicsSurfaceWidget::OnBreakPointHit(Pica::DebugContext::Event event, void* data) { emit Update(); widget()->setEnabled(true); } -void GraphicsSurfaceWidget::OnResumed() -{ +void GraphicsSurfaceWidget::OnResumed() { widget()->setEnabled(false); } -void GraphicsSurfaceWidget::OnSurfaceSourceChanged(int new_value) -{ +void GraphicsSurfaceWidget::OnSurfaceSourceChanged(int new_value) { surface_source = static_cast<Source>(new_value); emit Update(); } -void GraphicsSurfaceWidget::OnSurfaceAddressChanged(qint64 new_value) -{ +void GraphicsSurfaceWidget::OnSurfaceAddressChanged(qint64 new_value) { if (surface_address != new_value) { surface_address = static_cast<unsigned>(new_value); @@ -230,8 +226,7 @@ void GraphicsSurfaceWidget::OnSurfaceAddressChanged(qint64 new_value) } } -void GraphicsSurfaceWidget::OnSurfaceWidthChanged(int new_value) -{ +void GraphicsSurfaceWidget::OnSurfaceWidthChanged(int new_value) { if (surface_width != static_cast<unsigned>(new_value)) { surface_width = static_cast<unsigned>(new_value); @@ -240,8 +235,7 @@ void GraphicsSurfaceWidget::OnSurfaceWidthChanged(int new_value) } } -void GraphicsSurfaceWidget::OnSurfaceHeightChanged(int new_value) -{ +void GraphicsSurfaceWidget::OnSurfaceHeightChanged(int new_value) { if (surface_height != static_cast<unsigned>(new_value)) { surface_height = static_cast<unsigned>(new_value); @@ -250,8 +244,7 @@ void GraphicsSurfaceWidget::OnSurfaceHeightChanged(int new_value) } } -void GraphicsSurfaceWidget::OnSurfaceFormatChanged(int new_value) -{ +void GraphicsSurfaceWidget::OnSurfaceFormatChanged(int new_value) { if (surface_format != static_cast<Format>(new_value)) { surface_format = static_cast<Format>(new_value); @@ -260,24 +253,21 @@ void GraphicsSurfaceWidget::OnSurfaceFormatChanged(int new_value) } } -void GraphicsSurfaceWidget::OnSurfacePickerXChanged(int new_value) -{ +void GraphicsSurfaceWidget::OnSurfacePickerXChanged(int new_value) { if (surface_picker_x != new_value) { surface_picker_x = new_value; Pick(surface_picker_x, surface_picker_y); } } -void GraphicsSurfaceWidget::OnSurfacePickerYChanged(int new_value) -{ +void GraphicsSurfaceWidget::OnSurfacePickerYChanged(int new_value) { if (surface_picker_y != new_value) { surface_picker_y = new_value; Pick(surface_picker_x, surface_picker_y); } } -void GraphicsSurfaceWidget::Pick(int x, int y) -{ +void GraphicsSurfaceWidget::Pick(int x, int y) { surface_picker_x_control->setValue(x); surface_picker_y_control->setValue(y); @@ -312,74 +302,63 @@ void GraphicsSurfaceWidget::Pick(int x, int y) auto GetText = [offset](Format format, const u8* pixel) { switch (format) { - case Format::RGBA8: - { + case Format::RGBA8: { auto value = Color::DecodeRGBA8(pixel) / 255.0f; return QString("Red: %1, Green: %2, Blue: %3, Alpha: %4") - .arg(QString::number(value.r(), 'f', 2)) - .arg(QString::number(value.g(), 'f', 2)) - .arg(QString::number(value.b(), 'f', 2)) - .arg(QString::number(value.a(), 'f', 2)); + .arg(QString::number(value.r(), 'f', 2)) + .arg(QString::number(value.g(), 'f', 2)) + .arg(QString::number(value.b(), 'f', 2)) + .arg(QString::number(value.a(), 'f', 2)); } - case Format::RGB8: - { + case Format::RGB8: { auto value = Color::DecodeRGB8(pixel) / 255.0f; return QString("Red: %1, Green: %2, Blue: %3") - .arg(QString::number(value.r(), 'f', 2)) - .arg(QString::number(value.g(), 'f', 2)) - .arg(QString::number(value.b(), 'f', 2)); + .arg(QString::number(value.r(), 'f', 2)) + .arg(QString::number(value.g(), 'f', 2)) + .arg(QString::number(value.b(), 'f', 2)); } - case Format::RGB5A1: - { + case Format::RGB5A1: { auto value = Color::DecodeRGB5A1(pixel) / 255.0f; return QString("Red: %1, Green: %2, Blue: %3, Alpha: %4") - .arg(QString::number(value.r(), 'f', 2)) - .arg(QString::number(value.g(), 'f', 2)) - .arg(QString::number(value.b(), 'f', 2)) - .arg(QString::number(value.a(), 'f', 2)); + .arg(QString::number(value.r(), 'f', 2)) + .arg(QString::number(value.g(), 'f', 2)) + .arg(QString::number(value.b(), 'f', 2)) + .arg(QString::number(value.a(), 'f', 2)); } - case Format::RGB565: - { + case Format::RGB565: { auto value = Color::DecodeRGB565(pixel) / 255.0f; return QString("Red: %1, Green: %2, Blue: %3") - .arg(QString::number(value.r(), 'f', 2)) - .arg(QString::number(value.g(), 'f', 2)) - .arg(QString::number(value.b(), 'f', 2)); + .arg(QString::number(value.r(), 'f', 2)) + .arg(QString::number(value.g(), 'f', 2)) + .arg(QString::number(value.b(), 'f', 2)); } - case Format::RGBA4: - { + case Format::RGBA4: { auto value = Color::DecodeRGBA4(pixel) / 255.0f; return QString("Red: %1, Green: %2, Blue: %3, Alpha: %4") - .arg(QString::number(value.r(), 'f', 2)) - .arg(QString::number(value.g(), 'f', 2)) - .arg(QString::number(value.b(), 'f', 2)) - .arg(QString::number(value.a(), 'f', 2)); + .arg(QString::number(value.r(), 'f', 2)) + .arg(QString::number(value.g(), 'f', 2)) + .arg(QString::number(value.b(), 'f', 2)) + .arg(QString::number(value.a(), 'f', 2)); } case Format::IA8: - return QString("Index: %1, Alpha: %2") - .arg(pixel[0]) - .arg(pixel[1]); + return QString("Index: %1, Alpha: %2").arg(pixel[0]).arg(pixel[1]); case Format::RG8: { auto value = Color::DecodeRG8(pixel) / 255.0f; return QString("Red: %1, Green: %2") - .arg(QString::number(value.r(), 'f', 2)) - .arg(QString::number(value.g(), 'f', 2)); + .arg(QString::number(value.r(), 'f', 2)) + .arg(QString::number(value.g(), 'f', 2)); } case Format::I8: return QString("Index: %1").arg(*pixel); case Format::A8: return QString("Alpha: %1").arg(QString::number(*pixel / 255.0f, 'f', 2)); case Format::IA4: - return QString("Index: %1, Alpha: %2") - .arg(*pixel & 0xF) - .arg((*pixel & 0xF0) >> 4); - case Format::I4: - { + return QString("Index: %1, Alpha: %2").arg(*pixel & 0xF).arg((*pixel & 0xF0) >> 4); + case Format::I4: { u8 i = (*pixel >> ((offset % 2) ? 4 : 0)) & 0xF; return QString("Index: %1").arg(i); } - case Format::A4: - { + case Format::A4: { u8 a = (*pixel >> ((offset % 2) ? 4 : 0)) & 0xF; return QString("Alpha: %1").arg(QString::number(a / 15.0f, 'f', 2)); } @@ -387,21 +366,20 @@ void GraphicsSurfaceWidget::Pick(int x, int y) case Format::ETC1A4: // TODO: Display block information or channel values? return QString("Compressed data"); - case Format::D16: - { + case Format::D16: { auto value = Color::DecodeD16(pixel); return QString("Depth: %1").arg(QString::number(value / (float)0xFFFF, 'f', 4)); } - case Format::D24: - { + case Format::D24: { auto value = Color::DecodeD24(pixel); return QString("Depth: %1").arg(QString::number(value / (float)0xFFFFFF, 'f', 4)); } case Format::D24X8: - case Format::X24S8: - { + case Format::X24S8: { auto values = Color::DecodeD24S8(pixel); - return QString("Depth: %1, Stencil: %2").arg(QString::number(values[0] / (float)0xFFFFFF, 'f', 4)).arg(values[1]); + return QString("Depth: %1, Stencil: %2") + .arg(QString::number(values[0] / (float)0xFFFFFF, 'f', 4)) + .arg(values[1]); } case Format::Unknown: return QString("Unknown format"); @@ -422,18 +400,18 @@ void GraphicsSurfaceWidget::Pick(int x, int y) nibbles.append(QString::number(nibble, 16).toUpper()); } - surface_info_label->setText(QString("Raw: 0x%3\n(%4)").arg(nibbles).arg(GetText(surface_format, pixel))); + surface_info_label->setText( + QString("Raw: 0x%3\n(%4)").arg(nibbles).arg(GetText(surface_format, pixel))); surface_info_label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); } -void GraphicsSurfaceWidget::OnUpdate() -{ +void GraphicsSurfaceWidget::OnUpdate() { QPixmap pixmap; switch (surface_source) { - case Source::ColorBuffer: - { - // TODO: Store a reference to the registers in the debug context instead of accessing them directly... + case Source::ColorBuffer: { + // TODO: Store a reference to the registers in the debug context instead of accessing them + // directly... const auto& framebuffer = Pica::g_state.regs.framebuffer; @@ -470,8 +448,7 @@ void GraphicsSurfaceWidget::OnUpdate() break; } - case Source::DepthBuffer: - { + case Source::DepthBuffer: { const auto& framebuffer = Pica::g_state.regs.framebuffer; surface_address = framebuffer.GetDepthBufferPhysicalAddress(); @@ -499,8 +476,7 @@ void GraphicsSurfaceWidget::OnUpdate() break; } - case Source::StencilBuffer: - { + case Source::StencilBuffer: { const auto& framebuffer = Pica::g_state.regs.framebuffer; surface_address = framebuffer.GetDepthBufferPhysicalAddress(); @@ -522,12 +498,14 @@ void GraphicsSurfaceWidget::OnUpdate() case Source::Texture0: case Source::Texture1: - case Source::Texture2: - { + case Source::Texture2: { unsigned texture_index; - if (surface_source == Source::Texture0) texture_index = 0; - else if (surface_source == Source::Texture1) texture_index = 1; - else if (surface_source == Source::Texture2) texture_index = 2; + if (surface_source == Source::Texture0) + texture_index = 0; + else if (surface_source == Source::Texture1) + texture_index = 1; + else if (surface_source == Source::Texture2) + texture_index = 2; else { qDebug() << "Unknown texture source " << static_cast<int>(surface_source); break; @@ -547,8 +525,7 @@ void GraphicsSurfaceWidget::OnUpdate() break; } - case Source::Custom: - { + case Source::Custom: { // Keep user-specified values break; } @@ -613,7 +590,8 @@ void GraphicsSurfaceWidget::OnUpdate() } else { - ASSERT_MSG(nibbles_per_pixel >= 2, "Depth decoder only supports formats with at least one byte per pixel"); + ASSERT_MSG(nibbles_per_pixel >= 2, + "Depth decoder only supports formats with at least one byte per pixel"); unsigned bytes_per_pixel = nibbles_per_pixel / 2; for (unsigned int y = 0; y < surface_height; ++y) { @@ -621,34 +599,30 @@ void GraphicsSurfaceWidget::OnUpdate() const u32 coarse_y = y & ~7; u32 offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * stride; const u8* pixel = buffer + offset; - Math::Vec4<u8> color = { 0, 0, 0, 0 }; + Math::Vec4<u8> color = {0, 0, 0, 0}; - switch(surface_format) { - case Format::D16: - { + switch (surface_format) { + case Format::D16: { u32 data = Color::DecodeD16(pixel); color.r() = data & 0xFF; color.g() = (data >> 8) & 0xFF; break; } - case Format::D24: - { + case Format::D24: { u32 data = Color::DecodeD24(pixel); color.r() = data & 0xFF; color.g() = (data >> 8) & 0xFF; color.b() = (data >> 16) & 0xFF; break; } - case Format::D24X8: - { + case Format::D24X8: { Math::Vec2<u32> data = Color::DecodeD24S8(pixel); color.r() = data.x & 0xFF; color.g() = (data.x >> 8) & 0xFF; color.b() = (data.x >> 16) & 0xFF; break; } - case Format::X24S8: - { + case Format::X24S8: { Math::Vec2<u32> data = Color::DecodeD24S8(pixel); color.r() = color.g() = color.b() = data.y; break; @@ -661,7 +635,6 @@ void GraphicsSurfaceWidget::OnUpdate() decoded_image.setPixel(x, y, qRgba(color.r(), color.g(), color.b(), 255)); } } - } pixmap = QPixmap::fromImage(decoded_image); @@ -682,8 +655,10 @@ void GraphicsSurfaceWidget::SaveSurface() { QString bin_filter = tr("Binary data (*.bin)"); QString selectedFilter; - QString filename = QFileDialog::getSaveFileName(this, tr("Save Surface"), QString("texture-0x%1.png").arg(QString::number(surface_address, 16)), - QString("%1;;%2").arg(png_filter, bin_filter), &selectedFilter); + QString filename = QFileDialog::getSaveFileName( + this, tr("Save Surface"), + QString("texture-0x%1.png").arg(QString::number(surface_address, 16)), + QString("%1;;%2").arg(png_filter, bin_filter), &selectedFilter); if (filename.isEmpty()) { // If the user canceled the dialog, don't save anything. @@ -718,19 +693,18 @@ unsigned int GraphicsSurfaceWidget::NibblesPerPixel(GraphicsSurfaceWidget::Forma } switch (format) { - case Format::D24X8: - case Format::X24S8: - return 4 * 2; - case Format::D24: - return 3 * 2; - case Format::D16: - return 2 * 2; - default: - UNREACHABLE_MSG("GraphicsSurfaceWidget::BytesPerPixel: this " - "should not be reached as this function should " - "be given a format which is in " - "GraphicsSurfaceWidget::Format. Instead got %i", - static_cast<int>(format)); - return 0; + case Format::D24X8: + case Format::X24S8: + return 4 * 2; + case Format::D24: + return 3 * 2; + case Format::D16: + return 2 * 2; + default: + UNREACHABLE_MSG("GraphicsSurfaceWidget::BytesPerPixel: this should not be reached as this " + "function should be given a format which is in " + "GraphicsSurfaceWidget::Format. Instead got %i", + static_cast<int>(format)); + return 0; } } diff --git a/src/citra_qt/debugger/graphics_surface.h b/src/citra_qt/debugger/graphics_surface.h index 7c7f50e38..21e6b5b8b 100644 --- a/src/citra_qt/debugger/graphics_surface.h +++ b/src/citra_qt/debugger/graphics_surface.h @@ -4,10 +4,9 @@ #pragma once -#include "citra_qt/debugger/graphics_breakpoint_observer.h" - #include <QLabel> #include <QPushButton> +#include "citra_qt/debugger/graphics_breakpoint_observer.h" class QComboBox; class QSpinBox; @@ -15,8 +14,7 @@ class CSpinBox; class GraphicsSurfaceWidget; -class SurfacePicture : public QLabel -{ +class SurfacePicture : public QLabel { Q_OBJECT public: @@ -29,7 +27,6 @@ protected slots: private: GraphicsSurfaceWidget* surface_widget; - }; class GraphicsSurfaceWidget : public BreakPointObserverDock { @@ -38,43 +35,44 @@ class GraphicsSurfaceWidget : public BreakPointObserverDock { using Event = Pica::DebugContext::Event; enum class Source { - ColorBuffer = 0, - DepthBuffer = 1, + ColorBuffer = 0, + DepthBuffer = 1, StencilBuffer = 2, - Texture0 = 3, - Texture1 = 4, - Texture2 = 5, - Custom = 6, + Texture0 = 3, + Texture1 = 4, + Texture2 = 5, + Custom = 6, }; enum class Format { // These must match the TextureFormat type! - RGBA8 = 0, - RGB8 = 1, - RGB5A1 = 2, - RGB565 = 3, - RGBA4 = 4, - IA8 = 5, - RG8 = 6, ///< @note Also called HILO8 in 3DBrew. - I8 = 7, - A8 = 8, - IA4 = 9, - I4 = 10, - A4 = 11, - ETC1 = 12, // compressed - ETC1A4 = 13, + RGBA8 = 0, + RGB8 = 1, + RGB5A1 = 2, + RGB565 = 3, + RGBA4 = 4, + IA8 = 5, + RG8 = 6, ///< @note Also called HILO8 in 3DBrew. + I8 = 7, + A8 = 8, + IA4 = 9, + I4 = 10, + A4 = 11, + ETC1 = 12, // compressed + ETC1A4 = 13, MaxTextureFormat = 13, - D16 = 14, - D24 = 15, - D24X8 = 16, - X24S8 = 17, - Unknown = 18, + D16 = 14, + D24 = 15, + D24X8 = 16, + X24S8 = 17, + Unknown = 18, }; static unsigned int NibblesPerPixel(Format format); public: - GraphicsSurfaceWidget(std::shared_ptr<Pica::DebugContext> debug_context, QWidget* parent = nullptr); + GraphicsSurfaceWidget(std::shared_ptr<Pica::DebugContext> debug_context, + QWidget* parent = nullptr); void Pick(int x, int y); public slots: @@ -97,7 +95,6 @@ signals: void Update(); private: - QComboBox* surface_source_list; CSpinBox* surface_address_control; QSpinBox* surface_width_control; diff --git a/src/citra_qt/debugger/graphics_tracing.cpp b/src/citra_qt/debugger/graphics_tracing.cpp index 9c80f7ec9..5c6b74034 100644 --- a/src/citra_qt/debugger/graphics_tracing.cpp +++ b/src/citra_qt/debugger/graphics_tracing.cpp @@ -6,25 +6,18 @@ #include <array> #include <iterator> #include <memory> - -#include <boost/range/algorithm/copy.hpp> - #include <QBoxLayout> #include <QComboBox> #include <QFileDialog> #include <QMessageBox> #include <QPushButton> - +#include <boost/range/algorithm/copy.hpp> #include "citra_qt/debugger/graphics_tracing.h" - #include "common/common_types.h" - #include "core/hw/gpu.h" #include "core/hw/lcd.h" #include "core/tracer/recorder.h" - #include "nihstro/float24.h" - #include "video_core/pica.h" #include "video_core/pica_state.h" @@ -35,12 +28,16 @@ GraphicsTracingWidget::GraphicsTracingWidget(std::shared_ptr<Pica::DebugContext> setObjectName("CiTracing"); QPushButton* start_recording = new QPushButton(tr("Start Recording")); - QPushButton* stop_recording = new QPushButton(QIcon::fromTheme("document-save"), tr("Stop and Save")); + QPushButton* stop_recording = + new QPushButton(QIcon::fromTheme("document-save"), tr("Stop and Save")); QPushButton* abort_recording = new QPushButton(tr("Abort Recording")); - connect(this, SIGNAL(SetStartTracingButtonEnabled(bool)), start_recording, SLOT(setVisible(bool))); - connect(this, SIGNAL(SetStopTracingButtonEnabled(bool)), stop_recording, SLOT(setVisible(bool))); - connect(this, SIGNAL(SetAbortTracingButtonEnabled(bool)), abort_recording, SLOT(setVisible(bool))); + connect(this, SIGNAL(SetStartTracingButtonEnabled(bool)), start_recording, + SLOT(setVisible(bool))); + connect(this, SIGNAL(SetStopTracingButtonEnabled(bool)), stop_recording, + SLOT(setVisible(bool))); + connect(this, SIGNAL(SetAbortTracingButtonEnabled(bool)), abort_recording, + SLOT(setVisible(bool))); connect(start_recording, SIGNAL(clicked()), this, SLOT(StartRecording())); connect(stop_recording, SIGNAL(clicked()), this, SLOT(StopRecording())); connect(abort_recording, SIGNAL(clicked()), this, SLOT(AbortRecording())); @@ -74,26 +71,31 @@ void GraphicsTracingWidget::StartRecording() { std::array<u32, 4 * 16> default_attributes; for (unsigned i = 0; i < 16; ++i) { for (unsigned comp = 0; comp < 3; ++comp) { - default_attributes[4 * i + comp] = nihstro::to_float24(Pica::g_state.vs_default_attributes[i][comp].ToFloat32()); + default_attributes[4 * i + comp] = + nihstro::to_float24(Pica::g_state.vs_default_attributes[i][comp].ToFloat32()); } } std::array<u32, 4 * 96> vs_float_uniforms; for (unsigned i = 0; i < 96; ++i) for (unsigned comp = 0; comp < 3; ++comp) - vs_float_uniforms[4 * i + comp] = nihstro::to_float24(Pica::g_state.vs.uniforms.f[i][comp].ToFloat32()); + vs_float_uniforms[4 * i + comp] = + nihstro::to_float24(Pica::g_state.vs.uniforms.f[i][comp].ToFloat32()); CiTrace::Recorder::InitialState state; - std::copy_n((u32*)&GPU::g_regs, sizeof(GPU::g_regs) / sizeof(u32), std::back_inserter(state.gpu_registers)); - std::copy_n((u32*)&LCD::g_regs, sizeof(LCD::g_regs) / sizeof(u32), std::back_inserter(state.lcd_registers)); - std::copy_n((u32*)&Pica::g_state.regs, sizeof(Pica::g_state.regs) / sizeof(u32), std::back_inserter(state.pica_registers)); + std::copy_n((u32*)&GPU::g_regs, sizeof(GPU::g_regs) / sizeof(u32), + std::back_inserter(state.gpu_registers)); + std::copy_n((u32*)&LCD::g_regs, sizeof(LCD::g_regs) / sizeof(u32), + std::back_inserter(state.lcd_registers)); + std::copy_n((u32*)&Pica::g_state.regs, sizeof(Pica::g_state.regs) / sizeof(u32), + std::back_inserter(state.pica_registers)); boost::copy(default_attributes, std::back_inserter(state.default_attributes)); boost::copy(shader_binary, std::back_inserter(state.vs_program_binary)); boost::copy(swizzle_data, std::back_inserter(state.vs_swizzle_data)); boost::copy(vs_float_uniforms, std::back_inserter(state.vs_float_uniforms)); - //boost::copy(TODO: Not implemented, std::back_inserter(state.gs_program_binary)); - //boost::copy(TODO: Not implemented, std::back_inserter(state.gs_swizzle_data)); - //boost::copy(TODO: Not implemented, std::back_inserter(state.gs_float_uniforms)); + // boost::copy(TODO: Not implemented, std::back_inserter(state.gs_program_binary)); + // boost::copy(TODO: Not implemented, std::back_inserter(state.gs_swizzle_data)); + // boost::copy(TODO: Not implemented, std::back_inserter(state.gs_float_uniforms)); auto recorder = new CiTrace::Recorder(state); context->recorder = std::shared_ptr<CiTrace::Recorder>(recorder); @@ -156,11 +158,12 @@ void GraphicsTracingWidget::OnEmulationStopping() { if (!context) return; - if (context->recorder) { - auto reply = QMessageBox::question(this, tr("CiTracing still active"), - tr("A CiTrace is still being recorded. Do you want to save it? If not, all recorded data will be discarded."), - QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); + auto reply = + QMessageBox::question(this, tr("CiTracing still active"), + tr("A CiTrace is still being recorded. Do you want to save it? " + "If not, all recorded data will be discarded."), + QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if (reply == QMessageBox::Yes) { StopRecording(); diff --git a/src/citra_qt/debugger/graphics_tracing.h b/src/citra_qt/debugger/graphics_tracing.h index 753dfa914..e04a3dac3 100644 --- a/src/citra_qt/debugger/graphics_tracing.h +++ b/src/citra_qt/debugger/graphics_tracing.h @@ -12,7 +12,8 @@ class GraphicsTracingWidget : public BreakPointObserverDock { Q_OBJECT public: - GraphicsTracingWidget(std::shared_ptr<Pica::DebugContext> debug_context, QWidget* parent = nullptr); + GraphicsTracingWidget(std::shared_ptr<Pica::DebugContext> debug_context, + QWidget* parent = nullptr); private slots: void StartRecording(); diff --git a/src/citra_qt/debugger/graphics_vertex_shader.cpp b/src/citra_qt/debugger/graphics_vertex_shader.cpp index 391666d35..0b4320da5 100644 --- a/src/citra_qt/debugger/graphics_vertex_shader.cpp +++ b/src/citra_qt/debugger/graphics_vertex_shader.cpp @@ -4,7 +4,6 @@ #include <iomanip> #include <sstream> - #include <QBoxLayout> #include <QFileDialog> #include <QFormLayout> @@ -15,10 +14,8 @@ #include <QSignalMapper> #include <QSpinBox> #include <QTreeView> - #include "citra_qt/debugger/graphics_vertex_shader.h" #include "citra_qt/util/util.h" - #include "video_core/pica.h" #include "video_core/pica_state.h" #include "video_core/shader/shader.h" @@ -28,9 +25,8 @@ using nihstro::Instruction; using nihstro::SourceRegister; using nihstro::SwizzlePattern; -GraphicsVertexShaderModel::GraphicsVertexShaderModel(GraphicsVertexShaderWidget* parent): QAbstractTableModel(parent), par(parent) { - -} +GraphicsVertexShaderModel::GraphicsVertexShaderModel(GraphicsVertexShaderWidget* parent) + : QAbstractTableModel(parent), par(parent) {} int GraphicsVertexShaderModel::columnCount(const QModelIndex& parent) const { return 3; @@ -40,10 +36,10 @@ int GraphicsVertexShaderModel::rowCount(const QModelIndex& parent) const { return static_cast<int>(par->info.code.size()); } -QVariant GraphicsVertexShaderModel::headerData(int section, Qt::Orientation orientation, int role) const { - switch(role) { - case Qt::DisplayRole: - { +QVariant GraphicsVertexShaderModel::headerData(int section, Qt::Orientation orientation, + int role) const { + switch (role) { + case Qt::DisplayRole: { if (section == 0) { return tr("Offset"); } else if (section == 1) { @@ -69,8 +65,8 @@ static std::string SelectorToString(u32 selector) { } // e.g. "-c92[a0.x].xyzw" -static void print_input(std::ostringstream& output, const SourceRegister& input, - bool negate, const std::string& swizzle_mask, bool align = true, +static void print_input(std::ostringstream& output, const SourceRegister& input, bool negate, + const std::string& swizzle_mask, bool align = true, const std::string& address_register_name = std::string()) { if (align) output << std::setw(4) << std::right; @@ -83,20 +79,18 @@ static void print_input(std::ostringstream& output, const SourceRegister& input, QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) const { switch (role) { - case Qt::DisplayRole: - { + case Qt::DisplayRole: { switch (index.column()) { case 0: if (par->info.HasLabel(index.row())) return QString::fromStdString(par->info.GetLabel(index.row())); - return QString("%1").arg(4*index.row(), 4, 16, QLatin1Char('0')); + return QString("%1").arg(4 * index.row(), 4, 16, QLatin1Char('0')); case 1: return QString("%1").arg(par->info.code[index.row()].hex, 8, 16, QLatin1Char('0')); - case 2: - { + case 2: { std::ostringstream output; output.flags(std::ios::uppercase); @@ -117,8 +111,9 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con const Instruction instr = par->info.code[index.row()]; const OpCode opcode = instr.opcode; const OpCode::Info opcode_info = opcode.GetInfo(); - const u32 operand_desc_id = opcode_info.type == OpCode::Type::MultiplyAdd ? - instr.mad.operand_desc_id.Value() : instr.common.operand_desc_id.Value(); + const u32 operand_desc_id = opcode_info.type == OpCode::Type::MultiplyAdd + ? instr.mad.operand_desc_id.Value() + : instr.common.operand_desc_id.Value(); const SwizzlePattern swizzle = par->info.swizzle_info[operand_desc_id].pattern; // longest known instruction name: "setemit " @@ -136,15 +131,14 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con break; case OpCode::Type::Arithmetic: - case OpCode::Type::MultiplyAdd: - { + case OpCode::Type::MultiplyAdd: { // Use custom code for special instructions switch (opcode.EffectiveOpCode()) { - case OpCode::Id::CMP: - { + case OpCode::Id::CMP: { AlignToColumn(kOpcodeColumnWidth); - // NOTE: CMP always writes both cc components, so we do not consider the dest mask here. + // NOTE: CMP always writes both cc components, so we do not consider the dest + // mask here. output << " cc.xy"; AlignToColumn(kOutputColumnWidth); @@ -152,22 +146,29 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con SourceRegister src2 = instr.common.GetSrc2(false); output << ' '; - print_input(output, src1, swizzle.negate_src1, swizzle.SelectorToString(false).substr(0,1), false, instr.common.AddressRegisterName()); - output << ' ' << instr.common.compare_op.ToString(instr.common.compare_op.x) << ' '; - print_input(output, src2, swizzle.negate_src2, swizzle.SelectorToString(true).substr(0,1), false); + print_input(output, src1, swizzle.negate_src1, + swizzle.SelectorToString(false).substr(0, 1), false, + instr.common.AddressRegisterName()); + output << ' ' << instr.common.compare_op.ToString(instr.common.compare_op.x) + << ' '; + print_input(output, src2, swizzle.negate_src2, + swizzle.SelectorToString(true).substr(0, 1), false); output << ", "; - print_input(output, src1, swizzle.negate_src1, swizzle.SelectorToString(false).substr(1,1), false, instr.common.AddressRegisterName()); - output << ' ' << instr.common.compare_op.ToString(instr.common.compare_op.y) << ' '; - print_input(output, src2, swizzle.negate_src2, swizzle.SelectorToString(true).substr(1,1), false); + print_input(output, src1, swizzle.negate_src1, + swizzle.SelectorToString(false).substr(1, 1), false, + instr.common.AddressRegisterName()); + output << ' ' << instr.common.compare_op.ToString(instr.common.compare_op.y) + << ' '; + print_input(output, src2, swizzle.negate_src2, + swizzle.SelectorToString(true).substr(1, 1), false); break; } case OpCode::Id::MAD: - case OpCode::Id::MADI: - { + case OpCode::Id::MADI: { AlignToColumn(kOpcodeColumnWidth); bool src_is_inverted = 0 != (opcode_info.subtype & OpCode::Info::SrcInversed); @@ -175,34 +176,42 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con SourceRegister src2 = instr.mad.GetSrc2(src_is_inverted); SourceRegister src3 = instr.mad.GetSrc3(src_is_inverted); - output << std::setw(3) << std::right << instr.mad.dest.Value().GetName() << '.' << swizzle.DestMaskToString(); + output << std::setw(3) << std::right << instr.mad.dest.Value().GetName() << '.' + << swizzle.DestMaskToString(); AlignToColumn(kOutputColumnWidth); - print_input(output, src1, swizzle.negate_src1, SelectorToString(swizzle.src1_selector)); + print_input(output, src1, swizzle.negate_src1, + SelectorToString(swizzle.src1_selector)); AlignToColumn(kInputOperandColumnWidth); if (src_is_inverted) { - print_input(output, src2, swizzle.negate_src2, SelectorToString(swizzle.src2_selector)); + print_input(output, src2, swizzle.negate_src2, + SelectorToString(swizzle.src2_selector)); } else { - print_input(output, src2, swizzle.negate_src2, SelectorToString(swizzle.src2_selector), true, instr.mad.AddressRegisterName()); + print_input(output, src2, swizzle.negate_src2, + SelectorToString(swizzle.src2_selector), true, + instr.mad.AddressRegisterName()); } AlignToColumn(kInputOperandColumnWidth); if (src_is_inverted) { - print_input(output, src3, swizzle.negate_src3, SelectorToString(swizzle.src3_selector), true, instr.mad.AddressRegisterName()); + print_input(output, src3, swizzle.negate_src3, + SelectorToString(swizzle.src3_selector), true, + instr.mad.AddressRegisterName()); } else { - print_input(output, src3, swizzle.negate_src3, SelectorToString(swizzle.src3_selector)); + print_input(output, src3, swizzle.negate_src3, + SelectorToString(swizzle.src3_selector)); } AlignToColumn(kInputOperandColumnWidth); break; } - default: - { + default: { AlignToColumn(kOpcodeColumnWidth); bool src_is_inverted = 0 != (opcode_info.subtype & OpCode::Info::SrcInversed); if (opcode_info.subtype & OpCode::Info::Dest) { // e.g. "r12.xy__" - output << std::setw(3) << std::right << instr.common.dest.Value().GetName() << '.' << swizzle.DestMaskToString(); + output << std::setw(3) << std::right << instr.common.dest.Value().GetName() + << '.' << swizzle.DestMaskToString(); } else if (opcode_info.subtype == OpCode::Info::MOVA) { output << " a0." << swizzle.DestMaskToString(); } @@ -210,14 +219,18 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con if (opcode_info.subtype & OpCode::Info::Src1) { SourceRegister src1 = instr.common.GetSrc1(src_is_inverted); - print_input(output, src1, swizzle.negate_src1, swizzle.SelectorToString(false), true, instr.common.AddressRegisterName()); + print_input(output, src1, swizzle.negate_src1, + swizzle.SelectorToString(false), true, + instr.common.AddressRegisterName()); AlignToColumn(kInputOperandColumnWidth); } - // TODO: In some cases, the Address Register is used as an index for SRC2 instead of SRC1 + // TODO: In some cases, the Address Register is used as an index for SRC2 + // instead of SRC1 if (opcode_info.subtype & OpCode::Info::Src2) { SourceRegister src2 = instr.common.GetSrc2(src_is_inverted); - print_input(output, src2, swizzle.negate_src2, swizzle.SelectorToString(true)); + print_input(output, src2, swizzle.negate_src2, + swizzle.SelectorToString(true)); AlignToColumn(kInputOperandColumnWidth); } break; @@ -228,8 +241,7 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con } case OpCode::Type::Conditional: - case OpCode::Type::UniformFlowControl: - { + case OpCode::Type::UniformFlowControl: { output << ' '; switch (opcode.EffectiveOpCode()) { @@ -242,7 +254,8 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con output << '('; if (instr.flow_control.op != instr.flow_control.JustY) { - if (instr.flow_control.refx) output << '!'; + if (instr.flow_control.refx) + output << '!'; output << "cc.x"; } @@ -253,7 +266,8 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con } if (instr.flow_control.op != instr.flow_control.JustX) { - if (instr.flow_control.refy) output << '!'; + if (instr.flow_control.refy) + output << '!'; output << "cc.y"; } @@ -266,17 +280,23 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con u32 target_addr_else = instr.flow_control.dest_offset; if (opcode_info.subtype & OpCode::Info::HasAlternative) { - output << "else jump to 0x" << std::setw(4) << std::right << std::setfill('0') << std::hex << (4 * instr.flow_control.dest_offset); + output << "else jump to 0x" << std::setw(4) << std::right + << std::setfill('0') << std::hex + << (4 * instr.flow_control.dest_offset); } else if (opcode_info.subtype & OpCode::Info::HasExplicitDest) { - output << "jump to 0x" << std::setw(4) << std::right << std::setfill('0') << std::hex << (4 * instr.flow_control.dest_offset); + output << "jump to 0x" << std::setw(4) << std::right << std::setfill('0') + << std::hex << (4 * instr.flow_control.dest_offset); } else { // TODO: Handle other cases output << "(unknown destination)"; } if (opcode_info.subtype & OpCode::Info::HasFinishPoint) { - output << " (return on 0x" << std::setw(4) << std::right << std::setfill('0') << std::hex - << (4 * instr.flow_control.dest_offset + 4 * instr.flow_control.num_instructions) << ')'; + output << " (return on 0x" << std::setw(4) << std::right + << std::setfill('0') << std::hex + << (4 * instr.flow_control.dest_offset + + 4 * instr.flow_control.num_instructions) + << ')'; } break; @@ -300,8 +320,7 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con case Qt::FontRole: return GetMonospaceFont(); - case Qt::BackgroundRole: - { + case Qt::BackgroundRole: { // Highlight current instruction int current_record_index = par->cycle_index->value(); if (current_record_index < static_cast<int>(par->debug_data.records.size())) { @@ -319,10 +338,8 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con return QBrush(QColor(192, 192, 192)); } - // TODO: Draw arrows for each "reachable" instruction to visualize control flow - default: break; } @@ -331,23 +348,24 @@ QVariant GraphicsVertexShaderModel::data(const QModelIndex& index, int role) con } void GraphicsVertexShaderWidget::DumpShader() { - QString filename = QFileDialog::getSaveFileName(this, tr("Save Shader Dump"), "shader_dump.shbin", - tr("Shader Binary (*.shbin)")); + QString filename = QFileDialog::getSaveFileName( + this, tr("Save Shader Dump"), "shader_dump.shbin", tr("Shader Binary (*.shbin)")); if (filename.isEmpty()) { // If the user canceled the dialog, don't dump anything. return; } - auto& setup = Pica::g_state.vs; + auto& setup = Pica::g_state.vs; auto& config = Pica::g_state.regs.vs; - Pica::DebugUtils::DumpShader(filename.toStdString(), config, setup, Pica::g_state.regs.vs_output_attributes); + Pica::DebugUtils::DumpShader(filename.toStdString(), config, setup, + Pica::g_state.regs.vs_output_attributes); } -GraphicsVertexShaderWidget::GraphicsVertexShaderWidget(std::shared_ptr< Pica::DebugContext > debug_context, - QWidget* parent) - : BreakPointObserverDock(debug_context, "Pica Vertex Shader", parent) { +GraphicsVertexShaderWidget::GraphicsVertexShaderWidget( + std::shared_ptr<Pica::DebugContext> debug_context, QWidget* parent) + : BreakPointObserverDock(debug_context, "Pica Vertex Shader", parent) { setObjectName("PicaVertexShader"); // Clear input vertex data so that it contains valid float values in case a debug shader @@ -365,7 +383,8 @@ GraphicsVertexShaderWidget::GraphicsVertexShaderWidget(std::shared_ptr< Pica::De input_data[i]->setValidator(new QDoubleValidator(input_data[i])); } - breakpoint_warning = new QLabel(tr("(data only available at vertex shader invocation breakpoints)")); + breakpoint_warning = + new QLabel(tr("(data only available at vertex shader invocation breakpoints)")); // TODO: Add some button for jumping to the shader entry point @@ -442,7 +461,8 @@ GraphicsVertexShaderWidget::GraphicsVertexShaderWidget(std::shared_ptr< Pica::De // Set a minimum height so that the size of this label doesn't cause the rest of the bottom // part of the UI to keep jumping up and down when cycling through instructions. - instruction_description->setMinimumHeight(instruction_description->fontMetrics().lineSpacing() * 6); + instruction_description->setMinimumHeight(instruction_description->fontMetrics().lineSpacing() * + 6); instruction_description->setAlignment(Qt::AlignLeft | Qt::AlignTop); main_layout->addWidget(instruction_description); @@ -471,7 +491,8 @@ void GraphicsVertexShaderWidget::Reload(bool replace_vertex_data, void* vertex_d memcpy(&input_vertex, vertex_data, sizeof(input_vertex)); for (unsigned attr = 0; attr < 16; ++attr) { for (unsigned comp = 0; comp < 4; ++comp) { - input_data[4 * attr + comp]->setText(QString("%1").arg(input_vertex.attr[attr][comp].ToFloat32())); + input_data[4 * attr + comp]->setText( + QString("%1").arg(input_vertex.attr[attr][comp].ToFloat32())); } } breakpoint_warning->hide(); @@ -498,10 +519,11 @@ void GraphicsVertexShaderWidget::Reload(bool replace_vertex_data, void* vertex_d info.swizzle_info.push_back({pattern}); u32 entry_point = Pica::g_state.regs.vs.main_offset; - info.labels.insert({ entry_point, "main" }); + info.labels.insert({entry_point, "main"}); // Generate debug information - debug_data = Pica::g_state.vs.ProduceDebugInfo(input_vertex, num_attributes, shader_config, shader_setup); + debug_data = Pica::g_state.vs.ProduceDebugInfo(input_vertex, num_attributes, shader_config, + shader_setup); // Reload widget state for (int attr = 0; attr < num_attributes; ++attr) { @@ -537,29 +559,60 @@ void GraphicsVertexShaderWidget::OnCycleIndexChanged(int index) { auto& record = debug_data.records[index]; if (record.mask & Pica::Shader::DebugDataRecord::SRC1) - text += tr("SRC1: %1, %2, %3, %4\n").arg(record.src1.x.ToFloat32()).arg(record.src1.y.ToFloat32()).arg(record.src1.z.ToFloat32()).arg(record.src1.w.ToFloat32()); + text += tr("SRC1: %1, %2, %3, %4\n") + .arg(record.src1.x.ToFloat32()) + .arg(record.src1.y.ToFloat32()) + .arg(record.src1.z.ToFloat32()) + .arg(record.src1.w.ToFloat32()); if (record.mask & Pica::Shader::DebugDataRecord::SRC2) - text += tr("SRC2: %1, %2, %3, %4\n").arg(record.src2.x.ToFloat32()).arg(record.src2.y.ToFloat32()).arg(record.src2.z.ToFloat32()).arg(record.src2.w.ToFloat32()); + text += tr("SRC2: %1, %2, %3, %4\n") + .arg(record.src2.x.ToFloat32()) + .arg(record.src2.y.ToFloat32()) + .arg(record.src2.z.ToFloat32()) + .arg(record.src2.w.ToFloat32()); if (record.mask & Pica::Shader::DebugDataRecord::SRC3) - text += tr("SRC3: %1, %2, %3, %4\n").arg(record.src3.x.ToFloat32()).arg(record.src3.y.ToFloat32()).arg(record.src3.z.ToFloat32()).arg(record.src3.w.ToFloat32()); + text += tr("SRC3: %1, %2, %3, %4\n") + .arg(record.src3.x.ToFloat32()) + .arg(record.src3.y.ToFloat32()) + .arg(record.src3.z.ToFloat32()) + .arg(record.src3.w.ToFloat32()); if (record.mask & Pica::Shader::DebugDataRecord::DEST_IN) - text += tr("DEST_IN: %1, %2, %3, %4\n").arg(record.dest_in.x.ToFloat32()).arg(record.dest_in.y.ToFloat32()).arg(record.dest_in.z.ToFloat32()).arg(record.dest_in.w.ToFloat32()); + text += tr("DEST_IN: %1, %2, %3, %4\n") + .arg(record.dest_in.x.ToFloat32()) + .arg(record.dest_in.y.ToFloat32()) + .arg(record.dest_in.z.ToFloat32()) + .arg(record.dest_in.w.ToFloat32()); if (record.mask & Pica::Shader::DebugDataRecord::DEST_OUT) - text += tr("DEST_OUT: %1, %2, %3, %4\n").arg(record.dest_out.x.ToFloat32()).arg(record.dest_out.y.ToFloat32()).arg(record.dest_out.z.ToFloat32()).arg(record.dest_out.w.ToFloat32()); + text += tr("DEST_OUT: %1, %2, %3, %4\n") + .arg(record.dest_out.x.ToFloat32()) + .arg(record.dest_out.y.ToFloat32()) + .arg(record.dest_out.z.ToFloat32()) + .arg(record.dest_out.w.ToFloat32()); if (record.mask & Pica::Shader::DebugDataRecord::ADDR_REG_OUT) - text += tr("Addres Registers: %1, %2\n").arg(record.address_registers[0]).arg(record.address_registers[1]); + text += tr("Addres Registers: %1, %2\n") + .arg(record.address_registers[0]) + .arg(record.address_registers[1]); if (record.mask & Pica::Shader::DebugDataRecord::CMP_RESULT) - text += tr("Compare Result: %1, %2\n").arg(record.conditional_code[0] ? "true" : "false").arg(record.conditional_code[1] ? "true" : "false"); + text += tr("Compare Result: %1, %2\n") + .arg(record.conditional_code[0] ? "true" : "false") + .arg(record.conditional_code[1] ? "true" : "false"); if (record.mask & Pica::Shader::DebugDataRecord::COND_BOOL_IN) text += tr("Static Condition: %1\n").arg(record.cond_bool ? "true" : "false"); if (record.mask & Pica::Shader::DebugDataRecord::COND_CMP_IN) - text += tr("Dynamic Conditions: %1, %2\n").arg(record.cond_cmp[0] ? "true" : "false").arg(record.cond_cmp[1] ? "true" : "false"); + text += tr("Dynamic Conditions: %1, %2\n") + .arg(record.cond_cmp[0] ? "true" : "false") + .arg(record.cond_cmp[1] ? "true" : "false"); if (record.mask & Pica::Shader::DebugDataRecord::LOOP_INT_IN) - text += tr("Loop Parameters: %1 (repeats), %2 (initializer), %3 (increment), %4\n").arg(record.loop_int.x).arg(record.loop_int.y).arg(record.loop_int.z).arg(record.loop_int.w); - - text += tr("Instruction offset: 0x%1").arg(4 * record.instruction_offset, 4, 16, QLatin1Char('0')); + text += tr("Loop Parameters: %1 (repeats), %2 (initializer), %3 (increment), %4\n") + .arg(record.loop_int.x) + .arg(record.loop_int.y) + .arg(record.loop_int.z) + .arg(record.loop_int.w); + + text += + tr("Instruction offset: 0x%1").arg(4 * record.instruction_offset, 4, 16, QLatin1Char('0')); if (record.mask & Pica::Shader::DebugDataRecord::NEXT_INSTR) { text += tr(" -> 0x%2").arg(4 * record.next_instruction, 4, 16, QLatin1Char('0')); } else { @@ -570,6 +623,7 @@ void GraphicsVertexShaderWidget::OnCycleIndexChanged(int index) { // Emit model update notification and scroll to current instruction QModelIndex instr_index = model->index(record.instruction_offset, 0); - emit model->dataChanged(instr_index, model->index(record.instruction_offset, model->columnCount())); + emit model->dataChanged(instr_index, + model->index(record.instruction_offset, model->columnCount())); binary_list->scrollTo(instr_index, QAbstractItemView::EnsureVisible); } diff --git a/src/citra_qt/debugger/graphics_vertex_shader.h b/src/citra_qt/debugger/graphics_vertex_shader.h index 7f06f496a..ec42f24bb 100644 --- a/src/citra_qt/debugger/graphics_vertex_shader.h +++ b/src/citra_qt/debugger/graphics_vertex_shader.h @@ -5,11 +5,9 @@ #pragma once #include <QAbstractTableModel> - +#include <QTreeView> #include "citra_qt/debugger/graphics_breakpoint_observer.h" - #include "nihstro/parser_shbin.h" - #include "video_core/shader/shader.h" class QLabel; @@ -26,7 +24,8 @@ public: int columnCount(const QModelIndex& parent = QModelIndex()) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const override; private: GraphicsVertexShaderWidget* par; @@ -56,7 +55,9 @@ private slots: /** * Reload widget based on the current PICA200 state * @param replace_vertex_data If true, invalidate all current vertex data - * @param vertex_data New vertex data to use, as passed to OnBreakPointHit. May be nullptr to specify that no valid vertex data can be retrieved currently. Only used if replace_vertex_data is true. + * @param vertex_data New vertex data to use, as passed to OnBreakPointHit. May be nullptr to + * specify that no valid vertex data can be retrieved currently. Only used if + * replace_vertex_data is true. */ void Reload(bool replace_vertex_data = false, void* vertex_data = nullptr); @@ -66,9 +67,12 @@ private: GraphicsVertexShaderModel* model; /// TODO: Move these into a single struct - std::array<QLineEdit*, 4*16> input_data; // A text box for each of the 4 components of up to 16 vertex attributes - std::array<QWidget*, 16> input_data_container; // QWidget containing the QLayout containing each vertex attribute - std::array<QLabel*, 16> input_data_mapping; // A QLabel denoting the shader input attribute which the vertex attribute maps to + std::array<QLineEdit*, 4 * 16> + input_data; // A text box for each of the 4 components of up to 16 vertex attributes + std::array<QWidget*, 16> + input_data_container; // QWidget containing the QLayout containing each vertex attribute + std::array<QLabel*, 16> input_data_mapping; // A QLabel denoting the shader input attribute + // which the vertex attribute maps to // Text to be shown when input vertex data is not retrievable QLabel* breakpoint_warning; diff --git a/src/citra_qt/debugger/profiler.cpp b/src/citra_qt/debugger/profiler.cpp index 17898f54b..cee10403d 100644 --- a/src/citra_qt/debugger/profiler.cpp +++ b/src/citra_qt/debugger/profiler.cpp @@ -5,10 +5,8 @@ #include <QMouseEvent> #include <QPainter> #include <QString> - #include "citra_qt/debugger/profiler.h" #include "citra_qt/util/util.h" - #include "common/common_types.h" #include "common/microprofile.h" #include "common/profiler_reporting.h" @@ -22,57 +20,58 @@ using namespace Common::Profiling; -static QVariant GetDataForColumn(int col, const AggregatedDuration& duration) -{ +static QVariant GetDataForColumn(int col, const AggregatedDuration& duration) { static auto duration_to_float = [](Duration dur) -> float { using FloatMs = std::chrono::duration<float, std::chrono::milliseconds::period>; return std::chrono::duration_cast<FloatMs>(dur).count(); }; switch (col) { - case 1: return duration_to_float(duration.avg); - case 2: return duration_to_float(duration.min); - case 3: return duration_to_float(duration.max); - default: return QVariant(); + case 1: + return duration_to_float(duration.avg); + case 2: + return duration_to_float(duration.min); + case 3: + return duration_to_float(duration.max); + default: + return QVariant(); } } -ProfilerModel::ProfilerModel(QObject* parent) : QAbstractItemModel(parent) -{ +ProfilerModel::ProfilerModel(QObject* parent) : QAbstractItemModel(parent) { updateProfilingInfo(); } -QVariant ProfilerModel::headerData(int section, Qt::Orientation orientation, int role) const -{ +QVariant ProfilerModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { switch (section) { - case 0: return tr("Category"); - case 1: return tr("Avg"); - case 2: return tr("Min"); - case 3: return tr("Max"); + case 0: + return tr("Category"); + case 1: + return tr("Avg"); + case 2: + return tr("Min"); + case 3: + return tr("Max"); } } return QVariant(); } -QModelIndex ProfilerModel::index(int row, int column, const QModelIndex& parent) const -{ +QModelIndex ProfilerModel::index(int row, int column, const QModelIndex& parent) const { return createIndex(row, column); } -QModelIndex ProfilerModel::parent(const QModelIndex& child) const -{ +QModelIndex ProfilerModel::parent(const QModelIndex& child) const { return QModelIndex(); } -int ProfilerModel::columnCount(const QModelIndex& parent) const -{ +int ProfilerModel::columnCount(const QModelIndex& parent) const { return 4; } -int ProfilerModel::rowCount(const QModelIndex& parent) const -{ +int ProfilerModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) { return 0; } else { @@ -80,8 +79,7 @@ int ProfilerModel::rowCount(const QModelIndex& parent) const } } -QVariant ProfilerModel::data(const QModelIndex& index, int role) const -{ +QVariant ProfilerModel::data(const QModelIndex& index, int role) const { if (role == Qt::DisplayRole) { if (index.row() == 0) { if (index.column() == 0) { @@ -101,14 +99,12 @@ QVariant ProfilerModel::data(const QModelIndex& index, int role) const return QVariant(); } -void ProfilerModel::updateProfilingInfo() -{ +void ProfilerModel::updateProfilingInfo() { results = GetTimingResultsAggregator()->GetAggregatedResults(); emit dataChanged(createIndex(0, 1), createIndex(rowCount() - 1, 3)); } -ProfilerWidget::ProfilerWidget(QWidget* parent) : QDockWidget(parent) -{ +ProfilerWidget::ProfilerWidget(QWidget* parent) : QDockWidget(parent) { ui.setupUi(this); model = new ProfilerModel(this); @@ -118,8 +114,7 @@ ProfilerWidget::ProfilerWidget(QWidget* parent) : QDockWidget(parent) connect(&update_timer, SIGNAL(timeout()), model, SLOT(updateProfilingInfo())); } -void ProfilerWidget::setProfilingInfoUpdateEnabled(bool enable) -{ +void ProfilerWidget::setProfilingInfoUpdateEnabled(bool enable) { if (enable) { update_timer.start(100); model->updateProfilingInfo(); @@ -157,9 +152,7 @@ private: #endif -MicroProfileDialog::MicroProfileDialog(QWidget* parent) - : QWidget(parent, Qt::Dialog) -{ +MicroProfileDialog::MicroProfileDialog(QWidget* parent) : QWidget(parent, Qt::Dialog) { setObjectName("MicroProfile"); setWindowTitle(tr("MicroProfile")); resize(1000, 600); @@ -175,7 +168,8 @@ MicroProfileDialog::MicroProfileDialog(QWidget* parent) layout->addWidget(widget); setLayout(layout); - // Configure focus so that widget is focusable and the dialog automatically forwards focus to it. + // Configure focus so that widget is focusable and the dialog automatically forwards focus to + // it. setFocusProxy(widget); widget->setFocusPolicy(Qt::StrongFocus); widget->setFocus(); @@ -207,7 +201,6 @@ void MicroProfileDialog::hideEvent(QHideEvent* ev) { QWidget::hideEvent(ev); } - #if MICROPROFILE_ENABLED /// There's no way to pass a user pointer to MicroProfile, so this variable is used to make the @@ -308,7 +301,8 @@ void MicroProfileDrawText(int x, int y, u32 hex_color, const char* text, u32 tex } } -void MicroProfileDrawBox(int left, int top, int right, int bottom, u32 hex_color, MicroProfileBoxType type) { +void MicroProfileDrawBox(int left, int top, int right, int bottom, u32 hex_color, + MicroProfileBoxType type) { QColor color = QColor::fromRgba(hex_color); QBrush brush = color; if (type == MicroProfileBoxTypeBar) { @@ -326,7 +320,7 @@ void MicroProfileDrawLine2D(u32 vertices_length, float* vertices, u32 hex_color) static std::vector<QPointF> point_buf; for (u32 i = 0; i < vertices_length; ++i) { - point_buf.emplace_back(vertices[i*2 + 0], vertices[i*2 + 1]); + point_buf.emplace_back(vertices[i * 2 + 0], vertices[i * 2 + 1]); } // hex_color does not include an alpha, so it must be assumed to be 255 diff --git a/src/citra_qt/debugger/profiler.h b/src/citra_qt/debugger/profiler.h index 3b38ed8ec..d8c6487aa 100644 --- a/src/citra_qt/debugger/profiler.h +++ b/src/citra_qt/debugger/profiler.h @@ -7,21 +7,20 @@ #include <QAbstractItemModel> #include <QDockWidget> #include <QTimer> - -#include "ui_profiler.h" - #include "common/microprofile.h" #include "common/profiler_reporting.h" +#include "ui_profiler.h" -class ProfilerModel : public QAbstractItemModel -{ +class ProfilerModel : public QAbstractItemModel { Q_OBJECT public: ProfilerModel(QObject* parent); - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const override; + QModelIndex index(int row, int column, + const QModelIndex& parent = QModelIndex()) const override; QModelIndex parent(const QModelIndex& child) const override; int columnCount(const QModelIndex& parent = QModelIndex()) const override; int rowCount(const QModelIndex& parent = QModelIndex()) const override; @@ -34,8 +33,7 @@ private: Common::Profiling::AggregatedFrameResult results; }; -class ProfilerWidget : public QDockWidget -{ +class ProfilerWidget : public QDockWidget { Q_OBJECT public: @@ -51,7 +49,6 @@ private: QTimer update_timer; }; - class MicroProfileDialog : public QWidget { Q_OBJECT diff --git a/src/citra_qt/debugger/ramview.cpp b/src/citra_qt/debugger/ramview.cpp index 02347e83a..10a09dda8 100644 --- a/src/citra_qt/debugger/ramview.cpp +++ b/src/citra_qt/debugger/ramview.cpp @@ -4,12 +4,9 @@ #include "citra_qt/debugger/ramview.h" -GRamView::GRamView(QWidget* parent) : QHexEdit(parent) -{ -} +GRamView::GRamView(QWidget* parent) : QHexEdit(parent) {} -void GRamView::OnCPUStepped() -{ +void GRamView::OnCPUStepped() { // TODO: QHexEdit doesn't show vertical scroll bars for > 10MB data streams... - //setData(QByteArray((const char*)Mem_RAM,sizeof(Mem_RAM)/8)); + // setData(QByteArray((const char*)Mem_RAM,sizeof(Mem_RAM)/8)); } diff --git a/src/citra_qt/debugger/ramview.h b/src/citra_qt/debugger/ramview.h index 0ef74586b..8043c59e8 100644 --- a/src/citra_qt/debugger/ramview.h +++ b/src/citra_qt/debugger/ramview.h @@ -4,8 +4,7 @@ #include "qhexedit.h" -class GRamView : public QHexEdit -{ +class GRamView : public QHexEdit { Q_OBJECT public: diff --git a/src/citra_qt/debugger/registers.cpp b/src/citra_qt/debugger/registers.cpp index 1bd0bfebc..0b644432f 100644 --- a/src/citra_qt/debugger/registers.cpp +++ b/src/citra_qt/debugger/registers.cpp @@ -3,12 +3,10 @@ // Refer to the license.txt file included. #include <QTreeWidgetItem> - #include "citra_qt/debugger/registers.h" #include "citra_qt/util/util.h" - -#include "core/core.h" #include "core/arm/arm_interface.h" +#include "core/core.h" RegistersWidget::RegistersWidget(QWidget* parent) : QDockWidget(parent) { cpu_regs_ui.setupUi(this); @@ -16,7 +14,8 @@ RegistersWidget::RegistersWidget(QWidget* parent) : QDockWidget(parent) { tree = cpu_regs_ui.treeWidget; tree->addTopLevelItem(core_registers = new QTreeWidgetItem(QStringList(tr("Registers")))); tree->addTopLevelItem(vfp_registers = new QTreeWidgetItem(QStringList(tr("VFP Registers")))); - tree->addTopLevelItem(vfp_system_registers = new QTreeWidgetItem(QStringList(tr("VFP System Registers")))); + tree->addTopLevelItem(vfp_system_registers = + new QTreeWidgetItem(QStringList(tr("VFP System Registers")))); tree->addTopLevelItem(cpsr = new QTreeWidgetItem(QStringList("CPSR"))); for (int i = 0; i < 16; ++i) { @@ -63,17 +62,18 @@ void RegistersWidget::OnDebugModeEntered() { return; for (int i = 0; i < core_registers->childCount(); ++i) - core_registers->child(i)->setText(1, QString("0x%1").arg(Core::g_app_core->GetReg(i), 8, 16, QLatin1Char('0'))); + core_registers->child(i)->setText( + 1, QString("0x%1").arg(Core::g_app_core->GetReg(i), 8, 16, QLatin1Char('0'))); for (int i = 0; i < vfp_registers->childCount(); ++i) - vfp_registers->child(i)->setText(1, QString("0x%1").arg(Core::g_app_core->GetVFPReg(i), 8, 16, QLatin1Char('0'))); + vfp_registers->child(i)->setText( + 1, QString("0x%1").arg(Core::g_app_core->GetVFPReg(i), 8, 16, QLatin1Char('0'))); UpdateCPSRValues(); UpdateVFPSystemRegisterValues(); } -void RegistersWidget::OnDebugModeLeft() { -} +void RegistersWidget::OnDebugModeLeft() {} void RegistersWidget::OnEmulationStarting(EmuThread* emu_thread) { setEnabled(true); @@ -130,21 +130,24 @@ void RegistersWidget::UpdateCPSRValues() { const u32 cpsr_val = Core::g_app_core->GetCPSR(); cpsr->setText(1, QString("0x%1").arg(cpsr_val, 8, 16, QLatin1Char('0'))); - cpsr->child(0)->setText(1, QString("b%1").arg(cpsr_val & 0x1F, 5, 2, QLatin1Char('0'))); // M - Mode - cpsr->child(1)->setText(1, QString::number((cpsr_val >> 5) & 1)); // T - State - cpsr->child(2)->setText(1, QString::number((cpsr_val >> 6) & 1)); // F - FIQ disable - cpsr->child(3)->setText(1, QString::number((cpsr_val >> 7) & 1)); // I - IRQ disable - cpsr->child(4)->setText(1, QString::number((cpsr_val >> 8) & 1)); // A - Imprecise abort - cpsr->child(5)->setText(1, QString::number((cpsr_val >> 9) & 1)); // E - Data endianess - cpsr->child(6)->setText(1, QString::number((cpsr_val >> 10) & 0x3F)); // IT - If-Then state (DNM) - cpsr->child(7)->setText(1, QString::number((cpsr_val >> 16) & 0xF)); // GE - Greater-than-or-Equal - cpsr->child(8)->setText(1, QString::number((cpsr_val >> 20) & 0xF)); // DNM - Do not modify - cpsr->child(9)->setText(1, QString::number((cpsr_val >> 24) & 1)); // J - Jazelle - cpsr->child(10)->setText(1, QString::number((cpsr_val >> 27) & 1)); // Q - Saturation - cpsr->child(11)->setText(1, QString::number((cpsr_val >> 28) & 1)); // V - Overflow - cpsr->child(12)->setText(1, QString::number((cpsr_val >> 29) & 1)); // C - Carry/Borrow/Extend - cpsr->child(13)->setText(1, QString::number((cpsr_val >> 30) & 1)); // Z - Zero - cpsr->child(14)->setText(1, QString::number((cpsr_val >> 31) & 1)); // N - Negative/Less than + cpsr->child(0)->setText( + 1, QString("b%1").arg(cpsr_val & 0x1F, 5, 2, QLatin1Char('0'))); // M - Mode + cpsr->child(1)->setText(1, QString::number((cpsr_val >> 5) & 1)); // T - State + cpsr->child(2)->setText(1, QString::number((cpsr_val >> 6) & 1)); // F - FIQ disable + cpsr->child(3)->setText(1, QString::number((cpsr_val >> 7) & 1)); // I - IRQ disable + cpsr->child(4)->setText(1, QString::number((cpsr_val >> 8) & 1)); // A - Imprecise abort + cpsr->child(5)->setText(1, QString::number((cpsr_val >> 9) & 1)); // E - Data endianess + cpsr->child(6)->setText(1, + QString::number((cpsr_val >> 10) & 0x3F)); // IT - If-Then state (DNM) + cpsr->child(7)->setText(1, + QString::number((cpsr_val >> 16) & 0xF)); // GE - Greater-than-or-Equal + cpsr->child(8)->setText(1, QString::number((cpsr_val >> 20) & 0xF)); // DNM - Do not modify + cpsr->child(9)->setText(1, QString::number((cpsr_val >> 24) & 1)); // J - Jazelle + cpsr->child(10)->setText(1, QString::number((cpsr_val >> 27) & 1)); // Q - Saturation + cpsr->child(11)->setText(1, QString::number((cpsr_val >> 28) & 1)); // V - Overflow + cpsr->child(12)->setText(1, QString::number((cpsr_val >> 29) & 1)); // C - Carry/Borrow/Extend + cpsr->child(13)->setText(1, QString::number((cpsr_val >> 30) & 1)); // Z - Zero + cpsr->child(14)->setText(1, QString::number((cpsr_val >> 31) & 1)); // N - Negative/Less than } void RegistersWidget::CreateVFPSystemRegisterChildren() { @@ -188,9 +191,9 @@ void RegistersWidget::CreateVFPSystemRegisterChildren() { } void RegistersWidget::UpdateVFPSystemRegisterValues() { - const u32 fpscr_val = Core::g_app_core->GetVFPSystemReg(VFP_FPSCR); - const u32 fpexc_val = Core::g_app_core->GetVFPSystemReg(VFP_FPEXC); - const u32 fpinst_val = Core::g_app_core->GetVFPSystemReg(VFP_FPINST); + const u32 fpscr_val = Core::g_app_core->GetVFPSystemReg(VFP_FPSCR); + const u32 fpexc_val = Core::g_app_core->GetVFPSystemReg(VFP_FPEXC); + const u32 fpinst_val = Core::g_app_core->GetVFPSystemReg(VFP_FPINST); const u32 fpinst2_val = Core::g_app_core->GetVFPSystemReg(VFP_FPINST2); QTreeWidgetItem* const fpscr = vfp_system_registers->child(0); @@ -228,6 +231,8 @@ void RegistersWidget::UpdateVFPSystemRegisterValues() { fpexc->child(6)->setText(1, QString::number((fpexc_val >> 30) & 1)); fpexc->child(7)->setText(1, QString::number((fpexc_val >> 31) & 1)); - vfp_system_registers->child(2)->setText(1, QString("0x%1").arg(fpinst_val, 8, 16, QLatin1Char('0'))); - vfp_system_registers->child(3)->setText(1, QString("0x%1").arg(fpinst2_val, 8, 16, QLatin1Char('0'))); + vfp_system_registers->child(2)->setText( + 1, QString("0x%1").arg(fpinst_val, 8, 16, QLatin1Char('0'))); + vfp_system_registers->child(3)->setText( + 1, QString("0x%1").arg(fpinst2_val, 8, 16, QLatin1Char('0'))); } diff --git a/src/citra_qt/debugger/registers.h b/src/citra_qt/debugger/registers.h index cf27acc1c..54c9a8155 100644 --- a/src/citra_qt/debugger/registers.h +++ b/src/citra_qt/debugger/registers.h @@ -2,16 +2,14 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "ui_registers.h" - #include <QDockWidget> +#include "ui_registers.h" class QTreeWidget; class QTreeWidgetItem; class EmuThread; -class RegistersWidget : public QDockWidget -{ +class RegistersWidget : public QDockWidget { Q_OBJECT public: diff --git a/src/citra_qt/game_list.cpp b/src/citra_qt/game_list.cpp index 1910da3ac..07bc35308 100644 --- a/src/citra_qt/game_list.cpp +++ b/src/citra_qt/game_list.cpp @@ -5,19 +5,15 @@ #include <QHeaderView> #include <QThreadPool> #include <QVBoxLayout> - -#include "game_list.h" -#include "game_list_p.h" -#include "ui_settings.h" - -#include "core/loader/loader.h" - #include "common/common_paths.h" #include "common/logging/log.h" #include "common/string_util.h" +#include "core/loader/loader.h" +#include "game_list.h" +#include "game_list_p.h" +#include "ui_settings.h" -GameList::GameList(QWidget* parent) -{ +GameList::GameList(QWidget* parent) { QVBoxLayout* layout = new QVBoxLayout; tree_view = new QTreeView; @@ -38,9 +34,11 @@ GameList::GameList(QWidget* parent) item_model->setHeaderData(COLUMN_FILE_TYPE, Qt::Horizontal, "File type"); item_model->setHeaderData(COLUMN_SIZE, Qt::Horizontal, "Size"); - connect(tree_view, SIGNAL(activated(const QModelIndex&)), this, SLOT(ValidateEntry(const QModelIndex&))); + connect(tree_view, SIGNAL(activated(const QModelIndex&)), this, + SLOT(ValidateEntry(const QModelIndex&))); - // We must register all custom types with the Qt Automoc system so that we are able to use it with + // We must register all custom types with the Qt Automoc system so that we are able to use it + // with // signals/slots. In this case, QList falls under the umbrells of custom types. qRegisterMetaType<QList<QStandardItem*>>("QList<QStandardItem*>"); @@ -48,18 +46,15 @@ GameList::GameList(QWidget* parent) setLayout(layout); } -GameList::~GameList() -{ +GameList::~GameList() { emit ShouldCancelWorker(); } -void GameList::AddEntry(QList<QStandardItem*> entry_items) -{ +void GameList::AddEntry(QList<QStandardItem*> entry_items) { item_model->invisibleRootItem()->appendRow(entry_items); } -void GameList::ValidateEntry(const QModelIndex& item) -{ +void GameList::ValidateEntry(const QModelIndex& item) { // We don't care about the individual QStandardItem that was selected, but its row. int row = item_model->itemFromIndex(item)->row(); QStandardItem* child_file = item_model->invisibleRootItem()->child(row, COLUMN_NAME); @@ -73,14 +68,13 @@ void GameList::ValidateEntry(const QModelIndex& item) emit GameChosen(file_path); } -void GameList::DonePopulating() -{ +void GameList::DonePopulating() { tree_view->setEnabled(true); } -void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) -{ - if (!FileUtil::Exists(dir_path.toStdString()) || !FileUtil::IsDirectory(dir_path.toStdString())) { +void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) { + if (!FileUtil::Exists(dir_path.toStdString()) || + !FileUtil::IsDirectory(dir_path.toStdString())) { LOG_ERROR(Frontend, "Could not find game list folder at %s", dir_path.toLocal8Bit().data()); return; } @@ -92,22 +86,22 @@ void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) emit ShouldCancelWorker(); GameListWorker* worker = new GameListWorker(dir_path, deep_scan); - connect(worker, SIGNAL(EntryReady(QList<QStandardItem*>)), this, SLOT(AddEntry(QList<QStandardItem*>)), Qt::QueuedConnection); + connect(worker, SIGNAL(EntryReady(QList<QStandardItem*>)), this, + SLOT(AddEntry(QList<QStandardItem*>)), Qt::QueuedConnection); connect(worker, SIGNAL(Finished()), this, SLOT(DonePopulating()), Qt::QueuedConnection); - // Use DirectConnection here because worker->Cancel() is thread-safe and we want it to cancel without delay. + // Use DirectConnection here because worker->Cancel() is thread-safe and we want it to cancel + // without delay. connect(this, SIGNAL(ShouldCancelWorker()), worker, SLOT(Cancel()), Qt::DirectConnection); QThreadPool::globalInstance()->start(worker); current_worker = std::move(worker); } -void GameList::SaveInterfaceLayout() -{ +void GameList::SaveInterfaceLayout() { UISettings::values.gamelist_header_state = tree_view->header()->saveState(); } -void GameList::LoadInterfaceLayout() -{ +void GameList::LoadInterfaceLayout() { auto header = tree_view->header(); if (!header->restoreState(UISettings::values.gamelist_header_state)) { // We are using the name column to display icons and titles @@ -118,10 +112,8 @@ void GameList::LoadInterfaceLayout() item_model->sort(header->sortIndicatorSection(), header->sortIndicatorOrder()); } -void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion) -{ - const auto callback = [this, recursion](unsigned* num_entries_out, - const std::string& directory, +void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion) { + const auto callback = [this, recursion](unsigned* num_entries_out, const std::string& directory, const std::string& virtual_name) -> bool { std::string physical_name = directory + DIR_SEP + virtual_name; @@ -138,7 +130,8 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign emit EntryReady({ new GameListItemPath(QString::fromStdString(physical_name), smdh), - new GameListItem(QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))), + new GameListItem( + QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))), new GameListItemSize(FileUtil::GetSize(physical_name)), }); } else if (recursion > 0) { @@ -151,15 +144,13 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign FileUtil::ForeachDirectoryEntry(nullptr, dir_path, callback); } -void GameListWorker::run() -{ +void GameListWorker::run() { stop_processing = false; AddFstEntriesToGameList(dir_path.toStdString(), deep_scan ? 256 : 0); emit Finished(); } -void GameListWorker::Cancel() -{ +void GameListWorker::Cancel() { disconnect(this, 0, 0, 0); stop_processing = true; } diff --git a/src/citra_qt/game_list.h b/src/citra_qt/game_list.h index 198674f04..a22e9bc60 100644 --- a/src/citra_qt/game_list.h +++ b/src/citra_qt/game_list.h @@ -14,7 +14,6 @@ class GameListWorker; - class GameList : public QWidget { Q_OBJECT diff --git a/src/citra_qt/game_list_p.h b/src/citra_qt/game_list_p.h index 353b2d1e2..60ab4cf02 100644 --- a/src/citra_qt/game_list_p.h +++ b/src/citra_qt/game_list_p.h @@ -5,18 +5,14 @@ #pragma once #include <atomic> - #include <QImage> #include <QRunnable> #include <QStandardItem> #include <QString> - #include "citra_qt/util/util.h" -#include "common/string_util.h" #include "common/color.h" - +#include "common/string_util.h" #include "core/loader/smdh.h" - #include "video_core/utils.h" /** @@ -51,19 +47,19 @@ static QPixmap GetDefaultIcon(bool large) { * @param language title language * @return QString short title */ -static QString GetQStringShortTitleFromSMDH(const Loader::SMDH& smdh, Loader::SMDH::TitleLanguage language) { +static QString GetQStringShortTitleFromSMDH(const Loader::SMDH& smdh, + Loader::SMDH::TitleLanguage language) { return QString::fromUtf16(smdh.GetShortTitle(language).data()); } class GameListItem : public QStandardItem { public: - GameListItem(): QStandardItem() {} - GameListItem(const QString& string): QStandardItem(string) {} + GameListItem() : QStandardItem() {} + GameListItem(const QString& string) : QStandardItem(string) {} virtual ~GameListItem() override {} }; - /** * A specialization of GameListItem for path values. * This class ensures that for every full path value it holds, a correct string representation @@ -76,9 +72,8 @@ public: static const int FullPathRole = Qt::UserRole + 1; static const int TitleRole = Qt::UserRole + 2; - GameListItemPath(): GameListItem() {} - GameListItemPath(const QString& game_path, const std::vector<u8>& smdh_data): GameListItem() - { + GameListItemPath() : GameListItem() {} + GameListItemPath(const QString& game_path, const std::vector<u8>& smdh_data) : GameListItem() { setData(game_path, FullPathRole); if (!Loader::IsValidSMDH(smdh_data)) { @@ -94,13 +89,15 @@ public: setData(GetQPixmapFromSMDH(smdh, true), Qt::DecorationRole); // Get title form SMDH - setData(GetQStringShortTitleFromSMDH(smdh, Loader::SMDH::TitleLanguage::English), TitleRole); + setData(GetQStringShortTitleFromSMDH(smdh, Loader::SMDH::TitleLanguage::English), + TitleRole); } QVariant data(int role) const override { if (role == Qt::DisplayRole) { std::string filename; - Common::SplitPath(data(FullPathRole).toString().toStdString(), nullptr, &filename, nullptr); + Common::SplitPath(data(FullPathRole).toString().toStdString(), nullptr, &filename, + nullptr); QString title = data(TitleRole).toString(); return QString::fromStdString(filename) + (title.isEmpty() ? "" : "\n " + title); } else { @@ -109,7 +106,6 @@ public: } }; - /** * A specialization of GameListItem for size values. * This class ensures that for every numerical size value it holds (in bytes), a correct @@ -120,14 +116,12 @@ class GameListItemSize : public GameListItem { public: static const int SizeRole = Qt::UserRole + 1; - GameListItemSize(): GameListItem() {} - GameListItemSize(const qulonglong size_bytes): GameListItem() - { + GameListItemSize() : GameListItem() {} + GameListItemSize(const qulonglong size_bytes) : GameListItem() { setData(size_bytes, SizeRole); } - void setData(const QVariant& value, int role) override - { + void setData(const QVariant& value, int role) override { // By specializing setData for SizeRole, we can ensure that the numerical and string // representations of the data are always accurate and in the correct format. if (role == SizeRole) { @@ -141,15 +135,14 @@ public: /** * This operator is, in practice, only used by the TreeView sorting systems. - * Override it so that it will correctly sort by numerical value instead of by string representation. + * Override it so that it will correctly sort by numerical value instead of by string + * representation. */ - bool operator<(const QStandardItem& other) const override - { + bool operator<(const QStandardItem& other) const override { return data(SizeRole).toULongLong() < other.data(SizeRole).toULongLong(); } }; - /** * Asynchronous worker object for populating the game list. * Communicates with other threads through Qt's signal/slot system. @@ -158,8 +151,8 @@ class GameListWorker : public QObject, public QRunnable { Q_OBJECT public: - GameListWorker(QString dir_path, bool deep_scan): - QObject(), QRunnable(), dir_path(dir_path), deep_scan(deep_scan) {} + GameListWorker(QString dir_path, bool deep_scan) + : QObject(), QRunnable(), dir_path(dir_path), deep_scan(deep_scan) {} public slots: /// Starts the processing of directory tree information. diff --git a/src/citra_qt/hotkeys.cpp b/src/citra_qt/hotkeys.cpp index 41f95c63d..158ed506f 100644 --- a/src/citra_qt/hotkeys.cpp +++ b/src/citra_qt/hotkeys.cpp @@ -3,16 +3,13 @@ // Refer to the license.txt file included. #include <map> - -#include <QtGlobal> #include <QKeySequence> #include <QShortcut> - +#include <QtGlobal> #include "citra_qt/hotkeys.h" #include "citra_qt/ui_settings.h" -struct Hotkey -{ +struct Hotkey { Hotkey() : shortcut(nullptr), context(Qt::WindowShortcut) {} QKeySequence keyseq; @@ -25,33 +22,28 @@ typedef std::map<QString, HotkeyMap> HotkeyGroupMap; HotkeyGroupMap hotkey_groups; -void SaveHotkeys() -{ +void SaveHotkeys() { UISettings::values.shortcuts.clear(); - for (auto group : hotkey_groups) - { - for (auto hotkey : group.second) - { + for (auto group : hotkey_groups) { + for (auto hotkey : group.second) { UISettings::values.shortcuts.emplace_back( - UISettings::Shortcut(group.first + "/" + hotkey.first, - UISettings::ContextualShortcut(hotkey.second.keyseq.toString(), - hotkey.second.context))); + UISettings::Shortcut(group.first + "/" + hotkey.first, + UISettings::ContextualShortcut(hotkey.second.keyseq.toString(), + hotkey.second.context))); } } } -void LoadHotkeys() -{ - // Make sure NOT to use a reference here because it would become invalid once we call beginGroup() - for (auto shortcut : UISettings::values.shortcuts) - { +void LoadHotkeys() { + // Make sure NOT to use a reference here because it would become invalid once we call + // beginGroup() + for (auto shortcut : UISettings::values.shortcuts) { QStringList cat = shortcut.first.split("/"); Q_ASSERT(cat.size() >= 2); // RegisterHotkey assigns default keybindings, so use old values as default parameters Hotkey& hk = hotkey_groups[cat[0]][cat[1]]; - if (!shortcut.second.first.isEmpty()) - { + if (!shortcut.second.first.isEmpty()) { hk.keyseq = QKeySequence::fromString(shortcut.second.first); hk.context = (Qt::ShortcutContext)shortcut.second.second; } @@ -60,17 +52,15 @@ void LoadHotkeys() } } -void RegisterHotkey(const QString& group, const QString& action, const QKeySequence& default_keyseq, Qt::ShortcutContext default_context) -{ - if (hotkey_groups[group].find(action) == hotkey_groups[group].end()) - { +void RegisterHotkey(const QString& group, const QString& action, const QKeySequence& default_keyseq, + Qt::ShortcutContext default_context) { + if (hotkey_groups[group].find(action) == hotkey_groups[group].end()) { hotkey_groups[group][action].keyseq = default_keyseq; hotkey_groups[group][action].context = default_context; } } -QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget) -{ +QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget) { Hotkey& hk = hotkey_groups[group][action]; if (!hk.shortcut) @@ -79,16 +69,12 @@ QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widge return hk.shortcut; } - -GHotkeysDialog::GHotkeysDialog(QWidget* parent): QWidget(parent) -{ +GHotkeysDialog::GHotkeysDialog(QWidget* parent) : QWidget(parent) { ui.setupUi(this); - for (auto group : hotkey_groups) - { + for (auto group : hotkey_groups) { QTreeWidgetItem* toplevel_item = new QTreeWidgetItem(QStringList(group.first)); - for (auto hotkey : group.second) - { + for (auto hotkey : group.second) { QStringList columns; columns << hotkey.first << hotkey.second.keyseq.toString(); QTreeWidgetItem* item = new QTreeWidgetItem(columns); diff --git a/src/citra_qt/hotkeys.h b/src/citra_qt/hotkeys.h index 38aa5f012..350103c6f 100644 --- a/src/citra_qt/hotkeys.h +++ b/src/citra_qt/hotkeys.h @@ -16,36 +16,42 @@ class QShortcut; * * @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger") * @param action Name of the action (e.g. "Start Emulation", "Load Image") - * @param default_keyseq Default key sequence to assign if the hotkey wasn't present in the settings file before - * @param default_context Default context to assign if the hotkey wasn't present in the settings file before + * @param default_keyseq Default key sequence to assign if the hotkey wasn't present in the settings + * file before + * @param default_context Default context to assign if the hotkey wasn't present in the settings + * file before * @warning Both the group and action strings will be displayed in the hotkey settings dialog */ -void RegisterHotkey(const QString& group, const QString& action, const QKeySequence& default_keyseq = QKeySequence(), Qt::ShortcutContext default_context = Qt::WindowShortcut); +void RegisterHotkey(const QString& group, const QString& action, + const QKeySequence& default_keyseq = QKeySequence(), + Qt::ShortcutContext default_context = Qt::WindowShortcut); /** * Returns a QShortcut object whose activated() signal can be connected to other QObjects' slots. * * @param widget Parent widget of the returned QShortcut. - * @warning If multiple QWidgets' call this function for the same action, the returned QShortcut will be the same. Thus, you shouldn't rely on the caller really being the QShortcut's parent. + * @warning If multiple QWidgets' call this function for the same action, the returned QShortcut + * will be the same. Thus, you shouldn't rely on the caller really being the QShortcut's parent. */ QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget); /** * Saves all registered hotkeys to the settings file. * - * @note Each hotkey group will be stored a settings group; For each hotkey inside that group, a settings group will be created to store the key sequence and the hotkey context. + * @note Each hotkey group will be stored a settings group; For each hotkey inside that group, a + * settings group will be created to store the key sequence and the hotkey context. */ void SaveHotkeys(); /** * Loads hotkeys from the settings file. * - * @note Yet unregistered hotkeys which are present in the settings will automatically be registered. + * @note Yet unregistered hotkeys which are present in the settings will automatically be + * registered. */ void LoadHotkeys(); -class GHotkeysDialog : public QWidget -{ +class GHotkeysDialog : public QWidget { Q_OBJECT public: diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index cf467532f..82667446b 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -5,25 +5,15 @@ #include <clocale> #include <memory> #include <thread> - #include <glad/glad.h> - #define QT_NO_OPENGL #include <QDesktopWidget> -#include <QtGui> #include <QFileDialog> #include <QMessageBox> -#include "qhexedit.h" - +#include <QtGui> #include "citra_qt/bootmanager.h" #include "citra_qt/config.h" #include "citra_qt/configure_dialog.h" -#include "citra_qt/game_list.h" -#include "citra_qt/hotkeys.h" -#include "citra_qt/main.h" -#include "citra_qt/ui_settings.h" - -// Debugger #include "citra_qt/debugger/callstack.h" #include "citra_qt/debugger/disassembler.h" #include "citra_qt/debugger/graphics.h" @@ -35,28 +25,29 @@ #include "citra_qt/debugger/profiler.h" #include "citra_qt/debugger/ramview.h" #include "citra_qt/debugger/registers.h" - +#include "citra_qt/game_list.h" +#include "citra_qt/hotkeys.h" +#include "citra_qt/main.h" +#include "citra_qt/ui_settings.h" +#include "common/logging/backend.h" +#include "common/logging/filter.h" +#include "common/logging/log.h" +#include "common/logging/text_formatter.h" #include "common/microprofile.h" #include "common/platform.h" #include "common/scm_rev.h" #include "common/scope_exit.h" #include "common/string_util.h" -#include "common/logging/backend.h" -#include "common/logging/filter.h" -#include "common/logging/log.h" -#include "common/logging/text_formatter.h" - -#include "core/core.h" -#include "core/settings.h" -#include "core/system.h" #include "core/arm/disassembler/load_symbol_map.h" +#include "core/core.h" #include "core/gdbstub/gdbstub.h" #include "core/loader/loader.h" - +#include "core/settings.h" +#include "core/system.h" +#include "qhexedit.h" #include "video_core/video_core.h" -GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) -{ +GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) { Pica::g_debug_context = Pica::DebugContext::Construct(); ui.setupUi(this); @@ -91,7 +82,7 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) graphicsWidget = new GPUCommandStreamWidget(this); addDockWidget(Qt::RightDockWidgetArea, graphicsWidget); - graphicsWidget ->hide(); + graphicsWidget->hide(); graphicsCommandsWidget = new GPUCommandListWidget(this); addDockWidget(Qt::RightDockWidgetArea, graphicsCommandsWidget); @@ -110,7 +101,8 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) graphicsTracingWidget->hide(); auto graphicsSurfaceViewerAction = new QAction(tr("Create Pica surface viewer"), this); - connect(graphicsSurfaceViewerAction, SIGNAL(triggered()), this, SLOT(OnCreateGraphicsSurfaceViewer())); + connect(graphicsSurfaceViewerAction, SIGNAL(triggered()), this, + SLOT(OnCreateGraphicsSurfaceViewer())); QMenu* debug_menu = ui.menu_View->addMenu(tr("Debugging")); debug_menu->addAction(graphicsSurfaceViewerAction); @@ -167,35 +159,44 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) UpdateRecentFiles(); // Setup connections - connect(game_list, SIGNAL(GameChosen(QString)), this, SLOT(OnGameListLoadFile(QString)), Qt::DirectConnection); + connect(game_list, SIGNAL(GameChosen(QString)), this, SLOT(OnGameListLoadFile(QString)), + Qt::DirectConnection); connect(ui.action_Configure, SIGNAL(triggered()), this, SLOT(OnConfigure())); - connect(ui.action_Load_File, SIGNAL(triggered()), this, SLOT(OnMenuLoadFile()),Qt::DirectConnection); + connect(ui.action_Load_File, SIGNAL(triggered()), this, SLOT(OnMenuLoadFile()), + Qt::DirectConnection); connect(ui.action_Load_Symbol_Map, SIGNAL(triggered()), this, SLOT(OnMenuLoadSymbolMap())); - connect(ui.action_Select_Game_List_Root, SIGNAL(triggered()), this, SLOT(OnMenuSelectGameListRoot())); + connect(ui.action_Select_Game_List_Root, SIGNAL(triggered()), this, + SLOT(OnMenuSelectGameListRoot())); connect(ui.action_Start, SIGNAL(triggered()), this, SLOT(OnStartGame())); connect(ui.action_Pause, SIGNAL(triggered()), this, SLOT(OnPauseGame())); connect(ui.action_Stop, SIGNAL(triggered()), this, SLOT(OnStopGame())); connect(ui.action_Single_Window_Mode, SIGNAL(triggered(bool)), this, SLOT(ToggleWindowMode())); - connect(this, SIGNAL(EmulationStarting(EmuThread*)), disasmWidget, SLOT(OnEmulationStarting(EmuThread*))); + connect(this, SIGNAL(EmulationStarting(EmuThread*)), disasmWidget, + SLOT(OnEmulationStarting(EmuThread*))); connect(this, SIGNAL(EmulationStopping()), disasmWidget, SLOT(OnEmulationStopping())); - connect(this, SIGNAL(EmulationStarting(EmuThread*)), registersWidget, SLOT(OnEmulationStarting(EmuThread*))); + connect(this, SIGNAL(EmulationStarting(EmuThread*)), registersWidget, + SLOT(OnEmulationStarting(EmuThread*))); connect(this, SIGNAL(EmulationStopping()), registersWidget, SLOT(OnEmulationStopping())); - connect(this, SIGNAL(EmulationStarting(EmuThread*)), render_window, SLOT(OnEmulationStarting(EmuThread*))); + connect(this, SIGNAL(EmulationStarting(EmuThread*)), render_window, + SLOT(OnEmulationStarting(EmuThread*))); connect(this, SIGNAL(EmulationStopping()), render_window, SLOT(OnEmulationStopping())); - connect(this, SIGNAL(EmulationStarting(EmuThread*)), graphicsTracingWidget, SLOT(OnEmulationStarting(EmuThread*))); + connect(this, SIGNAL(EmulationStarting(EmuThread*)), graphicsTracingWidget, + SLOT(OnEmulationStarting(EmuThread*))); connect(this, SIGNAL(EmulationStopping()), graphicsTracingWidget, SLOT(OnEmulationStopping())); - // Setup hotkeys RegisterHotkey("Main Window", "Load File", QKeySequence::Open); RegisterHotkey("Main Window", "Start Emulation"); LoadHotkeys(); - connect(GetHotkey("Main Window", "Load File", this), SIGNAL(activated()), this, SLOT(OnMenuLoadFile())); - connect(GetHotkey("Main Window", "Start Emulation", this), SIGNAL(activated()), this, SLOT(OnStartGame())); + connect(GetHotkey("Main Window", "Load File", this), SIGNAL(activated()), this, + SLOT(OnMenuLoadFile())); + connect(GetHotkey("Main Window", "Start Emulation", this), SIGNAL(activated()), this, + SLOT(OnStartGame())); - std::string window_title = Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); + std::string window_title = + Common::StringFromFormat("Citra | %s-%s", Common::g_scm_branch, Common::g_scm_desc); setWindowTitle(window_title.c_str()); show(); @@ -208,8 +209,7 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) } } -GMainWindow::~GMainWindow() -{ +GMainWindow::~GMainWindow() { // will get automatically deleted otherwise if (render_window->parent() == nullptr) delete render_window; @@ -217,19 +217,18 @@ GMainWindow::~GMainWindow() Pica::g_debug_context.reset(); } -void GMainWindow::OnDisplayTitleBars(bool show) -{ +void GMainWindow::OnDisplayTitleBars(bool show) { QList<QDockWidget*> widgets = findChildren<QDockWidget*>(); if (show) { - for (QDockWidget* widget: widgets) { + for (QDockWidget* widget : widgets) { QWidget* old = widget->titleBarWidget(); widget->setTitleBarWidget(nullptr); if (old != nullptr) delete old; } } else { - for (QDockWidget* widget: widgets) { + for (QDockWidget* widget : widgets) { QWidget* old = widget->titleBarWidget(); widget->setTitleBarWidget(new QWidget()); if (old != nullptr) @@ -249,7 +248,8 @@ bool GMainWindow::InitializeSystem() { if (!gladLoadGL()) { QMessageBox::critical(this, tr("Error while starting Citra!"), tr("Failed to initialize the video core!\n\n" - "Please ensure that your GPU supports OpenGL 3.3 and that you have the latest graphics driver.")); + "Please ensure that your GPU supports OpenGL 3.3 and that you " + "have the latest graphics driver.")); return false; } @@ -260,7 +260,8 @@ bool GMainWindow::InitializeSystem() { case System::Result::ErrorInitVideoCore: QMessageBox::critical(this, tr("Error while starting Citra!"), tr("Failed to initialize the video core!\n\n" - "Please ensure that your GPU supports OpenGL 3.3 and that you have the latest graphics driver.")); + "Please ensure that your GPU supports OpenGL 3.3 and that you " + "have the latest graphics driver.")); break; default: @@ -293,8 +294,12 @@ bool GMainWindow::LoadROM(const std::string& filename) { QMessageBox popup_error; popup_error.setTextFormat(Qt::RichText); popup_error.setWindowTitle(tr("Error while loading ROM!")); - popup_error.setText(tr("The game that you are trying to load must be decrypted before being used with Citra.<br/><br/>" - "For more information on dumping and decrypting games, please see: <a href='https://citra-emu.org/wiki/Dumping-Game-Cartridges'>https://citra-emu.org/wiki/Dumping-Game-Cartridges</a>")); + popup_error.setText( + tr("The game that you are trying to load must be decrypted before being used with " + "Citra.<br/><br/>" + "For more information on dumping and decrypting games, please see: <a " + "href='https://citra-emu.org/wiki/Dumping-Game-Cartridges'>https://" + "citra-emu.org/wiki/Dumping-Game-Cartridges</a>")); popup_error.setIcon(QMessageBox::Critical); popup_error.exec(); break; @@ -306,8 +311,7 @@ bool GMainWindow::LoadROM(const std::string& filename) { case Loader::ResultStatus::Error: default: - QMessageBox::critical(this, tr("Error while loading ROM!"), - tr("Unknown error!")); + QMessageBox::critical(this, tr("Error while loading ROM!"), tr("Unknown error!")); break; } return false; @@ -332,13 +336,20 @@ void GMainWindow::BootGame(const std::string& filename) { emu_thread->start(); connect(render_window, SIGNAL(Closed()), this, SLOT(OnStopGame())); - // BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views before the CPU continues - connect(emu_thread.get(), SIGNAL(DebugModeEntered()), disasmWidget, SLOT(OnDebugModeEntered()), Qt::BlockingQueuedConnection); - connect(emu_thread.get(), SIGNAL(DebugModeEntered()), registersWidget, SLOT(OnDebugModeEntered()), Qt::BlockingQueuedConnection); - connect(emu_thread.get(), SIGNAL(DebugModeEntered()), callstackWidget, SLOT(OnDebugModeEntered()), Qt::BlockingQueuedConnection); - connect(emu_thread.get(), SIGNAL(DebugModeLeft()), disasmWidget, SLOT(OnDebugModeLeft()), Qt::BlockingQueuedConnection); - connect(emu_thread.get(), SIGNAL(DebugModeLeft()), registersWidget, SLOT(OnDebugModeLeft()), Qt::BlockingQueuedConnection); - connect(emu_thread.get(), SIGNAL(DebugModeLeft()), callstackWidget, SLOT(OnDebugModeLeft()), Qt::BlockingQueuedConnection); + // BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views + // before the CPU continues + connect(emu_thread.get(), SIGNAL(DebugModeEntered()), disasmWidget, SLOT(OnDebugModeEntered()), + Qt::BlockingQueuedConnection); + connect(emu_thread.get(), SIGNAL(DebugModeEntered()), registersWidget, + SLOT(OnDebugModeEntered()), Qt::BlockingQueuedConnection); + connect(emu_thread.get(), SIGNAL(DebugModeEntered()), callstackWidget, + SLOT(OnDebugModeEntered()), Qt::BlockingQueuedConnection); + connect(emu_thread.get(), SIGNAL(DebugModeLeft()), disasmWidget, SLOT(OnDebugModeLeft()), + Qt::BlockingQueuedConnection); + connect(emu_thread.get(), SIGNAL(DebugModeLeft()), registersWidget, SLOT(OnDebugModeLeft()), + Qt::BlockingQueuedConnection); + connect(emu_thread.get(), SIGNAL(DebugModeLeft()), callstackWidget, SLOT(OnDebugModeLeft()), + Qt::BlockingQueuedConnection); // Update the GUI registersWidget->OnDebugModeEntered(); @@ -393,10 +404,12 @@ void GMainWindow::StoreRecentFile(const std::string& filename) { } void GMainWindow::UpdateRecentFiles() { - unsigned int num_recent_files = std::min(UISettings::values.recent_files.size(), static_cast<int>(max_recent_files_item)); + unsigned int num_recent_files = + std::min(UISettings::values.recent_files.size(), static_cast<int>(max_recent_files_item)); for (unsigned int i = 0; i < num_recent_files; i++) { - QString text = QString("&%1. %2").arg(i + 1).arg(QFileInfo(UISettings::values.recent_files[i]).fileName()); + QString text = QString("&%1. %2").arg(i + 1).arg( + QFileInfo(UISettings::values.recent_files[i]).fileName()); actions_recent_files[i]->setText(text); actions_recent_files[i]->setData(UISettings::values.recent_files[i]); actions_recent_files[i]->setToolTip(UISettings::values.recent_files[i]); @@ -420,7 +433,9 @@ void GMainWindow::OnGameListLoadFile(QString game_path) { } void GMainWindow::OnMenuLoadFile() { - QString filename = QFileDialog::getOpenFileName(this, tr("Load File"), UISettings::values.roms_path, tr("3DS executable (*.3ds *.3dsx *.elf *.axf *.cci *.cxi)")); + QString filename = + QFileDialog::getOpenFileName(this, tr("Load File"), UISettings::values.roms_path, + tr("3DS executable (*.3ds *.3dsx *.elf *.axf *.cci *.cxi)")); if (!filename.isEmpty()) { UISettings::values.roms_path = QFileInfo(filename).path(); @@ -429,7 +444,8 @@ void GMainWindow::OnMenuLoadFile() { } void GMainWindow::OnMenuLoadSymbolMap() { - QString filename = QFileDialog::getOpenFileName(this, tr("Load Symbol Map"), UISettings::values.symbols_path, tr("Symbol map (*)")); + QString filename = QFileDialog::getOpenFileName( + this, tr("Load Symbol Map"), UISettings::values.symbols_path, tr("Symbol map (*)")); if (!filename.isEmpty()) { UISettings::values.symbols_path = QFileInfo(filename).path(); @@ -455,7 +471,8 @@ void GMainWindow::OnMenuRecentFile() { BootGame(filename.toStdString()); } else { // Display an error message and remove the file from the list. - QMessageBox::information(this, tr("File not found"), tr("File \"%1\" not found").arg(filename)); + QMessageBox::information(this, tr("File not found"), + tr("File \"%1\" not found").arg(filename)); UISettings::values.recent_files.removeOne(filename); UpdateRecentFiles(); @@ -512,8 +529,7 @@ void GMainWindow::ToggleWindowMode() { void GMainWindow::OnConfigure() { ConfigureDialog configureDialog(this); auto result = configureDialog.exec(); - if (result == QDialog::Accepted) - { + if (result == QDialog::Accepted) { configureDialog.applyConfiguration(); render_window->ReloadSetKeymaps(); config->Save(); @@ -531,9 +547,9 @@ bool GMainWindow::ConfirmClose() { if (emu_thread == nullptr || !UISettings::values.confirm_before_closing) return true; - auto answer = QMessageBox::question(this, tr("Citra"), - tr("Are you sure you want to close Citra?"), - QMessageBox::Yes | QMessageBox::No, QMessageBox::No); + auto answer = + QMessageBox::question(this, tr("Citra"), tr("Are you sure you want to close Citra?"), + QMessageBox::Yes | QMessageBox::No, QMessageBox::No); return answer != QMessageBox::No; } @@ -575,9 +591,7 @@ int main(int argc, char* argv[]) { Log::SetFilter(&log_filter); MicroProfileOnThreadCreate("Frontend"); - SCOPE_EXIT({ - MicroProfileShutdown(); - }); + SCOPE_EXIT({ MicroProfileShutdown(); }); // Init settings params QCoreApplication::setOrganizationName("Citra team"); @@ -586,7 +600,8 @@ int main(int argc, char* argv[]) { QApplication::setAttribute(Qt::AA_X11InitThreads); QApplication app(argc, argv); - // Qt changes the locale and causes issues in float conversion using std::to_string() when generating shaders + // Qt changes the locale and causes issues in float conversion using std::to_string() when + // generating shaders setlocale(LC_ALL, "C"); GMainWindow main_window; diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h index b836b13fb..c4349513f 100644 --- a/src/citra_qt/main.h +++ b/src/citra_qt/main.h @@ -7,7 +7,6 @@ #include <memory> #include <QMainWindow> - #include "ui_main.h" class Config; @@ -23,11 +22,11 @@ class CallstackWidget; class GPUCommandStreamWidget; class GPUCommandListWidget; -class GMainWindow : public QMainWindow -{ +class GMainWindow : public QMainWindow { Q_OBJECT - static const int max_recent_files_item = 10; ///< Max number of recently loaded items to keep track + /// Max number of recently loaded items to keep track of + static const int max_recent_files_item = 10; // TODO: Make use of this! enum { diff --git a/src/citra_qt/ui_settings.cpp b/src/citra_qt/ui_settings.cpp index 5f2215899..120b34990 100644 --- a/src/citra_qt/ui_settings.cpp +++ b/src/citra_qt/ui_settings.cpp @@ -7,5 +7,4 @@ namespace UISettings { Values values = {}; - } diff --git a/src/citra_qt/ui_settings.h b/src/citra_qt/ui_settings.h index 62db4a73e..ed7fdff7e 100644 --- a/src/citra_qt/ui_settings.h +++ b/src/citra_qt/ui_settings.h @@ -4,15 +4,14 @@ #pragma once +#include <vector> #include <QByteArray> -#include <QStringList> #include <QString> - -#include <vector> +#include <QStringList> namespace UISettings { -using ContextualShortcut = std::pair<QString, int> ; +using ContextualShortcut = std::pair<QString, int>; using Shortcut = std::pair<QString, ContextualShortcut>; struct Values { @@ -43,5 +42,4 @@ struct Values { }; extern Values values; - } diff --git a/src/citra_qt/util/spinbox.cpp b/src/citra_qt/util/spinbox.cpp index 415e7fbec..feb0ea1b3 100644 --- a/src/citra_qt/util/spinbox.cpp +++ b/src/citra_qt/util/spinbox.cpp @@ -1,7 +1,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. - // Copyright 2014 Tony Wasserka // All rights reserved. // @@ -32,12 +31,11 @@ #include <cstdlib> #include <QLineEdit> #include <QRegExpValidator> - #include "citra_qt/util/spinbox.h" #include "common/assert.h" -CSpinBox::CSpinBox(QWidget* parent) : QAbstractSpinBox(parent), min_value(-100), max_value(100), value(0), base(10), num_digits(0) -{ +CSpinBox::CSpinBox(QWidget* parent) + : QAbstractSpinBox(parent), min_value(-100), max_value(100), value(0), base(10), num_digits(0) { // TODO: Might be nice to not immediately call the slot. // Think of an address that is being replaced by a different one, in which case a lot // invalid intermediate addresses would be read from during editing. @@ -46,8 +44,7 @@ CSpinBox::CSpinBox(QWidget* parent) : QAbstractSpinBox(parent), min_value(-100), UpdateText(); } -void CSpinBox::SetValue(qint64 val) -{ +void CSpinBox::SetValue(qint64 val) { auto old_value = value; value = std::max(std::min(val, max_value), min_value); @@ -57,8 +54,7 @@ void CSpinBox::SetValue(qint64 val) } } -void CSpinBox::SetRange(qint64 min, qint64 max) -{ +void CSpinBox::SetRange(qint64 min, qint64 max) { min_value = min; max_value = max; @@ -66,8 +62,7 @@ void CSpinBox::SetRange(qint64 min, qint64 max) UpdateText(); } -void CSpinBox::stepBy(int steps) -{ +void CSpinBox::stepBy(int steps) { auto new_value = value; // Scale number of steps by the currently selected digit // TODO: Move this code elsewhere and enable it. @@ -93,8 +88,7 @@ void CSpinBox::stepBy(int steps) UpdateText(); } -QAbstractSpinBox::StepEnabled CSpinBox::stepEnabled() const -{ +QAbstractSpinBox::StepEnabled CSpinBox::stepEnabled() const { StepEnabled ret = StepNone; if (value > min_value) @@ -106,29 +100,25 @@ QAbstractSpinBox::StepEnabled CSpinBox::stepEnabled() const return ret; } -void CSpinBox::SetBase(int base) -{ +void CSpinBox::SetBase(int base) { this->base = base; UpdateText(); } -void CSpinBox::SetNumDigits(int num_digits) -{ +void CSpinBox::SetNumDigits(int num_digits) { this->num_digits = num_digits; UpdateText(); } -void CSpinBox::SetPrefix(const QString& prefix) -{ +void CSpinBox::SetPrefix(const QString& prefix) { this->prefix = prefix; UpdateText(); } -void CSpinBox::SetSuffix(const QString& suffix) -{ +void CSpinBox::SetSuffix(const QString& suffix) { this->suffix = suffix; UpdateText(); @@ -161,8 +151,7 @@ static QString StringToInputMask(const QString& input) { return mask; } -void CSpinBox::UpdateText() -{ +void CSpinBox::UpdateText() { // If a fixed number of digits is used, we put the line edit in insertion mode by setting an // input mask. QString mask; @@ -179,10 +168,9 @@ void CSpinBox::UpdateText() // The greatest signed 64-bit number has 19 decimal digits. // TODO: Could probably make this more generic with some logarithms. // For reference, unsigned 64-bit can have up to 20 decimal digits. - int digits = (num_digits != 0) ? num_digits - : (base == 16) ? 16 - : (base == 10) ? 19 - : 0xFF; // fallback case... + int digits = (num_digits != 0) + ? num_digits + : (base == 16) ? 16 : (base == 10) ? 19 : 0xFF; // fallback case... // Match num_digits digits // Digits irrelevant to the chosen number base are filtered in the validator @@ -203,29 +191,24 @@ void CSpinBox::UpdateText() lineEdit()->setCursorPosition(cursor_position); } -QString CSpinBox::TextFromValue() -{ - return prefix - + QString(HasSign() ? ((value < 0) ? "-" : "+") : "") - + QString("%1").arg(std::abs(value), num_digits, base, QLatin1Char('0')).toUpper() - + suffix; +QString CSpinBox::TextFromValue() { + return prefix + QString(HasSign() ? ((value < 0) ? "-" : "+") : "") + + QString("%1").arg(std::abs(value), num_digits, base, QLatin1Char('0')).toUpper() + + suffix; } -qint64 CSpinBox::ValueFromText() -{ +qint64 CSpinBox::ValueFromText() { unsigned strpos = prefix.length(); QString num_string = text().mid(strpos, text().length() - strpos - suffix.length()); return num_string.toLongLong(nullptr, base); } -bool CSpinBox::HasSign() const -{ +bool CSpinBox::HasSign() const { return base == 10 && min_value < 0; } -void CSpinBox::OnEditingFinished() -{ +void CSpinBox::OnEditingFinished() { // Only update for valid input QString input = lineEdit()->text(); int pos = 0; @@ -233,8 +216,7 @@ void CSpinBox::OnEditingFinished() SetValue(ValueFromText()); } -QValidator::State CSpinBox::validate(QString& input, int& pos) const -{ +QValidator::State CSpinBox::validate(QString& input, int& pos) const { if (!prefix.isEmpty() && input.left(prefix.length()) != prefix) return QValidator::Invalid; diff --git a/src/citra_qt/util/spinbox.h b/src/citra_qt/util/spinbox.h index ee7f08ec2..a57355cd6 100644 --- a/src/citra_qt/util/spinbox.h +++ b/src/citra_qt/util/spinbox.h @@ -1,7 +1,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. - // Copyright 2014 Tony Wasserka // All rights reserved. // @@ -29,7 +28,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - #pragma once #include <QAbstractSpinBox> diff --git a/src/citra_qt/util/util.cpp b/src/citra_qt/util/util.cpp index 2f9beb5cc..02be92bbd 100644 --- a/src/citra_qt/util/util.cpp +++ b/src/citra_qt/util/util.cpp @@ -4,7 +4,6 @@ #include <array> #include <cmath> - #include "citra_qt/util/util.h" QFont GetMonospaceFont() { @@ -16,10 +15,12 @@ QFont GetMonospaceFont() { } QString ReadableByteSize(qulonglong size) { - static const std::array<const char*, 6> units = { "B", "KiB", "MiB", "GiB", "TiB", "PiB" }; + static const std::array<const char*, 6> units = {"B", "KiB", "MiB", "GiB", "TiB", "PiB"}; if (size == 0) return "0"; - int digit_groups = std::min<int>(static_cast<int>(std::log10(size) / std::log10(1024)), static_cast<int>(units.size())); - return QString("%L1 %2").arg(size / std::pow(1024, digit_groups), 0, 'f', 1) - .arg(units[digit_groups]); + int digit_groups = std::min<int>(static_cast<int>(std::log10(size) / std::log10(1024)), + static_cast<int>(units.size())); + return QString("%L1 %2") + .arg(size / std::pow(1024, digit_groups), 0, 'f', 1) + .arg(units[digit_groups]); } diff --git a/src/common/assert.h b/src/common/assert.h index cd9b819a9..04e80c87a 100644 --- a/src/common/assert.h +++ b/src/common/assert.h @@ -5,7 +5,6 @@ #pragma once #include <cstdlib> - #include "common/common_funcs.h" #include "common/logging/log.h" @@ -18,25 +17,29 @@ // enough for our purposes. template <typename Fn> #if defined(_MSC_VER) - __declspec(noinline, noreturn) +__declspec(noinline, noreturn) #elif defined(__GNUC__) __attribute__((noinline, noreturn, cold)) #endif -static void assert_noinline_call(const Fn& fn) { + static void assert_noinline_call(const Fn& fn) { fn(); Crash(); exit(1); // Keeps GCC's mouth shut about this actually returning } -#define ASSERT(_a_) \ - do if (!(_a_)) { assert_noinline_call([] { \ - LOG_CRITICAL(Debug, "Assertion Failed!"); \ - }); } while (0) +#define ASSERT(_a_) \ + do \ + if (!(_a_)) { \ + assert_noinline_call([] { LOG_CRITICAL(Debug, "Assertion Failed!"); }); \ + } \ + while (0) -#define ASSERT_MSG(_a_, ...) \ - do if (!(_a_)) { assert_noinline_call([&] { \ - LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); \ - }); } while (0) +#define ASSERT_MSG(_a_, ...) \ + do \ + if (!(_a_)) { \ + assert_noinline_call([&] { LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); }); \ + } \ + while (0) #define UNREACHABLE() ASSERT_MSG(false, "Unreachable code!") #define UNREACHABLE_MSG(...) ASSERT_MSG(false, __VA_ARGS__) @@ -50,4 +53,4 @@ static void assert_noinline_call(const Fn& fn) { #endif #define UNIMPLEMENTED() DEBUG_ASSERT_MSG(false, "Unimplemented code!") -#define UNIMPLEMENTED_MSG(_a_, ...) ASSERT_MSG(false, _a_, __VA_ARGS__)
\ No newline at end of file +#define UNIMPLEMENTED_MSG(_a_, ...) ASSERT_MSG(false, _a_, __VA_ARGS__) diff --git a/src/common/bit_field.h b/src/common/bit_field.h index 4748999ed..030f7caeb 100644 --- a/src/common/bit_field.h +++ b/src/common/bit_field.h @@ -1,7 +1,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. - // Copyright 2014 Tony Wasserka // All rights reserved. // @@ -29,13 +28,11 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - #pragma once #include <cstddef> #include <limits> #include <type_traits> - #include "common/common_funcs.h" /* @@ -111,9 +108,8 @@ * symptoms. */ #pragma pack(1) -template<std::size_t position, std::size_t bits, typename T> -struct BitField -{ +template <std::size_t position, std::size_t bits, typename T> +struct BitField { private: // We hide the copy assigment operator here, because the default copy // assignment would copy the full storage value, rather than just the bits @@ -141,13 +137,10 @@ public: } FORCE_INLINE T Value() const { - if (std::numeric_limits<T>::is_signed) - { - std::size_t shift = 8 * sizeof(T)-bits; + if (std::numeric_limits<T>::is_signed) { + std::size_t shift = 8 * sizeof(T) - bits; return (T)((storage << (shift - position)) >> shift); - } - else - { + } else { return (T)((storage & GetMask()) >> position); } } @@ -162,15 +155,14 @@ private: // T is an enumeration. Note that T is wrapped within an enable_if in the // former case to workaround compile errors which arise when using // std::underlying_type<T>::type directly. - typedef typename std::conditional < std::is_enum<T>::value, - std::underlying_type<T>, - std::enable_if < true, T >> ::type::type StorageType; + typedef typename std::conditional<std::is_enum<T>::value, std::underlying_type<T>, + std::enable_if<true, T>>::type::type StorageType; // Unsigned version of StorageType typedef typename std::make_unsigned<StorageType>::type StorageTypeU; FORCE_INLINE StorageType GetMask() const { - return (((StorageTypeU)~0) >> (8 * sizeof(T)-bits)) << position; + return (((StorageTypeU)~0) >> (8 * sizeof(T) - bits)) << position; } StorageType storage; @@ -186,5 +178,6 @@ private: #pragma pack() #if (__GNUC__ >= 5) || defined(__clang__) || defined(_MSC_VER) -static_assert(std::is_trivially_copyable<BitField<0, 1, unsigned>>::value, "BitField must be trivially copyable"); +static_assert(std::is_trivially_copyable<BitField<0, 1, unsigned>>::value, + "BitField must be trivially copyable"); #endif diff --git a/src/common/bit_set.h b/src/common/bit_set.h index 7f5de8df2..c48b3b769 100644 --- a/src/common/bit_set.h +++ b/src/common/bit_set.h @@ -18,49 +18,60 @@ namespace Common { #ifdef _WIN32 template <typename T> -static inline int CountSetBits(T v) -{ +static inline int CountSetBits(T v) { // from https://graphics.stanford.edu/~seander/bithacks.html // GCC has this built in, but MSVC's intrinsic will only emit the actual // POPCNT instruction, which we're not depending on - v = v - ((v >> 1) & (T)~(T)0/3); - v = (v & (T)~(T)0/15*3) + ((v >> 2) & (T)~(T)0/15*3); - v = (v + (v >> 4)) & (T)~(T)0/255*15; - return (T)(v * ((T)~(T)0/255)) >> (sizeof(T) - 1) * 8; + v = v - ((v >> 1) & (T) ~(T)0 / 3); + v = (v & (T) ~(T)0 / 15 * 3) + ((v >> 2) & (T) ~(T)0 / 15 * 3); + v = (v + (v >> 4)) & (T) ~(T)0 / 255 * 15; + return (T)(v * ((T) ~(T)0 / 255)) >> (sizeof(T) - 1) * 8; } -static inline int LeastSignificantSetBit(u8 val) -{ +static inline int LeastSignificantSetBit(u8 val) { unsigned long index; _BitScanForward(&index, val); return (int)index; } -static inline int LeastSignificantSetBit(u16 val) -{ +static inline int LeastSignificantSetBit(u16 val) { unsigned long index; _BitScanForward(&index, val); return (int)index; } -static inline int LeastSignificantSetBit(u32 val) -{ +static inline int LeastSignificantSetBit(u32 val) { unsigned long index; _BitScanForward(&index, val); return (int)index; } -static inline int LeastSignificantSetBit(u64 val) -{ +static inline int LeastSignificantSetBit(u64 val) { unsigned long index; _BitScanForward64(&index, val); return (int)index; } #else -static inline int CountSetBits(u8 val) { return __builtin_popcount(val); } -static inline int CountSetBits(u16 val) { return __builtin_popcount(val); } -static inline int CountSetBits(u32 val) { return __builtin_popcount(val); } -static inline int CountSetBits(u64 val) { return __builtin_popcountll(val); } -static inline int LeastSignificantSetBit(u8 val) { return __builtin_ctz(val); } -static inline int LeastSignificantSetBit(u16 val) { return __builtin_ctz(val); } -static inline int LeastSignificantSetBit(u32 val) { return __builtin_ctz(val); } -static inline int LeastSignificantSetBit(u64 val) { return __builtin_ctzll(val); } +static inline int CountSetBits(u8 val) { + return __builtin_popcount(val); +} +static inline int CountSetBits(u16 val) { + return __builtin_popcount(val); +} +static inline int CountSetBits(u32 val) { + return __builtin_popcount(val); +} +static inline int CountSetBits(u64 val) { + return __builtin_popcountll(val); +} +static inline int LeastSignificantSetBit(u8 val) { + return __builtin_ctz(val); +} +static inline int LeastSignificantSetBit(u16 val) { + return __builtin_ctz(val); +} +static inline int LeastSignificantSetBit(u32 val) { + return __builtin_ctz(val); +} +static inline int LeastSignificantSetBit(u64 val) { + return __builtin_ctzll(val); +} #endif // Similar to std::bitset, this is a class which encapsulates a bitset, i.e. @@ -84,57 +95,62 @@ static inline int LeastSignificantSetBit(u64 val) { return __builtin_ctzll(val); // TODO: use constexpr when MSVC gets out of the Dark Ages template <typename IntTy> -class BitSet -{ +class BitSet { static_assert(!std::is_signed<IntTy>::value, "BitSet should not be used with signed types"); + public: // A reference to a particular bit, returned from operator[]. - class Ref - { + class Ref { public: Ref(Ref&& other) : m_bs(other.m_bs), m_mask(other.m_mask) {} Ref(BitSet* bs, IntTy mask) : m_bs(bs), m_mask(mask) {} - operator bool() const { return (m_bs->m_val & m_mask) != 0; } - bool operator=(bool set) - { + operator bool() const { + return (m_bs->m_val & m_mask) != 0; + } + bool operator=(bool set) { m_bs->m_val = (m_bs->m_val & ~m_mask) | (set ? m_mask : 0); return set; } + private: BitSet* m_bs; IntTy m_mask; }; // A STL-like iterator is required to be able to use range-based for loops. - class Iterator - { + class Iterator { public: Iterator(const Iterator& other) : m_val(other.m_val), m_bit(other.m_bit) {} Iterator(IntTy val, int bit) : m_val(val), m_bit(bit) {} - Iterator& operator=(Iterator other) { new (this) Iterator(other); return *this; } - int operator*() { return m_bit; } - Iterator& operator++() - { - if (m_val == 0) - { + Iterator& operator=(Iterator other) { + new (this) Iterator(other); + return *this; + } + int operator*() { + return m_bit; + } + Iterator& operator++() { + if (m_val == 0) { m_bit = -1; - } - else - { + } else { int bit = LeastSignificantSetBit(m_val); m_val &= ~(1 << bit); m_bit = bit; } return *this; } - Iterator operator++(int _) - { + Iterator operator++(int _) { Iterator other(*this); ++*this; return other; } - bool operator==(Iterator other) const { return m_bit == other.m_bit; } - bool operator!=(Iterator other) const { return m_bit != other.m_bit; } + bool operator==(Iterator other) const { + return m_bit == other.m_bit; + } + bool operator!=(Iterator other) const { + return m_bit != other.m_bit; + } + private: IntTy m_val; int m_bit; @@ -142,42 +158,75 @@ public: BitSet() : m_val(0) {} explicit BitSet(IntTy val) : m_val(val) {} - BitSet(std::initializer_list<int> init) - { + BitSet(std::initializer_list<int> init) { m_val = 0; for (int bit : init) m_val |= (IntTy)1 << bit; } - static BitSet AllTrue(size_t count) - { - return BitSet(count == sizeof(IntTy)*8 ? ~(IntTy)0 : (((IntTy)1 << count) - 1)); - } - - Ref operator[](size_t bit) { return Ref(this, (IntTy)1 << bit); } - const Ref operator[](size_t bit) const { return (*const_cast<BitSet*>(this))[bit]; } - bool operator==(BitSet other) const { return m_val == other.m_val; } - bool operator!=(BitSet other) const { return m_val != other.m_val; } - bool operator<(BitSet other) const { return m_val < other.m_val; } - bool operator>(BitSet other) const { return m_val > other.m_val; } - BitSet operator|(BitSet other) const { return BitSet(m_val | other.m_val); } - BitSet operator&(BitSet other) const { return BitSet(m_val & other.m_val); } - BitSet operator^(BitSet other) const { return BitSet(m_val ^ other.m_val); } - BitSet operator~() const { return BitSet(~m_val); } - BitSet& operator|=(BitSet other) { return *this = *this | other; } - BitSet& operator&=(BitSet other) { return *this = *this & other; } - BitSet& operator^=(BitSet other) { return *this = *this ^ other; } + static BitSet AllTrue(size_t count) { + return BitSet(count == sizeof(IntTy) * 8 ? ~(IntTy)0 : (((IntTy)1 << count) - 1)); + } + + Ref operator[](size_t bit) { + return Ref(this, (IntTy)1 << bit); + } + const Ref operator[](size_t bit) const { + return (*const_cast<BitSet*>(this))[bit]; + } + bool operator==(BitSet other) const { + return m_val == other.m_val; + } + bool operator!=(BitSet other) const { + return m_val != other.m_val; + } + bool operator<(BitSet other) const { + return m_val < other.m_val; + } + bool operator>(BitSet other) const { + return m_val > other.m_val; + } + BitSet operator|(BitSet other) const { + return BitSet(m_val | other.m_val); + } + BitSet operator&(BitSet other) const { + return BitSet(m_val & other.m_val); + } + BitSet operator^(BitSet other) const { + return BitSet(m_val ^ other.m_val); + } + BitSet operator~() const { + return BitSet(~m_val); + } + BitSet& operator|=(BitSet other) { + return *this = *this | other; + } + BitSet& operator&=(BitSet other) { + return *this = *this & other; + } + BitSet& operator^=(BitSet other) { + return *this = *this ^ other; + } operator u32() = delete; - operator bool() { return m_val != 0; } + operator bool() { + return m_val != 0; + } // Warning: Even though on modern CPUs this is a single fast instruction, // Dolphin's official builds do not currently assume POPCNT support on x86, // so slower explicit bit twiddling is generated. Still should generally // be faster than a loop. - unsigned int Count() const { return CountSetBits(m_val); } + unsigned int Count() const { + return CountSetBits(m_val); + } - Iterator begin() const { Iterator it(m_val, 0); return ++it; } - Iterator end() const { return Iterator(m_val, -1); } + Iterator begin() const { + Iterator it(m_val, 0); + return ++it; + } + Iterator end() const { + return Iterator(m_val, -1); + } IntTy m_val; }; diff --git a/src/common/break_points.cpp b/src/common/break_points.cpp index e7d0d3e43..03a19acba 100644 --- a/src/common/break_points.cpp +++ b/src/common/break_points.cpp @@ -2,33 +2,29 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <algorithm> +#include <sstream> #include "common/break_points.h" #include "common/logging/log.h" -#include <sstream> -#include <algorithm> - -bool BreakPoints::IsAddressBreakPoint(u32 iAddress) const -{ +bool BreakPoints::IsAddressBreakPoint(u32 iAddress) const { auto cond = [&iAddress](const TBreakPoint& bp) { return bp.iAddress == iAddress; }; - auto it = std::find_if(m_BreakPoints.begin(), m_BreakPoints.end(), cond); + auto it = std::find_if(m_BreakPoints.begin(), m_BreakPoints.end(), cond); return it != m_BreakPoints.end(); } -bool BreakPoints::IsTempBreakPoint(u32 iAddress) const -{ - auto cond = [&iAddress](const TBreakPoint& bp) { return bp.iAddress == iAddress && bp.bTemporary; }; - auto it = std::find_if(m_BreakPoints.begin(), m_BreakPoints.end(), cond); +bool BreakPoints::IsTempBreakPoint(u32 iAddress) const { + auto cond = [&iAddress](const TBreakPoint& bp) { + return bp.iAddress == iAddress && bp.bTemporary; + }; + auto it = std::find_if(m_BreakPoints.begin(), m_BreakPoints.end(), cond); return it != m_BreakPoints.end(); } -BreakPoints::TBreakPointsStr BreakPoints::GetStrings() const -{ +BreakPoints::TBreakPointsStr BreakPoints::GetStrings() const { TBreakPointsStr bps; - for (auto breakpoint : m_BreakPoints) - { - if (!breakpoint.bTemporary) - { + for (auto breakpoint : m_BreakPoints) { + if (!breakpoint.bTemporary) { std::stringstream bp; bp << std::hex << breakpoint.iAddress << " " << (breakpoint.bOn ? "n" : ""); bps.push_back(bp.str()); @@ -38,10 +34,8 @@ BreakPoints::TBreakPointsStr BreakPoints::GetStrings() const return bps; } -void BreakPoints::AddFromStrings(const TBreakPointsStr& bps) -{ - for (auto bps_item : bps) - { +void BreakPoints::AddFromStrings(const TBreakPointsStr& bps) { + for (auto bps_item : bps) { TBreakPoint bp; std::stringstream bpstr; bpstr << std::hex << bps_item; @@ -52,18 +46,15 @@ void BreakPoints::AddFromStrings(const TBreakPointsStr& bps) } } -void BreakPoints::Add(const TBreakPoint& bp) -{ - if (!IsAddressBreakPoint(bp.iAddress)) - { +void BreakPoints::Add(const TBreakPoint& bp) { + if (!IsAddressBreakPoint(bp.iAddress)) { m_BreakPoints.push_back(bp); - //if (jit) + // if (jit) // jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4); } } -void BreakPoints::Add(u32 em_address, bool temp) -{ +void BreakPoints::Add(u32 em_address, bool temp) { if (!IsAddressBreakPoint(em_address)) // only add new addresses { TBreakPoint pt; // breakpoint settings @@ -73,22 +64,20 @@ void BreakPoints::Add(u32 em_address, bool temp) m_BreakPoints.push_back(pt); - //if (jit) + // if (jit) // jit->GetBlockCache()->InvalidateICache(em_address, 4); } } -void BreakPoints::Remove(u32 em_address) -{ +void BreakPoints::Remove(u32 em_address) { auto cond = [&em_address](const TBreakPoint& bp) { return bp.iAddress == em_address; }; - auto it = std::find_if(m_BreakPoints.begin(), m_BreakPoints.end(), cond); + auto it = std::find_if(m_BreakPoints.begin(), m_BreakPoints.end(), cond); if (it != m_BreakPoints.end()) m_BreakPoints.erase(it); } -void BreakPoints::Clear() -{ - //if (jit) +void BreakPoints::Clear() { + // if (jit) //{ // std::for_each(m_BreakPoints.begin(), m_BreakPoints.end(), // [](const TBreakPoint& bp) diff --git a/src/common/break_points.h b/src/common/break_points.h index b0629df37..e15b9f842 100644 --- a/src/common/break_points.h +++ b/src/common/break_points.h @@ -4,28 +4,27 @@ #pragma once -#include <vector> #include <string> - +#include <vector> #include "common/common_types.h" class DebugInterface; -struct TBreakPoint -{ - u32 iAddress; +struct TBreakPoint { + u32 iAddress; bool bOn; bool bTemporary; }; // Code breakpoints. -class BreakPoints -{ +class BreakPoints { public: typedef std::vector<TBreakPoint> TBreakPoints; typedef std::vector<std::string> TBreakPointsStr; - const TBreakPoints& GetBreakPoints() { return m_BreakPoints; } + const TBreakPoints& GetBreakPoints() { + return m_BreakPoints; + } TBreakPointsStr GetStrings() const; void AddFromStrings(const TBreakPointsStr& bps); @@ -35,7 +34,7 @@ public: bool IsTempBreakPoint(u32 iAddress) const; // Add BreakPoint - void Add(u32 em_address, bool temp=false); + void Add(u32 em_address, bool temp = false); void Add(const TBreakPoint& bp); // Remove Breakpoint @@ -46,5 +45,5 @@ public: private: TBreakPoints m_BreakPoints; - u32 m_iBreakOnCount; + u32 m_iBreakOnCount; }; diff --git a/src/common/chunk_file.h b/src/common/chunk_file.h index 1e1bcff31..5145a3657 100644 --- a/src/common/chunk_file.h +++ b/src/common/chunk_file.h @@ -35,87 +35,90 @@ #include <type_traits> #include <utility> #include <vector> - #include "common/assert.h" #include "common/common_types.h" #include "common/logging/log.h" template <class T> -struct LinkedListItem : public T -{ - LinkedListItem<T> *next; +struct LinkedListItem : public T { + LinkedListItem<T>* next; }; class PointerWrap; -class PointerWrapSection -{ +class PointerWrapSection { public: - PointerWrapSection(PointerWrap &p, int ver, const char *title) : p_(p), ver_(ver), title_(title) { - } + PointerWrapSection(PointerWrap& p, int ver, const char* title) + : p_(p), ver_(ver), title_(title) {} ~PointerWrapSection(); - bool operator == (const int &v) const { return ver_ == v; } - bool operator != (const int &v) const { return ver_ != v; } - bool operator <= (const int &v) const { return ver_ <= v; } - bool operator >= (const int &v) const { return ver_ >= v; } - bool operator < (const int &v) const { return ver_ < v; } - bool operator > (const int &v) const { return ver_ > v; } + bool operator==(const int& v) const { + return ver_ == v; + } + bool operator!=(const int& v) const { + return ver_ != v; + } + bool operator<=(const int& v) const { + return ver_ <= v; + } + bool operator>=(const int& v) const { + return ver_ >= v; + } + bool operator<(const int& v) const { + return ver_ < v; + } + bool operator>(const int& v) const { + return ver_ > v; + } - operator bool() const { + operator bool() const { return ver_ > 0; } private: - PointerWrap &p_; + PointerWrap& p_; int ver_; - const char *title_; + const char* title_; }; // Wrapper class -class PointerWrap -{ - // This makes it a compile error if you forget to define DoState() on non-POD. - // Which also can be a problem, for example struct tm is non-POD on linux, for whatever reason... +class PointerWrap { +// This makes it a compile error if you forget to define DoState() on non-POD. +// Which also can be a problem, for example struct tm is non-POD on linux, for whatever reason... #ifdef _MSC_VER - template<typename T, bool isPOD = std::is_pod<T>::value, bool isPointer = std::is_pointer<T>::value> + template <typename T, bool isPOD = std::is_pod<T>::value, + bool isPointer = std::is_pointer<T>::value> #else - template<typename T, bool isPOD = __is_pod(T), bool isPointer = std::is_pointer<T>::value> + template <typename T, bool isPOD = __is_pod(T), bool isPointer = std::is_pointer<T>::value> #endif - struct DoHelper - { - static void DoArray(PointerWrap *p, T *x, int count) - { + struct DoHelper { + static void DoArray(PointerWrap* p, T* x, int count) { for (int i = 0; i < count; ++i) p->Do(x[i]); } - static void Do(PointerWrap *p, T &x) - { + static void Do(PointerWrap* p, T& x) { p->DoClass(x); } }; - template<typename T> - struct DoHelper<T, true, false> - { - static void DoArray(PointerWrap *p, T *x, int count) - { - p->DoVoid((void *)x, sizeof(T) * count); + template <typename T> + struct DoHelper<T, true, false> { + static void DoArray(PointerWrap* p, T* x, int count) { + p->DoVoid((void*)x, sizeof(T) * count); } - static void Do(PointerWrap *p, T &x) - { - p->DoVoid((void *)&x, sizeof(x)); + static void Do(PointerWrap* p, T& x) { + p->DoVoid((void*)&x, sizeof(x)); } }; public: enum Mode { MODE_READ = 1, // load - MODE_WRITE, // save - MODE_MEASURE, // calculate size - MODE_VERIFY, // compare + MODE_WRITE, // save + MODE_MEASURE, // calculate size + MODE_VERIFY, // compare }; enum Error { @@ -124,247 +127,237 @@ public: ERROR_FAILURE = 2, }; - u8 **ptr; + u8** ptr; Mode mode; Error error; public: - PointerWrap(u8 **ptr_, Mode mode_) : ptr(ptr_), mode(mode_), error(ERROR_NONE) {} - PointerWrap(unsigned char **ptr_, int mode_) : ptr((u8**)ptr_), mode((Mode)mode_), error(ERROR_NONE) {} + PointerWrap(u8** ptr_, Mode mode_) : ptr(ptr_), mode(mode_), error(ERROR_NONE) {} + PointerWrap(unsigned char** ptr_, int mode_) + : ptr((u8**)ptr_), mode((Mode)mode_), error(ERROR_NONE) {} - PointerWrapSection Section(const char *title, int ver) { + PointerWrapSection Section(const char* title, int ver) { return Section(title, ver, ver); } // The returned object can be compared against the version that was loaded. // This can be used to support versions as old as minVer. // Version = 0 means the section was not found. - PointerWrapSection Section(const char *title, int minVer, int ver) { + PointerWrapSection Section(const char* title, int minVer, int ver) { char marker[16] = {0}; int foundVersion = ver; strncpy(marker, title, sizeof(marker)); - if (!ExpectVoid(marker, sizeof(marker))) - { + if (!ExpectVoid(marker, sizeof(marker))) { // Might be before we added name markers for safety. if (foundVersion == 1 && ExpectVoid(&foundVersion, sizeof(foundVersion))) DoMarker(title); // Wasn't found, but maybe we can still load the state. else foundVersion = 0; - } - else + } else Do(foundVersion); if (error == ERROR_FAILURE || foundVersion < minVer || foundVersion > ver) { - LOG_ERROR(Common, "Savestate failure: wrong version %d found for %s", foundVersion, title); + LOG_ERROR(Common, "Savestate failure: wrong version %d found for %s", foundVersion, + title); SetError(ERROR_FAILURE); return PointerWrapSection(*this, -1, title); } return PointerWrapSection(*this, foundVersion, title); } - void SetMode(Mode mode_) {mode = mode_;} - Mode GetMode() const {return mode;} - u8 **GetPPtr() {return ptr;} - void SetError(Error error_) - { + void SetMode(Mode mode_) { + mode = mode_; + } + Mode GetMode() const { + return mode; + } + u8** GetPPtr() { + return ptr; + } + void SetError(Error error_) { if (error < error_) error = error_; if (error > ERROR_WARNING) mode = PointerWrap::MODE_MEASURE; } - bool ExpectVoid(void *data, int size) - { + bool ExpectVoid(void* data, int size) { switch (mode) { - case MODE_READ: if (memcmp(data, *ptr, size) != 0) return false; break; - case MODE_WRITE: memcpy(*ptr, data, size); break; - case MODE_MEASURE: break; // MODE_MEASURE - don't need to do anything + case MODE_READ: + if (memcmp(data, *ptr, size) != 0) + return false; + break; + case MODE_WRITE: + memcpy(*ptr, data, size); + break; + case MODE_MEASURE: + break; // MODE_MEASURE - don't need to do anything case MODE_VERIFY: for (int i = 0; i < size; i++) { - DEBUG_ASSERT_MSG(((u8*)data)[i] == (*ptr)[i], + DEBUG_ASSERT_MSG( + ((u8*)data)[i] == (*ptr)[i], "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", - ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], - (*ptr)[i], (*ptr)[i], &(*ptr)[i]); + ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], (*ptr)[i], (*ptr)[i], + &(*ptr)[i]); } break; - default: break; // throw an error? + default: + break; // throw an error? } (*ptr) += size; return true; } - void DoVoid(void *data, int size) - { + void DoVoid(void* data, int size) { switch (mode) { - case MODE_READ: memcpy(data, *ptr, size); break; - case MODE_WRITE: memcpy(*ptr, data, size); break; - case MODE_MEASURE: break; // MODE_MEASURE - don't need to do anything + case MODE_READ: + memcpy(data, *ptr, size); + break; + case MODE_WRITE: + memcpy(*ptr, data, size); + break; + case MODE_MEASURE: + break; // MODE_MEASURE - don't need to do anything case MODE_VERIFY: for (int i = 0; i < size; i++) { - DEBUG_ASSERT_MSG(((u8*)data)[i] == (*ptr)[i], + DEBUG_ASSERT_MSG( + ((u8*)data)[i] == (*ptr)[i], "Savestate verification failure: %d (0x%X) (at %p) != %d (0x%X) (at %p).\n", - ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], - (*ptr)[i], (*ptr)[i], &(*ptr)[i]); + ((u8*)data)[i], ((u8*)data)[i], &((u8*)data)[i], (*ptr)[i], (*ptr)[i], + &(*ptr)[i]); } break; - default: break; // throw an error? + default: + break; // throw an error? } (*ptr) += size; } - template<class K, class T> - void Do(std::map<K, T *> &x) - { - if (mode == MODE_READ) - { - for (auto it = x.begin(), end = x.end(); it != end; ++it) - { + template <class K, class T> + void Do(std::map<K, T*>& x) { + if (mode == MODE_READ) { + for (auto it = x.begin(), end = x.end(); it != end; ++it) { if (it->second != nullptr) delete it->second; } } - T *dv = nullptr; + T* dv = nullptr; DoMap(x, dv); } - template<class K, class T> - void Do(std::map<K, T> &x) - { + template <class K, class T> + void Do(std::map<K, T>& x) { T dv = T(); DoMap(x, dv); } - template<class K, class T> - void DoMap(std::map<K, T> &x, T &default_val) - { + template <class K, class T> + void DoMap(std::map<K, T>& x, T& default_val) { unsigned int number = (unsigned int)x.size(); Do(number); switch (mode) { - case MODE_READ: - { - x.clear(); - while (number > 0) - { - K first = K(); - Do(first); - T second = default_val; - Do(second); - x[first] = second; - --number; - } + case MODE_READ: { + x.clear(); + while (number > 0) { + K first = K(); + Do(first); + T second = default_val; + Do(second); + x[first] = second; + --number; } - break; + } break; case MODE_WRITE: case MODE_MEASURE: - case MODE_VERIFY: - { - typename std::map<K, T>::iterator itr = x.begin(); - while (number > 0) - { - K first = itr->first; - Do(first); - Do(itr->second); - --number; - ++itr; - } + case MODE_VERIFY: { + typename std::map<K, T>::iterator itr = x.begin(); + while (number > 0) { + K first = itr->first; + Do(first); + Do(itr->second); + --number; + ++itr; } - break; + } break; } } - template<class K, class T> - void Do(std::multimap<K, T *> &x) - { - if (mode == MODE_READ) - { - for (auto it = x.begin(), end = x.end(); it != end; ++it) - { + template <class K, class T> + void Do(std::multimap<K, T*>& x) { + if (mode == MODE_READ) { + for (auto it = x.begin(), end = x.end(); it != end; ++it) { if (it->second != nullptr) delete it->second; } } - T *dv = nullptr; + T* dv = nullptr; DoMultimap(x, dv); } - template<class K, class T> - void Do(std::multimap<K, T> &x) - { + template <class K, class T> + void Do(std::multimap<K, T>& x) { T dv = T(); DoMultimap(x, dv); } - template<class K, class T> - void DoMultimap(std::multimap<K, T> &x, T &default_val) - { + template <class K, class T> + void DoMultimap(std::multimap<K, T>& x, T& default_val) { unsigned int number = (unsigned int)x.size(); Do(number); switch (mode) { - case MODE_READ: - { - x.clear(); - while (number > 0) - { - K first = K(); - Do(first); - T second = default_val; - Do(second); - x.insert(std::make_pair(first, second)); - --number; - } + case MODE_READ: { + x.clear(); + while (number > 0) { + K first = K(); + Do(first); + T second = default_val; + Do(second); + x.insert(std::make_pair(first, second)); + --number; } - break; + } break; case MODE_WRITE: case MODE_MEASURE: - case MODE_VERIFY: - { - typename std::multimap<K, T>::iterator itr = x.begin(); - while (number > 0) - { - Do(itr->first); - Do(itr->second); - --number; - ++itr; - } + case MODE_VERIFY: { + typename std::multimap<K, T>::iterator itr = x.begin(); + while (number > 0) { + Do(itr->first); + Do(itr->second); + --number; + ++itr; } - break; + } break; } } // Store vectors. - template<class T> - void Do(std::vector<T *> &x) - { - T *dv = nullptr; + template <class T> + void Do(std::vector<T*>& x) { + T* dv = nullptr; DoVector(x, dv); } - template<class T> - void Do(std::vector<T> &x) - { + template <class T> + void Do(std::vector<T>& x) { T dv = T(); DoVector(x, dv); } - - template<class T> - void DoPOD(std::vector<T> &x) - { + template <class T> + void DoPOD(std::vector<T>& x) { T dv = T(); DoVectorPOD(x, dv); } - template<class T> - void Do(std::vector<T> &x, T &default_val) - { + template <class T> + void Do(std::vector<T>& x, T& default_val) { DoVector(x, default_val); } - template<class T> - void DoVector(std::vector<T> &x, T &default_val) - { + template <class T> + void DoVector(std::vector<T>& x, T& default_val) { u32 vec_size = (u32)x.size(); Do(vec_size); x.resize(vec_size, default_val); @@ -372,9 +365,8 @@ public: DoArray(&x[0], vec_size); } - template<class T> - void DoVectorPOD(std::vector<T> &x, T &default_val) - { + template <class T> + void DoVectorPOD(std::vector<T>& x, T& default_val) { u32 vec_size = (u32)x.size(); Do(vec_size); x.resize(vec_size, default_val); @@ -383,55 +375,48 @@ public: } // Store deques. - template<class T> - void Do(std::deque<T *> &x) - { - T *dv = nullptr; + template <class T> + void Do(std::deque<T*>& x) { + T* dv = nullptr; DoDeque(x, dv); } - template<class T> - void Do(std::deque<T> &x) - { + template <class T> + void Do(std::deque<T>& x) { T dv = T(); DoDeque(x, dv); } - template<class T> - void DoDeque(std::deque<T> &x, T &default_val) - { + template <class T> + void DoDeque(std::deque<T>& x, T& default_val) { u32 deq_size = (u32)x.size(); Do(deq_size); x.resize(deq_size, default_val); u32 i; - for(i = 0; i < deq_size; i++) + for (i = 0; i < deq_size; i++) Do(x[i]); } // Store STL lists. - template<class T> - void Do(std::list<T *> &x) - { - T *dv = nullptr; + template <class T> + void Do(std::list<T*>& x) { + T* dv = nullptr; Do(x, dv); } - template<class T> - void Do(std::list<T> &x) - { + template <class T> + void Do(std::list<T>& x) { T dv = T(); DoList(x, dv); } - template<class T> - void Do(std::list<T> &x, T &default_val) - { + template <class T> + void Do(std::list<T>& x, T& default_val) { DoList(x, default_val); } - template<class T> - void DoList(std::list<T> &x, T &default_val) - { + template <class T> + void DoList(std::list<T>& x, T& default_val) { u32 list_size = (u32)x.size(); Do(list_size); x.resize(list_size, default_val); @@ -441,15 +426,11 @@ public: Do(*itr); } - // Store STL sets. template <class T> - void Do(std::set<T *> &x) - { - if (mode == MODE_READ) - { - for (auto it = x.begin(), end = x.end(); it != end; ++it) - { + void Do(std::set<T*>& x) { + if (mode == MODE_READ) { + for (auto it = x.begin(), end = x.end(); it != end; ++it) { if (*it != nullptr) delete *it; } @@ -458,39 +439,31 @@ public: } template <class T> - void Do(std::set<T> &x) - { + void Do(std::set<T>& x) { DoSet(x); } template <class T> - void DoSet(std::set<T> &x) - { + void DoSet(std::set<T>& x) { unsigned int number = (unsigned int)x.size(); Do(number); - switch (mode) - { - case MODE_READ: - { - x.clear(); - while (number-- > 0) - { - T it = T(); - Do(it); - x.insert(it); - } + switch (mode) { + case MODE_READ: { + x.clear(); + while (number-- > 0) { + T it = T(); + Do(it); + x.insert(it); } - break; + } break; case MODE_WRITE: case MODE_MEASURE: - case MODE_VERIFY: - { - typename std::set<T>::iterator itr = x.begin(); - while (number-- > 0) - Do(*itr++); - } - break; + case MODE_VERIFY: { + typename std::set<T>::iterator itr = x.begin(); + while (number-- > 0) + Do(*itr++); + } break; default: LOG_ERROR(Common, "Savestate error: invalid mode %d.", mode); @@ -498,51 +471,58 @@ public: } // Store strings. - void Do(std::string &x) - { + void Do(std::string& x) { int stringLen = (int)x.length() + 1; Do(stringLen); switch (mode) { - case MODE_READ: x = (char*)*ptr; break; - case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; - case MODE_MEASURE: break; + case MODE_READ: + x = (char*)*ptr; + break; + case MODE_WRITE: + memcpy(*ptr, x.c_str(), stringLen); + break; + case MODE_MEASURE: + break; case MODE_VERIFY: DEBUG_ASSERT_MSG((x == (char*)*ptr), - "Savestate verification failure: \"%s\" != \"%s\" (at %p).\n", - x.c_str(), (char*)*ptr, ptr); + "Savestate verification failure: \"%s\" != \"%s\" (at %p).\n", + x.c_str(), (char*)*ptr, ptr); break; } (*ptr) += stringLen; } - void Do(std::wstring &x) - { - int stringLen = sizeof(wchar_t)*((int)x.length() + 1); + void Do(std::wstring& x) { + int stringLen = sizeof(wchar_t) * ((int)x.length() + 1); Do(stringLen); switch (mode) { - case MODE_READ: x = (wchar_t*)*ptr; break; - case MODE_WRITE: memcpy(*ptr, x.c_str(), stringLen); break; - case MODE_MEASURE: break; + case MODE_READ: + x = (wchar_t*)*ptr; + break; + case MODE_WRITE: + memcpy(*ptr, x.c_str(), stringLen); + break; + case MODE_MEASURE: + break; case MODE_VERIFY: DEBUG_ASSERT_MSG((x == (wchar_t*)*ptr), - "Savestate verification failure: \"%ls\" != \"%ls\" (at %p).\n", - x.c_str(), (wchar_t*)*ptr, ptr); + "Savestate verification failure: \"%ls\" != \"%ls\" (at %p).\n", + x.c_str(), (wchar_t*)*ptr, ptr); break; } (*ptr) += stringLen; } - template<class T> - void DoClass(T &x) { + template <class T> + void DoClass(T& x) { x.DoState(*this); } - template<class T> - void DoClass(T *&x) { - if (mode == MODE_READ) - { + template <class T> + void DoClass(T*& x) { + if (mode == MODE_READ) { if (x != nullptr) delete x; x = new T(); @@ -550,81 +530,70 @@ public: x->DoState(*this); } - template<class T> - void DoArray(T *x, int count) { + template <class T> + void DoArray(T* x, int count) { DoHelper<T>::DoArray(this, x, count); } - template<class T> - void Do(T &x) { + template <class T> + void Do(T& x) { DoHelper<T>::Do(this, x); } - template<class T> - void DoPOD(T &x) { + template <class T> + void DoPOD(T& x) { DoHelper<T>::Do(this, x); } - template<class T> - void DoPointer(T* &x, T*const base) { - // pointers can be more than 2^31 apart, but you're using this function wrong if you need that much range + template <class T> + void DoPointer(T*& x, T* const base) { + // pointers can be more than 2^31 apart, but you're using this function wrong if you need + // that much range s32 offset = x - base; Do(offset); if (mode == MODE_READ) x = base + offset; } - template<class T, LinkedListItem<T>* (*TNew)(), void (*TFree)(LinkedListItem<T>*), void (*TDo)(PointerWrap&, T*)> - void DoLinkedList(LinkedListItem<T>*& list_start, LinkedListItem<T>** list_end = nullptr) - { + template <class T, LinkedListItem<T>* (*TNew)(), void (*TFree)(LinkedListItem<T>*), + void (*TDo)(PointerWrap&, T*)> + void DoLinkedList(LinkedListItem<T>*& list_start, LinkedListItem<T>** list_end = nullptr) { LinkedListItem<T>* list_cur = list_start; LinkedListItem<T>* prev = nullptr; - while (true) - { + while (true) { u8 shouldExist = (list_cur ? 1 : 0); Do(shouldExist); - if (shouldExist == 1) - { + if (shouldExist == 1) { LinkedListItem<T>* cur = list_cur ? list_cur : TNew(); TDo(*this, (T*)cur); - if (!list_cur) - { - if (mode == MODE_READ) - { + if (!list_cur) { + if (mode == MODE_READ) { cur->next = nullptr; list_cur = cur; if (prev) prev->next = cur; else list_start = cur; - } - else - { + } else { TFree(cur); continue; } } - } - else - { - if (mode == MODE_READ) - { + } else { + if (mode == MODE_READ) { if (prev) prev->next = nullptr; if (list_end) *list_end = prev; - if (list_cur) - { + if (list_cur) { if (list_start == list_cur) list_start = nullptr; - do - { + do { LinkedListItem<T>* next = list_cur->next; TFree(list_cur); list_cur = next; - } - while (list_cur); + } while (list_cur); } } break; @@ -634,13 +603,13 @@ public: } } - void DoMarker(const char* prevName, u32 arbitraryNumber=0x42) - { + void DoMarker(const char* prevName, u32 arbitraryNumber = 0x42) { u32 cookie = arbitraryNumber; Do(cookie); - if(mode == PointerWrap::MODE_READ && cookie != arbitraryNumber) - { - LOG_ERROR(Common, "After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). Aborting savestate load...", prevName, cookie, cookie, arbitraryNumber, arbitraryNumber); + if (mode == PointerWrap::MODE_READ && cookie != arbitraryNumber) { + LOG_ERROR(Common, "After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). " + "Aborting savestate load...", + prevName, cookie, cookie, arbitraryNumber, arbitraryNumber); SetError(ERROR_FAILURE); } } diff --git a/src/common/code_block.h b/src/common/code_block.h index 2fa4a0090..6a55a8e30 100644 --- a/src/common/code_block.h +++ b/src/common/code_block.h @@ -5,7 +5,6 @@ #pragma once #include <cstddef> - #include "common/common_types.h" #include "common/memory_util.h" @@ -14,24 +13,27 @@ // having to prefix them with gen-> or something similar. // Example implementation: // class JIT : public CodeBlock<ARMXEmitter> {} -template<class T> class CodeBlock : public T, NonCopyable -{ +template <class T> +class CodeBlock : public T, NonCopyable { private: // A privately used function to set the executable RAM space to something invalid. - // For debugging usefulness it should be used to set the RAM to a host specific breakpoint instruction + // For debugging usefulness it should be used to set the RAM to a host specific breakpoint + // instruction virtual void PoisonMemory() = 0; protected: - u8 *region; + u8* region; size_t region_size; public: CodeBlock() : region(nullptr), region_size(0) {} - virtual ~CodeBlock() { if (region) FreeCodeSpace(); } + virtual ~CodeBlock() { + if (region) + FreeCodeSpace(); + } // Call this before you generate any code. - void AllocCodeSpace(int size) - { + void AllocCodeSpace(int size) { region_size = size; region = (u8*)AllocateExecutableMemory(region_size); T::SetCodePtr(region); @@ -39,15 +41,13 @@ public: // Always clear code space with breakpoints, so that if someone accidentally executes // uninitialized, it just breaks into the debugger. - void ClearCodeSpace() - { + void ClearCodeSpace() { PoisonMemory(); ResetCodePtr(); } // Call this when shutting down. Don't rely on the destructor, even though it'll do the job. - void FreeCodeSpace() - { + void FreeCodeSpace() { #ifdef __SYMBIAN32__ ResetExecutableMemory(region); #else @@ -57,33 +57,29 @@ public: region_size = 0; } - bool IsInSpace(const u8 *ptr) - { + bool IsInSpace(const u8* ptr) { return (ptr >= region) && (ptr < (region + region_size)); } // Cannot currently be undone. Will write protect the entire code region. // Start over if you need to change the code (call FreeCodeSpace(), AllocCodeSpace()). - void WriteProtect() - { + void WriteProtect() { WriteProtectMemory(region, region_size, true); } - void ResetCodePtr() - { + void ResetCodePtr() { T::SetCodePtr(region); } - size_t GetSpaceLeft() const - { + size_t GetSpaceLeft() const { return region_size - (T::GetCodePtr() - region); } - u8 *GetBasePtr() { + u8* GetBasePtr() { return region; } - size_t GetOffset(const u8 *ptr) const { + size_t GetOffset(const u8* ptr) const { return ptr - region; } }; diff --git a/src/common/color.h b/src/common/color.h index 908879ea6..4ebd4f3d0 100644 --- a/src/common/color.h +++ b/src/common/color.h @@ -56,7 +56,7 @@ constexpr u8 Convert8To6(u8 value) { * @return Result color decoded as Math::Vec4<u8> */ inline const Math::Vec4<u8> DecodeRGBA8(const u8* bytes) { - return { bytes[3], bytes[2], bytes[1], bytes[0] }; + return {bytes[3], bytes[2], bytes[1], bytes[0]}; } /** @@ -65,7 +65,7 @@ inline const Math::Vec4<u8> DecodeRGBA8(const u8* bytes) { * @return Result color decoded as Math::Vec4<u8> */ inline const Math::Vec4<u8> DecodeRGB8(const u8* bytes) { - return { bytes[2], bytes[1], bytes[0], 255 }; + return {bytes[2], bytes[1], bytes[0], 255}; } /** @@ -74,7 +74,7 @@ inline const Math::Vec4<u8> DecodeRGB8(const u8* bytes) { * @return Result color decoded as Math::Vec4<u8> */ inline const Math::Vec4<u8> DecodeRG8(const u8* bytes) { - return { bytes[1], bytes[0], 0, 255 }; + return {bytes[1], bytes[0], 0, 255}; } /** @@ -84,8 +84,8 @@ inline const Math::Vec4<u8> DecodeRG8(const u8* bytes) { */ inline const Math::Vec4<u8> DecodeRGB565(const u8* bytes) { const u16_le pixel = *reinterpret_cast<const u16_le*>(bytes); - return { Convert5To8((pixel >> 11) & 0x1F), Convert6To8((pixel >> 5) & 0x3F), - Convert5To8(pixel & 0x1F), 255 }; + return {Convert5To8((pixel >> 11) & 0x1F), Convert6To8((pixel >> 5) & 0x3F), + Convert5To8(pixel & 0x1F), 255}; } /** @@ -95,8 +95,8 @@ inline const Math::Vec4<u8> DecodeRGB565(const u8* bytes) { */ inline const Math::Vec4<u8> DecodeRGB5A1(const u8* bytes) { const u16_le pixel = *reinterpret_cast<const u16_le*>(bytes); - return { Convert5To8((pixel >> 11) & 0x1F), Convert5To8((pixel >> 6) & 0x1F), - Convert5To8((pixel >> 1) & 0x1F), Convert1To8(pixel & 0x1) }; + return {Convert5To8((pixel >> 11) & 0x1F), Convert5To8((pixel >> 6) & 0x1F), + Convert5To8((pixel >> 1) & 0x1F), Convert1To8(pixel & 0x1)}; } /** @@ -106,8 +106,8 @@ inline const Math::Vec4<u8> DecodeRGB5A1(const u8* bytes) { */ inline const Math::Vec4<u8> DecodeRGBA4(const u8* bytes) { const u16_le pixel = *reinterpret_cast<const u16_le*>(bytes); - return { Convert4To8((pixel >> 12) & 0xF), Convert4To8((pixel >> 8) & 0xF), - Convert4To8((pixel >> 4) & 0xF), Convert4To8(pixel & 0xF) }; + return {Convert4To8((pixel >> 12) & 0xF), Convert4To8((pixel >> 8) & 0xF), + Convert4To8((pixel >> 4) & 0xF), Convert4To8(pixel & 0xF)}; } /** @@ -134,7 +134,7 @@ inline u32 DecodeD24(const u8* bytes) { * @return Resulting values stored as a Math::Vec2 */ inline const Math::Vec2<u32> DecodeD24S8(const u8* bytes) { - return { static_cast<u32>((bytes[2] << 16) | (bytes[1] << 8) | bytes[0]), bytes[3] }; + return {static_cast<u32>((bytes[2] << 16) | (bytes[1] << 8) | bytes[0]), bytes[3]}; } /** @@ -175,8 +175,8 @@ inline void EncodeRG8(const Math::Vec4<u8>& color, u8* bytes) { * @param bytes Destination pointer to store encoded color */ inline void EncodeRGB565(const Math::Vec4<u8>& color, u8* bytes) { - *reinterpret_cast<u16_le*>(bytes) = (Convert8To5(color.r()) << 11) | - (Convert8To6(color.g()) << 5) | Convert8To5(color.b()); + *reinterpret_cast<u16_le*>(bytes) = + (Convert8To5(color.r()) << 11) | (Convert8To6(color.g()) << 5) | Convert8To5(color.b()); } /** @@ -186,7 +186,8 @@ inline void EncodeRGB565(const Math::Vec4<u8>& color, u8* bytes) { */ inline void EncodeRGB5A1(const Math::Vec4<u8>& color, u8* bytes) { *reinterpret_cast<u16_le*>(bytes) = (Convert8To5(color.r()) << 11) | - (Convert8To5(color.g()) << 6) | (Convert8To5(color.b()) << 1) | Convert8To1(color.a()); + (Convert8To5(color.g()) << 6) | + (Convert8To5(color.b()) << 1) | Convert8To1(color.a()); } /** @@ -196,7 +197,8 @@ inline void EncodeRGB5A1(const Math::Vec4<u8>& color, u8* bytes) { */ inline void EncodeRGBA4(const Math::Vec4<u8>& color, u8* bytes) { *reinterpret_cast<u16_le*>(bytes) = (Convert8To4(color.r()) << 12) | - (Convert8To4(color.g()) << 8) | (Convert8To4(color.b()) << 4) | Convert8To4(color.a()); + (Convert8To4(color.g()) << 8) | + (Convert8To4(color.b()) << 4) | Convert8To4(color.a()); } /** diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h index 4633897ce..b141e79ed 100644 --- a/src/common/common_funcs.h +++ b/src/common/common_funcs.h @@ -7,14 +7,13 @@ #if !defined(ARCHITECTURE_x86_64) && !defined(_M_ARM) #include <cstdlib> // for exit #endif - #include "common_types.h" #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) /// Textually concatenates two tokens. The double-expansion is required by the C preprocessor. #define CONCAT2(x, y) DO_CONCAT2(x, y) -#define DO_CONCAT2(x, y) x ## y +#define DO_CONCAT2(x, y) x##y // helper macro to properly align structure members. // Calling INSERT_PADDING_BYTES will add a new member variable with a name like "pad121", @@ -24,9 +23,9 @@ // Inlining #ifdef _WIN32 - #define FORCE_INLINE __forceinline +#define FORCE_INLINE __forceinline #else - #define FORCE_INLINE inline __attribute__((always_inline)) +#define FORCE_INLINE inline __attribute__((always_inline)) #endif #ifndef _MSC_VER @@ -46,7 +45,8 @@ #else inline u32 rotl(u32 x, int shift) { shift &= 31; - if (!shift) return x; + if (!shift) + return x; return (x << shift) | (x >> (32 - shift)); } #endif @@ -56,17 +56,18 @@ inline u32 rotl(u32 x, int shift) { #else inline u32 rotr(u32 x, int shift) { shift &= 31; - if (!shift) return x; + if (!shift) + return x; return (x >> shift) | (x << (32 - shift)); } #endif -inline u64 _rotl64(u64 x, unsigned int shift){ +inline u64 _rotl64(u64 x, unsigned int shift) { unsigned int n = shift % 64; return (x << n) | (x >> (64 - n)); } -inline u64 _rotr64(u64 x, unsigned int shift){ +inline u64 _rotr64(u64 x, unsigned int shift) { unsigned int n = shift % 64; return (x >> n) | (x << (64 - n)); } @@ -74,17 +75,17 @@ inline u64 _rotr64(u64 x, unsigned int shift){ #else // _MSC_VER #if (_MSC_VER < 1900) - // Function Cross-Compatibility - #define snprintf _snprintf +// Function Cross-Compatibility +#define snprintf _snprintf #endif // Locale Cross-Compatibility #define locale_t _locale_t extern "C" { - __declspec(dllimport) void __stdcall DebugBreak(void); +__declspec(dllimport) void __stdcall DebugBreak(void); } -#define Crash() {DebugBreak();} +#define Crash() DebugBreak() // cstdlib provides these on MSVC #define rotr _rotr diff --git a/src/common/common_paths.h b/src/common/common_paths.h index 2903f2cf2..a5342a610 100644 --- a/src/common/common_paths.h +++ b/src/common/common_paths.h @@ -16,13 +16,13 @@ #define ROOT_DIR "." #define USERDATA_DIR "user" #ifdef USER_DIR - #define EMU_DATA_DIR USER_DIR +#define EMU_DATA_DIR USER_DIR #else - #ifdef _WIN32 - #define EMU_DATA_DIR "Citra Emulator" - #else - #define EMU_DATA_DIR "citra-emu" - #endif +#ifdef _WIN32 +#define EMU_DATA_DIR "Citra Emulator" +#else +#define EMU_DATA_DIR "citra-emu" +#endif #endif // Dirs in both User and Sys @@ -31,32 +31,32 @@ #define JAP_DIR "JAP" // Subdirs in the User dir returned by GetUserPath(D_USER_IDX) -#define CONFIG_DIR "config" -#define GAMECONFIG_DIR "game_config" -#define MAPS_DIR "maps" -#define CACHE_DIR "cache" -#define SDMC_DIR "sdmc" -#define NAND_DIR "nand" -#define SYSDATA_DIR "sysdata" -#define SHADERCACHE_DIR "shader_cache" -#define STATESAVES_DIR "state_saves" -#define SCREENSHOTS_DIR "screenShots" -#define DUMP_DIR "dump" -#define DUMP_TEXTURES_DIR "textures" -#define DUMP_FRAMES_DIR "frames" -#define DUMP_AUDIO_DIR "audio" -#define LOGS_DIR "logs" -#define SHADERS_DIR "shaders" -#define SYSCONF_DIR "sysconf" +#define CONFIG_DIR "config" +#define GAMECONFIG_DIR "game_config" +#define MAPS_DIR "maps" +#define CACHE_DIR "cache" +#define SDMC_DIR "sdmc" +#define NAND_DIR "nand" +#define SYSDATA_DIR "sysdata" +#define SHADERCACHE_DIR "shader_cache" +#define STATESAVES_DIR "state_saves" +#define SCREENSHOTS_DIR "screenShots" +#define DUMP_DIR "dump" +#define DUMP_TEXTURES_DIR "textures" +#define DUMP_FRAMES_DIR "frames" +#define DUMP_AUDIO_DIR "audio" +#define LOGS_DIR "logs" +#define SHADERS_DIR "shaders" +#define SYSCONF_DIR "sysconf" // Filenames // Files in the directory returned by GetUserPath(D_CONFIG_IDX) -#define EMU_CONFIG "emu.ini" -#define DEBUGGER_CONFIG "debugger.ini" -#define LOGGER_CONFIG "logger.ini" +#define EMU_CONFIG "emu.ini" +#define DEBUGGER_CONFIG "debugger.ini" +#define LOGGER_CONFIG "logger.ini" // Sys files -#define SHARED_FONT "shared_font.bin" +#define SHARED_FONT "shared_font.bin" // Files in the directory returned by GetUserPath(D_LOGS_IDX) #define MAIN_LOG "emu.log" diff --git a/src/common/common_types.h b/src/common/common_types.h index 9f51dff18..ee18eac81 100644 --- a/src/common/common_types.h +++ b/src/common/common_types.h @@ -32,18 +32,18 @@ #endif #endif -typedef std::uint8_t u8; ///< 8-bit unsigned byte +typedef std::uint8_t u8; ///< 8-bit unsigned byte typedef std::uint16_t u16; ///< 16-bit unsigned short typedef std::uint32_t u32; ///< 32-bit unsigned word typedef std::uint64_t u64; ///< 64-bit unsigned int -typedef std::int8_t s8; ///< 8-bit signed byte +typedef std::int8_t s8; ///< 8-bit signed byte typedef std::int16_t s16; ///< 16-bit signed short typedef std::int32_t s32; ///< 32-bit signed word typedef std::int64_t s64; ///< 64-bit signed int -typedef float f32; ///< 32-bit floating point -typedef double f64; ///< 64-bit floating point +typedef float f32; ///< 32-bit floating point +typedef double f64; ///< 64-bit floating point // TODO: It would be nice to eventually replace these with strong types that prevent accidental // conversion between each other. diff --git a/src/common/emu_window.cpp b/src/common/emu_window.cpp index fd728c109..122f1c212 100644 --- a/src/common/emu_window.cpp +++ b/src/common/emu_window.cpp @@ -4,10 +4,8 @@ #include <algorithm> #include <cmath> - #include "common/assert.h" #include "common/key_map.h" - #include "emu_window.h" #include "video_core/video_core.h" @@ -44,18 +42,17 @@ void EmuWindow::CirclePadUpdated(float x, float y) { */ static bool IsWithinTouchscreen(const EmuWindow::FramebufferLayout& layout, unsigned framebuffer_x, unsigned framebuffer_y) { - return (framebuffer_y >= layout.bottom_screen.top && - framebuffer_y < layout.bottom_screen.bottom && - framebuffer_x >= layout.bottom_screen.left && - framebuffer_x < layout.bottom_screen.right); + return ( + framebuffer_y >= layout.bottom_screen.top && framebuffer_y < layout.bottom_screen.bottom && + framebuffer_x >= layout.bottom_screen.left && framebuffer_x < layout.bottom_screen.right); } -std::tuple<unsigned,unsigned> EmuWindow::ClipToTouchScreen(unsigned new_x, unsigned new_y) { +std::tuple<unsigned, unsigned> EmuWindow::ClipToTouchScreen(unsigned new_x, unsigned new_y) { new_x = std::max(new_x, framebuffer_layout.bottom_screen.left); - new_x = std::min(new_x, framebuffer_layout.bottom_screen.right-1); + new_x = std::min(new_x, framebuffer_layout.bottom_screen.right - 1); new_y = std::max(new_y, framebuffer_layout.bottom_screen.top); - new_y = std::min(new_y, framebuffer_layout.bottom_screen.bottom-1); + new_y = std::min(new_y, framebuffer_layout.bottom_screen.bottom - 1); return std::make_tuple(new_x, new_y); } @@ -64,10 +61,12 @@ void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) return; - touch_x = VideoCore::kScreenBottomWidth * (framebuffer_x - framebuffer_layout.bottom_screen.left) / - (framebuffer_layout.bottom_screen.right - framebuffer_layout.bottom_screen.left); - touch_y = VideoCore::kScreenBottomHeight * (framebuffer_y - framebuffer_layout.bottom_screen.top) / - (framebuffer_layout.bottom_screen.bottom - framebuffer_layout.bottom_screen.top); + touch_x = VideoCore::kScreenBottomWidth * + (framebuffer_x - framebuffer_layout.bottom_screen.left) / + (framebuffer_layout.bottom_screen.right - framebuffer_layout.bottom_screen.left); + touch_y = VideoCore::kScreenBottomHeight * + (framebuffer_y - framebuffer_layout.bottom_screen.top) / + (framebuffer_layout.bottom_screen.bottom - framebuffer_layout.bottom_screen.top); touch_pressed = true; pad_state.touch.Assign(1); @@ -90,16 +89,19 @@ void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) { TouchPressed(framebuffer_x, framebuffer_y); } -EmuWindow::FramebufferLayout EmuWindow::FramebufferLayout::DefaultScreenLayout(unsigned width, unsigned height) { +EmuWindow::FramebufferLayout EmuWindow::FramebufferLayout::DefaultScreenLayout(unsigned width, + unsigned height) { // When hiding the widget, the function receives a size of 0 - if (width == 0) width = 1; - if (height == 0) height = 1; + if (width == 0) + width = 1; + if (height == 0) + height = 1; - EmuWindow::FramebufferLayout res = { width, height, {}, {} }; + EmuWindow::FramebufferLayout res = {width, height, {}, {}}; float window_aspect_ratio = static_cast<float>(height) / width; - float emulation_aspect_ratio = static_cast<float>(VideoCore::kScreenTopHeight * 2) / - VideoCore::kScreenTopWidth; + float emulation_aspect_ratio = + static_cast<float>(VideoCore::kScreenTopHeight * 2) / VideoCore::kScreenTopWidth; if (window_aspect_ratio > emulation_aspect_ratio) { // Window is narrower than the emulation content => apply borders to the top and bottom @@ -110,8 +112,9 @@ EmuWindow::FramebufferLayout EmuWindow::FramebufferLayout::DefaultScreenLayout(u res.top_screen.top = (height - viewport_height) / 2; res.top_screen.bottom = res.top_screen.top + viewport_height / 2; - int bottom_width = static_cast<int>((static_cast<float>(VideoCore::kScreenBottomWidth) / - VideoCore::kScreenTopWidth) * (res.top_screen.right - res.top_screen.left)); + int bottom_width = static_cast<int>( + (static_cast<float>(VideoCore::kScreenBottomWidth) / VideoCore::kScreenTopWidth) * + (res.top_screen.right - res.top_screen.left)); int bottom_border = ((res.top_screen.right - res.top_screen.left) - bottom_width) / 2; res.bottom_screen.left = bottom_border; @@ -127,8 +130,9 @@ EmuWindow::FramebufferLayout EmuWindow::FramebufferLayout::DefaultScreenLayout(u res.top_screen.top = 0; res.top_screen.bottom = res.top_screen.top + height / 2; - int bottom_width = static_cast<int>((static_cast<float>(VideoCore::kScreenBottomWidth) / - VideoCore::kScreenTopWidth) * (res.top_screen.right - res.top_screen.left)); + int bottom_width = static_cast<int>( + (static_cast<float>(VideoCore::kScreenBottomWidth) / VideoCore::kScreenTopWidth) * + (res.top_screen.right - res.top_screen.left)); int bottom_border = ((res.top_screen.right - res.top_screen.left) - bottom_width) / 2; res.bottom_screen.left = res.top_screen.left + bottom_border; diff --git a/src/common/emu_window.h b/src/common/emu_window.h index 57e303b6d..67df63e06 100644 --- a/src/common/emu_window.h +++ b/src/common/emu_window.h @@ -6,10 +6,8 @@ #include <tuple> #include <utility> - #include "common/common_types.h" #include "common/math_util.h" - #include "core/hle/service/hid/hid.h" /** @@ -30,15 +28,14 @@ * - DO NOT TREAT THIS CLASS AS A GUI TOOLKIT ABSTRACTION LAYER. That's not what it is. Please * re-read the upper points again and think about it if you don't see this. */ -class EmuWindow -{ +class EmuWindow { public: /// Data structure to store emuwindow configuration struct WindowConfig { - bool fullscreen; - int res_width; - int res_height; - std::pair<unsigned,unsigned> min_client_area_size; + bool fullscreen; + int res_width; + int res_height; + std::pair<unsigned, unsigned> min_client_area_size; }; /// Describes the layout of the window framebuffer (size and top/bottom screen positions) @@ -193,15 +190,18 @@ public: /** * Returns currently active configuration. - * @note Accesses to the returned object need not be consistent because it may be modified in another thread + * @note Accesses to the returned object need not be consistent because it may be modified in + * another thread */ const WindowConfig& GetActiveConfig() const { return active_config; } /** - * Requests the internal configuration to be replaced by the specified argument at some point in the future. - * @note This method is thread-safe, because it delays configuration changes to the GUI event loop. Hence there is no guarantee on when the requested configuration will be active. + * Requests the internal configuration to be replaced by the specified argument at some point in + * the future. + * @note This method is thread-safe, because it delays configuration changes to the GUI event + * loop. Hence there is no guarantee on when the requested configuration will be active. */ void SetConfig(const WindowConfig& val) { config = val; @@ -258,7 +258,7 @@ protected: * Update internal client area size with the given parameter. * @note EmuWindow implementations will usually use this in window resize event handlers. */ - void NotifyClientAreaSizeChanged(const std::pair<unsigned,unsigned>& size) { + void NotifyClientAreaSizeChanged(const std::pair<unsigned, unsigned>& size) { client_area_width = size.first; client_area_height = size.second; } @@ -266,32 +266,35 @@ protected: private: /** * Handler called when the minimal client area was requested to be changed via SetConfig. - * For the request to be honored, EmuWindow implementations will usually reimplement this function. + * For the request to be honored, EmuWindow implementations will usually reimplement this + * function. */ - virtual void OnMinimalClientAreaChangeRequest(const std::pair<unsigned,unsigned>& minimal_size) { + virtual void OnMinimalClientAreaChangeRequest( + const std::pair<unsigned, unsigned>& minimal_size) { // By default, ignore this request and do nothing. } FramebufferLayout framebuffer_layout; ///< Current framebuffer layout - unsigned client_area_width; ///< Current client width, should be set by window impl. - unsigned client_area_height; ///< Current client height, should be set by window impl. + unsigned client_area_width; ///< Current client width, should be set by window impl. + unsigned client_area_height; ///< Current client height, should be set by window impl. - WindowConfig config; ///< Internal configuration (changes pending for being applied in ProcessConfigurationChanges) - WindowConfig active_config; ///< Internal active configuration + WindowConfig config; ///< Internal configuration (changes pending for being applied in + /// ProcessConfigurationChanges) + WindowConfig active_config; ///< Internal active configuration - bool touch_pressed; ///< True if touchpad area is currently pressed, otherwise false + bool touch_pressed; ///< True if touchpad area is currently pressed, otherwise false - u16 touch_x; ///< Touchpad X-position in native 3DS pixel coordinates (0-320) - u16 touch_y; ///< Touchpad Y-position in native 3DS pixel coordinates (0-240) + u16 touch_x; ///< Touchpad X-position in native 3DS pixel coordinates (0-320) + u16 touch_y; ///< Touchpad Y-position in native 3DS pixel coordinates (0-240) s16 circle_pad_x; ///< Circle pad X-position in native 3DS pixel coordinates (-156 - 156) s16 circle_pad_y; ///< Circle pad Y-position in native 3DS pixel coordinates (-156 - 156) - /** - * Clip the provided coordinates to be inside the touchscreen area. - */ - std::tuple<unsigned,unsigned> ClipToTouchScreen(unsigned new_x, unsigned new_y); + /** + * Clip the provided coordinates to be inside the touchscreen area. + */ + std::tuple<unsigned, unsigned> ClipToTouchScreen(unsigned new_x, unsigned new_y); Service::HID::PadState pad_state; }; diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index bc83ab737..14cbcac6b 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -9,66 +9,63 @@ #include "common/logging/log.h" #ifdef _WIN32 - #include <windows.h> - #include <shlobj.h> // for SHGetFolderPath - #include <shellapi.h> - #include <commdlg.h> // for GetSaveFileName - #include <io.h> - #include <direct.h> // getcwd - #include <tchar.h> - - #include "common/string_util.h" - - // 64 bit offsets for windows - #define fseeko _fseeki64 - #define ftello _ftelli64 - #define atoll _atoi64 - #define stat64 _stat64 - #define fstat64 _fstat64 - #define fileno _fileno +#include <windows.h> +// windows.h needs to be included before other windows headers +#include <commdlg.h> // for GetSaveFileName +#include <direct.h> // getcwd +#include <io.h> +#include <shellapi.h> +#include <shlobj.h> // for SHGetFolderPath +#include <tchar.h> +#include "common/string_util.h" + +// 64 bit offsets for windows +#define fseeko _fseeki64 +#define ftello _ftelli64 +#define atoll _atoi64 +#define stat64 _stat64 +#define fstat64 _fstat64 +#define fileno _fileno #else - #ifdef __APPLE__ - #include <sys/param.h> - #endif - #include <cctype> - #include <cerrno> - #include <cstdlib> - #include <cstring> - #include <dirent.h> - #include <pwd.h> - #include <unistd.h> +#ifdef __APPLE__ +#include <sys/param.h> +#endif +#include <cctype> +#include <cerrno> +#include <cstdlib> +#include <cstring> +#include <dirent.h> +#include <pwd.h> +#include <unistd.h> #endif #if defined(__APPLE__) - #include <CoreFoundation/CFString.h> - #include <CoreFoundation/CFURL.h> - #include <CoreFoundation/CFBundle.h> +#include <CoreFoundation/CFBundle.h> +#include <CoreFoundation/CFString.h> +#include <CoreFoundation/CFURL.h> #endif #include <algorithm> #include <sys/stat.h> #ifndef S_ISDIR - #define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) +#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) #endif #ifdef BSD4_4 - #define stat64 stat - #define fstat64 fstat +#define stat64 stat +#define fstat64 fstat #endif // This namespace has various generic functions related to files and paths. // The code still needs a ton of cleanup. // REMEMBER: strdup considered harmful! -namespace FileUtil -{ +namespace FileUtil { // Remove any ending forward slashes from directory paths // Modifies argument. -static void StripTailDirSlashes(std::string &fname) -{ - if (fname.length() > 1) - { +static void StripTailDirSlashes(std::string& fname) { + if (fname.length() > 1) { size_t i = fname.length(); while (i > 0 && fname[i - 1] == DIR_SEP_CHR) --i; @@ -78,8 +75,7 @@ static void StripTailDirSlashes(std::string &fname) } // Returns true if file filename exists -bool Exists(const std::string &filename) -{ +bool Exists(const std::string& filename) { struct stat64 file_info; std::string copy(filename); @@ -99,8 +95,7 @@ bool Exists(const std::string &filename) } // Returns true if filename is a directory -bool IsDirectory(const std::string &filename) -{ +bool IsDirectory(const std::string& filename) { struct stat64 file_info; std::string copy(filename); @@ -117,8 +112,8 @@ bool IsDirectory(const std::string &filename) #endif if (result < 0) { - LOG_WARNING(Common_Filesystem, "stat failed on %s: %s", - filename.c_str(), GetLastErrorMsg()); + LOG_WARNING(Common_Filesystem, "stat failed on %s: %s", filename.c_str(), + GetLastErrorMsg()); return false; } @@ -127,36 +122,32 @@ bool IsDirectory(const std::string &filename) // Deletes a given filename, return true on success // Doesn't supports deleting a directory -bool Delete(const std::string &filename) -{ +bool Delete(const std::string& filename) { LOG_INFO(Common_Filesystem, "file %s", filename.c_str()); // Return true because we care about the file no // being there, not the actual delete. - if (!Exists(filename)) - { + if (!Exists(filename)) { LOG_WARNING(Common_Filesystem, "%s does not exist", filename.c_str()); return true; } // We can't delete a directory - if (IsDirectory(filename)) - { + if (IsDirectory(filename)) { LOG_ERROR(Common_Filesystem, "Failed: %s is a directory", filename.c_str()); return false; } #ifdef _WIN32 - if (!DeleteFileW(Common::UTF8ToUTF16W(filename).c_str())) - { - LOG_ERROR(Common_Filesystem, "DeleteFile failed on %s: %s", - filename.c_str(), GetLastErrorMsg()); + if (!DeleteFileW(Common::UTF8ToUTF16W(filename).c_str())) { + LOG_ERROR(Common_Filesystem, "DeleteFile failed on %s: %s", filename.c_str(), + GetLastErrorMsg()); return false; } #else if (unlink(filename.c_str()) == -1) { - LOG_ERROR(Common_Filesystem, "unlink failed on %s: %s", - filename.c_str(), GetLastErrorMsg()); + LOG_ERROR(Common_Filesystem, "unlink failed on %s: %s", filename.c_str(), + GetLastErrorMsg()); return false; } #endif @@ -165,16 +156,15 @@ bool Delete(const std::string &filename) } // Returns true if successful, or path already exists. -bool CreateDir(const std::string &path) -{ +bool CreateDir(const std::string& path) { LOG_TRACE(Common_Filesystem, "directory %s", path.c_str()); #ifdef _WIN32 if (::CreateDirectoryW(Common::UTF8ToUTF16W(path).c_str(), nullptr)) return true; DWORD error = GetLastError(); - if (error == ERROR_ALREADY_EXISTS) - { - LOG_WARNING(Common_Filesystem, "CreateDirectory failed on %s: already exists", path.c_str()); + if (error == ERROR_ALREADY_EXISTS) { + LOG_WARNING(Common_Filesystem, "CreateDirectory failed on %s: already exists", + path.c_str()); return true; } LOG_ERROR(Common_Filesystem, "CreateDirectory failed on %s: %i", path.c_str(), error); @@ -185,8 +175,7 @@ bool CreateDir(const std::string &path) int err = errno; - if (err == EEXIST) - { + if (err == EEXIST) { LOG_WARNING(Common_Filesystem, "mkdir failed on %s: already exists", path.c_str()); return true; } @@ -197,20 +186,17 @@ bool CreateDir(const std::string &path) } // Creates the full path of fullPath returns true on success -bool CreateFullPath(const std::string &fullPath) -{ +bool CreateFullPath(const std::string& fullPath) { int panicCounter = 100; LOG_TRACE(Common_Filesystem, "path %s", fullPath.c_str()); - if (FileUtil::Exists(fullPath)) - { + if (FileUtil::Exists(fullPath)) { LOG_WARNING(Common_Filesystem, "path exists %s", fullPath.c_str()); return true; } size_t position = 0; - while (true) - { + while (true) { // Find next sub path position = fullPath.find(DIR_SEP_CHR, position); @@ -227,8 +213,7 @@ bool CreateFullPath(const std::string &fullPath) // A safety check panicCounter--; - if (panicCounter <= 0) - { + if (panicCounter <= 0) { LOG_ERROR(Common, "CreateFullPath: directory structure is too deep"); return false; } @@ -236,15 +221,12 @@ bool CreateFullPath(const std::string &fullPath) } } - // Deletes a directory filename, returns true on success -bool DeleteDir(const std::string &filename) -{ +bool DeleteDir(const std::string& filename) { LOG_INFO(Common_Filesystem, "directory %s", filename.c_str()); // check if a directory - if (!FileUtil::IsDirectory(filename)) - { + if (!FileUtil::IsDirectory(filename)) { LOG_ERROR(Common_Filesystem, "Not a directory %s", filename.c_str()); return false; } @@ -262,83 +244,73 @@ bool DeleteDir(const std::string &filename) } // renames file srcFilename to destFilename, returns true on success -bool Rename(const std::string &srcFilename, const std::string &destFilename) -{ - LOG_TRACE(Common_Filesystem, "%s --> %s", - srcFilename.c_str(), destFilename.c_str()); +bool Rename(const std::string& srcFilename, const std::string& destFilename) { + LOG_TRACE(Common_Filesystem, "%s --> %s", srcFilename.c_str(), destFilename.c_str()); #ifdef _WIN32 - if (_wrename(Common::UTF8ToUTF16W(srcFilename).c_str(), Common::UTF8ToUTF16W(destFilename).c_str()) == 0) + if (_wrename(Common::UTF8ToUTF16W(srcFilename).c_str(), + Common::UTF8ToUTF16W(destFilename).c_str()) == 0) return true; #else if (rename(srcFilename.c_str(), destFilename.c_str()) == 0) return true; #endif - LOG_ERROR(Common_Filesystem, "failed %s --> %s: %s", - srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); + LOG_ERROR(Common_Filesystem, "failed %s --> %s: %s", srcFilename.c_str(), destFilename.c_str(), + GetLastErrorMsg()); return false; } // copies file srcFilename to destFilename, returns true on success -bool Copy(const std::string &srcFilename, const std::string &destFilename) -{ - LOG_TRACE(Common_Filesystem, "%s --> %s", - srcFilename.c_str(), destFilename.c_str()); +bool Copy(const std::string& srcFilename, const std::string& destFilename) { + LOG_TRACE(Common_Filesystem, "%s --> %s", srcFilename.c_str(), destFilename.c_str()); #ifdef _WIN32 - if (CopyFileW(Common::UTF8ToUTF16W(srcFilename).c_str(), Common::UTF8ToUTF16W(destFilename).c_str(), FALSE)) + if (CopyFileW(Common::UTF8ToUTF16W(srcFilename).c_str(), + Common::UTF8ToUTF16W(destFilename).c_str(), FALSE)) return true; - LOG_ERROR(Common_Filesystem, "failed %s --> %s: %s", - srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); + LOG_ERROR(Common_Filesystem, "failed %s --> %s: %s", srcFilename.c_str(), destFilename.c_str(), + GetLastErrorMsg()); return false; #else - // buffer size +// buffer size #define BSIZE 1024 char buffer[BSIZE]; // Open input file - FILE *input = fopen(srcFilename.c_str(), "rb"); - if (!input) - { - LOG_ERROR(Common_Filesystem, "opening input failed %s --> %s: %s", - srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); + FILE* input = fopen(srcFilename.c_str(), "rb"); + if (!input) { + LOG_ERROR(Common_Filesystem, "opening input failed %s --> %s: %s", srcFilename.c_str(), + destFilename.c_str(), GetLastErrorMsg()); return false; } // open output file - FILE *output = fopen(destFilename.c_str(), "wb"); - if (!output) - { + FILE* output = fopen(destFilename.c_str(), "wb"); + if (!output) { fclose(input); - LOG_ERROR(Common_Filesystem, "opening output failed %s --> %s: %s", - srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); + LOG_ERROR(Common_Filesystem, "opening output failed %s --> %s: %s", srcFilename.c_str(), + destFilename.c_str(), GetLastErrorMsg()); return false; } // copy loop - while (!feof(input)) - { + while (!feof(input)) { // read input int rnum = fread(buffer, sizeof(char), BSIZE, input); - if (rnum != BSIZE) - { - if (ferror(input) != 0) - { - LOG_ERROR(Common_Filesystem, - "failed reading from source, %s --> %s: %s", - srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); + if (rnum != BSIZE) { + if (ferror(input) != 0) { + LOG_ERROR(Common_Filesystem, "failed reading from source, %s --> %s: %s", + srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); goto bail; } } // write output int wnum = fwrite(buffer, sizeof(char), rnum, output); - if (wnum != rnum) - { - LOG_ERROR(Common_Filesystem, - "failed writing to output, %s --> %s: %s", - srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); + if (wnum != rnum) { + LOG_ERROR(Common_Filesystem, "failed writing to output, %s --> %s: %s", + srcFilename.c_str(), destFilename.c_str(), GetLastErrorMsg()); goto bail; } } @@ -356,16 +328,13 @@ bail: } // Returns the size of filename (64bit) -u64 GetSize(const std::string &filename) -{ - if (!Exists(filename)) - { +u64 GetSize(const std::string& filename) { + if (!Exists(filename)) { LOG_ERROR(Common_Filesystem, "failed %s: No such file", filename.c_str()); return 0; } - if (IsDirectory(filename)) - { + if (IsDirectory(filename)) { LOG_ERROR(Common_Filesystem, "failed %s: is a directory", filename.c_str()); return 0; } @@ -377,65 +346,54 @@ u64 GetSize(const std::string &filename) if (stat64(filename.c_str(), &buf) == 0) #endif { - LOG_TRACE(Common_Filesystem, "%s: %lld", - filename.c_str(), (long long)buf.st_size); + LOG_TRACE(Common_Filesystem, "%s: %lld", filename.c_str(), (long long)buf.st_size); return buf.st_size; } - LOG_ERROR(Common_Filesystem, "Stat failed %s: %s", - filename.c_str(), GetLastErrorMsg()); + LOG_ERROR(Common_Filesystem, "Stat failed %s: %s", filename.c_str(), GetLastErrorMsg()); return 0; } // Overloaded GetSize, accepts file descriptor -u64 GetSize(const int fd) -{ +u64 GetSize(const int fd) { struct stat64 buf; if (fstat64(fd, &buf) != 0) { - LOG_ERROR(Common_Filesystem, "GetSize: stat failed %i: %s", - fd, GetLastErrorMsg()); + LOG_ERROR(Common_Filesystem, "GetSize: stat failed %i: %s", fd, GetLastErrorMsg()); return 0; } return buf.st_size; } // Overloaded GetSize, accepts FILE* -u64 GetSize(FILE *f) -{ +u64 GetSize(FILE* f) { // can't use off_t here because it can be 32-bit u64 pos = ftello(f); if (fseeko(f, 0, SEEK_END) != 0) { - LOG_ERROR(Common_Filesystem, "GetSize: seek failed %p: %s", - f, GetLastErrorMsg()); + LOG_ERROR(Common_Filesystem, "GetSize: seek failed %p: %s", f, GetLastErrorMsg()); return 0; } u64 size = ftello(f); if ((size != pos) && (fseeko(f, pos, SEEK_SET) != 0)) { - LOG_ERROR(Common_Filesystem, "GetSize: seek failed %p: %s", - f, GetLastErrorMsg()); + LOG_ERROR(Common_Filesystem, "GetSize: seek failed %p: %s", f, GetLastErrorMsg()); return 0; } return size; } // creates an empty file filename, returns true on success -bool CreateEmptyFile(const std::string &filename) -{ +bool CreateEmptyFile(const std::string& filename) { LOG_TRACE(Common_Filesystem, "%s", filename.c_str()); - if (!FileUtil::IOFile(filename, "wb")) - { - LOG_ERROR(Common_Filesystem, "failed %s: %s", - filename.c_str(), GetLastErrorMsg()); + if (!FileUtil::IOFile(filename, "wb")) { + LOG_ERROR(Common_Filesystem, "failed %s: %s", filename.c_str(), GetLastErrorMsg()); return false; } return true; } - -bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directory, DirectoryEntryCallable callback) -{ +bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string& directory, + DirectoryEntryCallable callback) { LOG_TRACE(Common_Filesystem, "directory %s", directory.c_str()); // How many files + directories we found @@ -457,7 +415,7 @@ bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directo do { const std::string virtual_name(Common::UTF16ToUTF8(ffd.cFileName)); #else - DIR *dirp = opendir(directory.c_str()); + DIR* dirp = opendir(directory.c_str()); if (!dirp) return false; @@ -493,8 +451,8 @@ bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directo return true; } -unsigned ScanDirectoryTree(const std::string &directory, FSTEntry& parent_entry, unsigned int recursion) -{ +unsigned ScanDirectoryTree(const std::string& directory, FSTEntry& parent_entry, + unsigned int recursion) { const auto callback = [recursion, &parent_entry](unsigned* num_entries_out, const std::string& directory, const std::string& virtual_name) -> bool { @@ -526,11 +484,8 @@ unsigned ScanDirectoryTree(const std::string &directory, FSTEntry& parent_entry, return ForeachDirectoryEntry(&num_entries, directory, callback) ? num_entries : 0; } - -bool DeleteDirRecursively(const std::string &directory, unsigned int recursion) -{ - const auto callback = [recursion](unsigned* num_entries_out, - const std::string& directory, +bool DeleteDirRecursively(const std::string& directory, unsigned int recursion) { + const auto callback = [recursion](unsigned* num_entries_out, const std::string& directory, const std::string& virtual_name) -> bool { std::string new_path = directory + DIR_SEP_CHR + virtual_name; @@ -551,53 +506,53 @@ bool DeleteDirRecursively(const std::string &directory, unsigned int recursion) } // Create directory and copy contents (does not overwrite existing files) -void CopyDir(const std::string &source_path, const std::string &dest_path) -{ +void CopyDir(const std::string& source_path, const std::string& dest_path) { #ifndef _WIN32 - if (source_path == dest_path) return; - if (!FileUtil::Exists(source_path)) return; - if (!FileUtil::Exists(dest_path)) FileUtil::CreateFullPath(dest_path); - - DIR *dirp = opendir(source_path.c_str()); - if (!dirp) return; + if (source_path == dest_path) + return; + if (!FileUtil::Exists(source_path)) + return; + if (!FileUtil::Exists(dest_path)) + FileUtil::CreateFullPath(dest_path); + + DIR* dirp = opendir(source_path.c_str()); + if (!dirp) + return; while (struct dirent* result = readdir(dirp)) { const std::string virtualName(result->d_name); // check for "." and ".." if (((virtualName[0] == '.') && (virtualName[1] == '\0')) || - ((virtualName[0] == '.') && (virtualName[1] == '.') && - (virtualName[2] == '\0'))) + ((virtualName[0] == '.') && (virtualName[1] == '.') && (virtualName[2] == '\0'))) continue; std::string source, dest; source = source_path + virtualName; dest = dest_path + virtualName; - if (IsDirectory(source)) - { + if (IsDirectory(source)) { source += '/'; dest += '/'; - if (!FileUtil::Exists(dest)) FileUtil::CreateFullPath(dest); + if (!FileUtil::Exists(dest)) + FileUtil::CreateFullPath(dest); CopyDir(source, dest); - } - else if (!FileUtil::Exists(dest)) FileUtil::Copy(source, dest); + } else if (!FileUtil::Exists(dest)) + FileUtil::Copy(source, dest); } closedir(dirp); #endif } // Returns the current directory -std::string GetCurrentDir() -{ - // Get the current working directory (getcwd uses malloc) +std::string GetCurrentDir() { +// Get the current working directory (getcwd uses malloc) #ifdef _WIN32 - wchar_t *dir; + wchar_t* dir; if (!(dir = _wgetcwd(nullptr, 0))) { #else - char *dir; + char* dir; if (!(dir = getcwd(nullptr, 0))) { #endif - LOG_ERROR(Common_Filesystem, "GetCurrentDirectory failed: %s", - GetLastErrorMsg()); + LOG_ERROR(Common_Filesystem, "GetCurrentDirectory failed: %s", GetLastErrorMsg()); return nullptr; } #ifdef _WIN32 @@ -610,8 +565,7 @@ std::string GetCurrentDir() } // Sets the current directory to the given directory -bool SetCurrentDir(const std::string &directory) -{ +bool SetCurrentDir(const std::string& directory) { #ifdef _WIN32 return _wchdir(Common::UTF8ToUTF16W(directory).c_str()) == 0; #else @@ -620,8 +574,7 @@ bool SetCurrentDir(const std::string &directory) } #if defined(__APPLE__) -std::string GetBundleDirectory() -{ +std::string GetBundleDirectory() { CFURLRef BundleRef; char AppBundlePath[MAXPATHLEN]; // Get the main bundle for the app @@ -636,11 +589,9 @@ std::string GetBundleDirectory() #endif #ifdef _WIN32 -std::string& GetExeDirectory() -{ +std::string& GetExeDirectory() { static std::string exe_path; - if (exe_path.empty()) - { + if (exe_path.empty()) { wchar_t wchar_exe_path[2048]; GetModuleFileNameW(nullptr, wchar_exe_path, 2048); exe_path = Common::UTF16ToUTF8(wchar_exe_path); @@ -660,7 +611,8 @@ static const std::string& GetHomeDirectory() { home_path = envvar; } else { auto pw = getpwuid(getuid()); - ASSERT_MSG(pw, "$HOME isn’t defined, and the current user can’t be found in /etc/passwd."); + ASSERT_MSG(pw, + "$HOME isn’t defined, and the current user can’t be found in /etc/passwd."); home_path = pw->pw_dir; } } @@ -699,11 +651,10 @@ static const std::string GetUserDirectory(const std::string& envvar) { } #endif -std::string GetSysDirectory() -{ +std::string GetSysDirectory() { std::string sysDir; -#if defined (__APPLE__) +#if defined(__APPLE__) sysDir = GetBundleDirectory(); sysDir += DIR_SEP; sysDir += SYSDATA_DIR; @@ -718,123 +669,114 @@ std::string GetSysDirectory() // Returns a string with a Citra data dir or file in the user's home // directory. To be used in "multi-user" mode (that is, installed). -const std::string& GetUserPath(const unsigned int DirIDX, const std::string &newPath) -{ +const std::string& GetUserPath(const unsigned int DirIDX, const std::string& newPath) { static std::string paths[NUM_PATH_INDICES]; // Set up all paths and files on the first run - if (paths[D_USER_IDX].empty()) - { + if (paths[D_USER_IDX].empty()) { #ifdef _WIN32 - paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP; + paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP; paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; - paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; + paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; #else if (FileUtil::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) { - paths[D_USER_IDX] = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; + paths[D_USER_IDX] = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; - paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; + paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; } else { - std::string data_dir = GetUserDirectory("XDG_DATA_HOME"); + std::string data_dir = GetUserDirectory("XDG_DATA_HOME"); std::string config_dir = GetUserDirectory("XDG_CONFIG_HOME"); - std::string cache_dir = GetUserDirectory("XDG_CACHE_HOME"); + std::string cache_dir = GetUserDirectory("XDG_CACHE_HOME"); - paths[D_USER_IDX] = data_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; + paths[D_USER_IDX] = data_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; paths[D_CONFIG_IDX] = config_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; - paths[D_CACHE_IDX] = cache_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; + paths[D_CACHE_IDX] = cache_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; } #endif - paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP; - paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP; - paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; - paths[D_NAND_IDX] = paths[D_USER_IDX] + NAND_DIR DIR_SEP; - paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP; - paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; - paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; - paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP; - paths[D_SCREENSHOTS_IDX] = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP; - paths[D_DUMP_IDX] = paths[D_USER_IDX] + DUMP_DIR DIR_SEP; - paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; - paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; - paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; - paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOGS_DIR DIR_SEP; + paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP; + paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP; + paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; + paths[D_NAND_IDX] = paths[D_USER_IDX] + NAND_DIR DIR_SEP; + paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP; + paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; + paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; + paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP; + paths[D_SCREENSHOTS_IDX] = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP; + paths[D_DUMP_IDX] = paths[D_USER_IDX] + DUMP_DIR DIR_SEP; + paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; + paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; + paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; + paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOGS_DIR DIR_SEP; paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; - paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; - paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; + paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; + paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; } - if (!newPath.empty()) - { - if (!FileUtil::IsDirectory(newPath)) - { + if (!newPath.empty()) { + if (!FileUtil::IsDirectory(newPath)) { LOG_ERROR(Common_Filesystem, "Invalid path specified %s", newPath.c_str()); return paths[DirIDX]; - } - else - { + } else { paths[DirIDX] = newPath; } - switch (DirIDX) - { + switch (DirIDX) { case D_ROOT_IDX: - paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP; - paths[D_SYSCONF_IDX] = paths[D_USER_IDX] + SYSCONF_DIR + DIR_SEP; - paths[F_SYSCONF_IDX] = paths[D_SYSCONF_IDX] + SYSCONF; + paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP; + paths[D_SYSCONF_IDX] = paths[D_USER_IDX] + SYSCONF_DIR + DIR_SEP; + paths[F_SYSCONF_IDX] = paths[D_SYSCONF_IDX] + SYSCONF; break; case D_USER_IDX: - paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP; - paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; - paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP; - paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP; - paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; - paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; - paths[D_NAND_IDX] = paths[D_USER_IDX] + NAND_DIR DIR_SEP; - paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; - paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; - paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP; - paths[D_SCREENSHOTS_IDX] = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP; - paths[D_DUMP_IDX] = paths[D_USER_IDX] + DUMP_DIR DIR_SEP; - paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; - paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; - paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; - paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOGS_DIR DIR_SEP; - paths[D_SYSCONF_IDX] = paths[D_USER_IDX] + SYSCONF_DIR DIR_SEP; - paths[F_EMUCONFIG_IDX] = paths[D_CONFIG_IDX] + EMU_CONFIG; + paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP; + paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; + paths[D_GAMECONFIG_IDX] = paths[D_USER_IDX] + GAMECONFIG_DIR DIR_SEP; + paths[D_MAPS_IDX] = paths[D_USER_IDX] + MAPS_DIR DIR_SEP; + paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; + paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; + paths[D_NAND_IDX] = paths[D_USER_IDX] + NAND_DIR DIR_SEP; + paths[D_SHADERCACHE_IDX] = paths[D_USER_IDX] + SHADERCACHE_DIR DIR_SEP; + paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; + paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP; + paths[D_SCREENSHOTS_IDX] = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP; + paths[D_DUMP_IDX] = paths[D_USER_IDX] + DUMP_DIR DIR_SEP; + paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; + paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; + paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; + paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOGS_DIR DIR_SEP; + paths[D_SYSCONF_IDX] = paths[D_USER_IDX] + SYSCONF_DIR DIR_SEP; + paths[F_EMUCONFIG_IDX] = paths[D_CONFIG_IDX] + EMU_CONFIG; paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; - paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; - paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; + paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; + paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; break; case D_CONFIG_IDX: - paths[F_EMUCONFIG_IDX] = paths[D_CONFIG_IDX] + EMU_CONFIG; + paths[F_EMUCONFIG_IDX] = paths[D_CONFIG_IDX] + EMU_CONFIG; paths[F_DEBUGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + DEBUGGER_CONFIG; - paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; + paths[F_LOGGERCONFIG_IDX] = paths[D_CONFIG_IDX] + LOGGER_CONFIG; break; case D_DUMP_IDX: - paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; - paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; - paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; + paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP; + paths[D_DUMPAUDIO_IDX] = paths[D_DUMP_IDX] + DUMP_AUDIO_DIR DIR_SEP; + paths[D_DUMPTEXTURES_IDX] = paths[D_DUMP_IDX] + DUMP_TEXTURES_DIR DIR_SEP; break; case D_LOGS_IDX: - paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; + paths[F_MAINLOG_IDX] = paths[D_LOGS_IDX] + MAIN_LOG; } } return paths[DirIDX]; } -size_t WriteStringToFile(bool text_file, const std::string &str, const char *filename) -{ +size_t WriteStringToFile(bool text_file, const std::string& str, const char* filename) { return FileUtil::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size()); } -size_t ReadFileToString(bool text_file, const char *filename, std::string &str) -{ +size_t ReadFileToString(bool text_file, const char* filename, std::string& str) { IOFile file(filename, text_file ? "r" : "rb"); if (!file) @@ -886,42 +828,35 @@ void SplitFilename83(const std::string& filename, std::array<char, 9>& short_nam } } -IOFile::IOFile() -{ -} +IOFile::IOFile() {} -IOFile::IOFile(const std::string& filename, const char openmode[]) -{ +IOFile::IOFile(const std::string& filename, const char openmode[]) { Open(filename, openmode); } -IOFile::~IOFile() -{ +IOFile::~IOFile() { Close(); } -IOFile::IOFile(IOFile&& other) -{ +IOFile::IOFile(IOFile&& other) { Swap(other); } -IOFile& IOFile::operator=(IOFile&& other) -{ +IOFile& IOFile::operator=(IOFile&& other) { Swap(other); return *this; } -void IOFile::Swap(IOFile& other) -{ +void IOFile::Swap(IOFile& other) { std::swap(m_file, other.m_file); std::swap(m_good, other.m_good); } -bool IOFile::Open(const std::string& filename, const char openmode[]) -{ +bool IOFile::Open(const std::string& filename, const char openmode[]) { Close(); #ifdef _WIN32 - _wfopen_s(&m_file, Common::UTF8ToUTF16W(filename).c_str(), Common::UTF8ToUTF16W(openmode).c_str()); + _wfopen_s(&m_file, Common::UTF8ToUTF16W(filename).c_str(), + Common::UTF8ToUTF16W(openmode).c_str()); #else m_file = fopen(filename.c_str(), openmode); #endif @@ -930,8 +865,7 @@ bool IOFile::Open(const std::string& filename, const char openmode[]) return m_good; } -bool IOFile::Close() -{ +bool IOFile::Close() { if (!IsOpen() || 0 != std::fclose(m_file)) m_good = false; @@ -939,50 +873,46 @@ bool IOFile::Close() return m_good; } -u64 IOFile::GetSize() const -{ +u64 IOFile::GetSize() const { if (IsOpen()) return FileUtil::GetSize(m_file); return 0; } -bool IOFile::Seek(s64 off, int origin) -{ +bool IOFile::Seek(s64 off, int origin) { if (!IsOpen() || 0 != fseeko(m_file, off, origin)) m_good = false; return m_good; } -u64 IOFile::Tell() const -{ +u64 IOFile::Tell() const { if (IsOpen()) return ftello(m_file); return -1; } -bool IOFile::Flush() -{ +bool IOFile::Flush() { if (!IsOpen() || 0 != std::fflush(m_file)) m_good = false; return m_good; } -bool IOFile::Resize(u64 size) -{ - if (!IsOpen() || 0 != +bool IOFile::Resize(u64 size) { + if (!IsOpen() || + 0 != #ifdef _WIN32 - // ector: _chsize sucks, not 64-bit safe - // F|RES: changed to _chsize_s. i think it is 64-bit safe - _chsize_s(_fileno(m_file), size) + // ector: _chsize sucks, not 64-bit safe + // F|RES: changed to _chsize_s. i think it is 64-bit safe + _chsize_s(_fileno(m_file), size) #else - // TODO: handle 64bit and growing - ftruncate(fileno(m_file), size) + // TODO: handle 64bit and growing + ftruncate(fileno(m_file), size) #endif - ) + ) m_good = false; return m_good; diff --git a/src/common/file_util.h b/src/common/file_util.h index 7ad7ee829..204b06f14 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -5,15 +5,13 @@ #pragma once #include <array> +#include <cstdio> #include <fstream> #include <functional> -#include <cstdio> #include <string> #include <type_traits> #include <vector> - #include "common/common_types.h" - #ifdef _MSC_VER #include "common/string_util.h" #endif @@ -51,75 +49,75 @@ enum { NUM_PATH_INDICES }; -namespace FileUtil -{ +namespace FileUtil { // FileSystem tree node/ -struct FSTEntry -{ +struct FSTEntry { bool isDirectory; - u64 size; // file length or number of entries from children - std::string physicalName; // name on disk - std::string virtualName; // name in FST names table + u64 size; // file length or number of entries from children + std::string physicalName; // name on disk + std::string virtualName; // name in FST names table std::vector<FSTEntry> children; }; // Returns true if file filename exists -bool Exists(const std::string &filename); +bool Exists(const std::string& filename); // Returns true if filename is a directory -bool IsDirectory(const std::string &filename); +bool IsDirectory(const std::string& filename); // Returns the size of filename (64bit) -u64 GetSize(const std::string &filename); +u64 GetSize(const std::string& filename); // Overloaded GetSize, accepts file descriptor u64 GetSize(const int fd); // Overloaded GetSize, accepts FILE* -u64 GetSize(FILE *f); +u64 GetSize(FILE* f); // Returns true if successful, or path already exists. -bool CreateDir(const std::string &filename); +bool CreateDir(const std::string& filename); // Creates the full path of fullPath returns true on success -bool CreateFullPath(const std::string &fullPath); +bool CreateFullPath(const std::string& fullPath); // Deletes a given filename, return true on success // Doesn't supports deleting a directory -bool Delete(const std::string &filename); +bool Delete(const std::string& filename); // Deletes a directory filename, returns true on success -bool DeleteDir(const std::string &filename); +bool DeleteDir(const std::string& filename); // renames file srcFilename to destFilename, returns true on success -bool Rename(const std::string &srcFilename, const std::string &destFilename); +bool Rename(const std::string& srcFilename, const std::string& destFilename); // copies file srcFilename to destFilename, returns true on success -bool Copy(const std::string &srcFilename, const std::string &destFilename); +bool Copy(const std::string& srcFilename, const std::string& destFilename); // creates an empty file filename, returns true on success -bool CreateEmptyFile(const std::string &filename); +bool CreateEmptyFile(const std::string& filename); /** - * @param num_entries_out to be assigned by the callable with the number of iterated directory entries, never null + * @param num_entries_out to be assigned by the callable with the number of iterated directory + * entries, never null * @param directory the path to the enclosing directory * @param virtual_name the entry name, without any preceding directory info * @return whether handling the entry succeeded */ -using DirectoryEntryCallable = std::function<bool(unsigned* num_entries_out, - const std::string& directory, - const std::string& virtual_name)>; +using DirectoryEntryCallable = std::function<bool( + unsigned* num_entries_out, const std::string& directory, const std::string& virtual_name)>; /** * Scans a directory, calling the callback for each file/directory contained within. * If the callback returns failure, scanning halts and this function returns failure as well - * @param num_entries_out assigned by the function with the number of iterated directory entries, can be null + * @param num_entries_out assigned by the function with the number of iterated directory entries, + * can be null * @param directory the directory to scan * @param callback The callback which will be called for each entry * @return whether scanning the directory succeeded */ -bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directory, DirectoryEntryCallable callback); +bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string& directory, + DirectoryEntryCallable callback); /** * Scans the directory tree, storing the results. @@ -128,23 +126,24 @@ bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directo * @param recursion Number of children directories to read before giving up. * @return the total number of files/directories found */ -unsigned ScanDirectoryTree(const std::string &directory, FSTEntry& parent_entry, unsigned int recursion = 0); +unsigned ScanDirectoryTree(const std::string& directory, FSTEntry& parent_entry, + unsigned int recursion = 0); // deletes the given directory and anything under it. Returns true on success. -bool DeleteDirRecursively(const std::string &directory, unsigned int recursion = 256); +bool DeleteDirRecursively(const std::string& directory, unsigned int recursion = 256); // Returns the current directory std::string GetCurrentDir(); // Create directory and copy contents (does not overwrite existing files) -void CopyDir(const std::string &source_path, const std::string &dest_path); +void CopyDir(const std::string& source_path, const std::string& dest_path); // Set the current directory to given directory -bool SetCurrentDir(const std::string &directory); +bool SetCurrentDir(const std::string& directory); // Returns a pointer to a string with a Citra data dir in the user's home // directory. To be used in "multi-user" mode (that is, installed). -const std::string& GetUserPath(const unsigned int DirIDX, const std::string &newPath=""); +const std::string& GetUserPath(const unsigned int DirIDX, const std::string& newPath = ""); // Returns the path to where the sys file are std::string GetSysDirectory(); @@ -154,11 +153,11 @@ std::string GetBundleDirectory(); #endif #ifdef _WIN32 -std::string &GetExeDirectory(); +std::string& GetExeDirectory(); #endif -size_t WriteStringToFile(bool text_file, const std::string &str, const char *filename); -size_t ReadFileToString(bool text_file, const char *filename, std::string &str); +size_t WriteStringToFile(bool text_file, const std::string& str, const char* filename); +size_t ReadFileToString(bool text_file, const char* filename, std::string& str); /** * Splits the filename into 8.3 format @@ -173,8 +172,7 @@ void SplitFilename83(const std::string& filename, std::array<char, 9>& short_nam // simple wrapper for cstdlib file functions to // hopefully will make error checking easier // and make forgetting an fclose() harder -class IOFile : public NonCopyable -{ +class IOFile : public NonCopyable { public: IOFile(); IOFile(const std::string& filename, const char openmode[]); @@ -190,11 +188,12 @@ public: bool Close(); template <typename T> - size_t ReadArray(T* data, size_t length) - { - static_assert(std::is_standard_layout<T>(), "Given array does not consist of standard layout objects"); + size_t ReadArray(T* data, size_t length) { + static_assert(std::is_standard_layout<T>(), + "Given array does not consist of standard layout objects"); #if (__GNUC__ >= 5) || defined(__clang__) || defined(_MSC_VER) - static_assert(std::is_trivially_copyable<T>(), "Given array does not consist of trivially copyable objects"); + static_assert(std::is_trivially_copyable<T>(), + "Given array does not consist of trivially copyable objects"); #endif if (!IsOpen()) { @@ -210,11 +209,12 @@ public: } template <typename T> - size_t WriteArray(const T* data, size_t length) - { - static_assert(std::is_standard_layout<T>(), "Given array does not consist of standard layout objects"); + size_t WriteArray(const T* data, size_t length) { + static_assert(std::is_standard_layout<T>(), + "Given array does not consist of standard layout objects"); #if (__GNUC__ >= 5) || defined(__clang__) || defined(_MSC_VER) - static_assert(std::is_trivially_copyable<T>(), "Given array does not consist of trivially copyable objects"); + static_assert(std::is_trivially_copyable<T>(), + "Given array does not consist of trivially copyable objects"); #endif if (!IsOpen()) { @@ -229,27 +229,31 @@ public: return items_written; } - size_t ReadBytes(void* data, size_t length) - { + size_t ReadBytes(void* data, size_t length) { return ReadArray(reinterpret_cast<char*>(data), length); } - size_t WriteBytes(const void* data, size_t length) - { + size_t WriteBytes(const void* data, size_t length) { return WriteArray(reinterpret_cast<const char*>(data), length); } - template<typename T> + template <typename T> size_t WriteObject(const T& object) { static_assert(!std::is_pointer<T>::value, "Given object is a pointer"); return WriteArray(&object, 1); } - bool IsOpen() const { return nullptr != m_file; } + bool IsOpen() const { + return nullptr != m_file; + } // m_good is set to false when a read, write or other function fails - bool IsGood() const { return m_good; } - explicit operator bool() const { return IsGood(); } + bool IsGood() const { + return m_good; + } + explicit operator bool() const { + return IsGood(); + } bool Seek(s64 off, int origin); u64 Tell() const; @@ -258,19 +262,21 @@ public: bool Flush(); // clear error state - void Clear() { m_good = true; std::clearerr(m_file); } + void Clear() { + m_good = true; + std::clearerr(m_file); + } private: std::FILE* m_file = nullptr; bool m_good = true; }; -} // namespace +} // namespace // To deal with Windows being dumb at unicode: template <typename T> -void OpenFStream(T& fstream, const std::string& filename, std::ios_base::openmode openmode) -{ +void OpenFStream(T& fstream, const std::string& filename, std::ios_base::openmode openmode) { #ifdef _MSC_VER fstream.open(Common::UTF8ToTStr(filename).c_str(), openmode); #else diff --git a/src/common/hash.cpp b/src/common/hash.cpp index c49c2f60e..5aa5118eb 100644 --- a/src/common/hash.cpp +++ b/src/common/hash.cpp @@ -5,7 +5,6 @@ #if defined(_MSC_VER) #include <stdlib.h> #endif - #include "common_funcs.h" #include "common_types.h" #include "hash.h" @@ -36,7 +35,7 @@ static FORCE_INLINE u64 fmix64(u64 k) { // platforms (MurmurHash3_x64_128). It was taken from: // https://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp void MurmurHash3_128(const void* key, int len, u32 seed, void* out) { - const u8 * data = (const u8*)key; + const u8* data = (const u8*)key; const int nblocks = len / 16; u64 h1 = seed; @@ -47,52 +46,84 @@ void MurmurHash3_128(const void* key, int len, u32 seed, void* out) { // Body - const u64 * blocks = (const u64 *)(data); + const u64* blocks = (const u64*)(data); for (int i = 0; i < nblocks; i++) { - u64 k1 = getblock64(blocks,i*2+0); - u64 k2 = getblock64(blocks,i*2+1); - - k1 *= c1; k1 = _rotl64(k1,31); k1 *= c2; h1 ^= k1; - - h1 = _rotl64(h1,27); h1 += h2; h1 = h1*5+0x52dce729; - - k2 *= c2; k2 = _rotl64(k2,33); k2 *= c1; h2 ^= k2; - - h2 = _rotl64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5; + u64 k1 = getblock64(blocks, i * 2 + 0); + u64 k2 = getblock64(blocks, i * 2 + 1); + + k1 *= c1; + k1 = _rotl64(k1, 31); + k1 *= c2; + h1 ^= k1; + + h1 = _rotl64(h1, 27); + h1 += h2; + h1 = h1 * 5 + 0x52dce729; + + k2 *= c2; + k2 = _rotl64(k2, 33); + k2 *= c1; + h2 ^= k2; + + h2 = _rotl64(h2, 31); + h2 += h1; + h2 = h2 * 5 + 0x38495ab5; } // Tail - const u8 * tail = (const u8*)(data + nblocks*16); + const u8* tail = (const u8*)(data + nblocks * 16); u64 k1 = 0; u64 k2 = 0; switch (len & 15) { - case 15: k2 ^= ((u64)tail[14]) << 48; - case 14: k2 ^= ((u64)tail[13]) << 40; - case 13: k2 ^= ((u64)tail[12]) << 32; - case 12: k2 ^= ((u64)tail[11]) << 24; - case 11: k2 ^= ((u64)tail[10]) << 16; - case 10: k2 ^= ((u64)tail[ 9]) << 8; - case 9: k2 ^= ((u64)tail[ 8]) << 0; - k2 *= c2; k2 = _rotl64(k2,33); k2 *= c1; h2 ^= k2; - - case 8: k1 ^= ((u64)tail[ 7]) << 56; - case 7: k1 ^= ((u64)tail[ 6]) << 48; - case 6: k1 ^= ((u64)tail[ 5]) << 40; - case 5: k1 ^= ((u64)tail[ 4]) << 32; - case 4: k1 ^= ((u64)tail[ 3]) << 24; - case 3: k1 ^= ((u64)tail[ 2]) << 16; - case 2: k1 ^= ((u64)tail[ 1]) << 8; - case 1: k1 ^= ((u64)tail[ 0]) << 0; - k1 *= c1; k1 = _rotl64(k1,31); k1 *= c2; h1 ^= k1; + case 15: + k2 ^= ((u64)tail[14]) << 48; + case 14: + k2 ^= ((u64)tail[13]) << 40; + case 13: + k2 ^= ((u64)tail[12]) << 32; + case 12: + k2 ^= ((u64)tail[11]) << 24; + case 11: + k2 ^= ((u64)tail[10]) << 16; + case 10: + k2 ^= ((u64)tail[9]) << 8; + case 9: + k2 ^= ((u64)tail[8]) << 0; + k2 *= c2; + k2 = _rotl64(k2, 33); + k2 *= c1; + h2 ^= k2; + + case 8: + k1 ^= ((u64)tail[7]) << 56; + case 7: + k1 ^= ((u64)tail[6]) << 48; + case 6: + k1 ^= ((u64)tail[5]) << 40; + case 5: + k1 ^= ((u64)tail[4]) << 32; + case 4: + k1 ^= ((u64)tail[3]) << 24; + case 3: + k1 ^= ((u64)tail[2]) << 16; + case 2: + k1 ^= ((u64)tail[1]) << 8; + case 1: + k1 ^= ((u64)tail[0]) << 0; + k1 *= c1; + k1 = _rotl64(k1, 31); + k1 *= c2; + h1 ^= k1; }; // Finalization - h1 ^= len; h2 ^= len; + h1 ^= len; + h2 ^= len; h1 += h2; h2 += h1; diff --git a/src/common/key_map.cpp b/src/common/key_map.cpp index ad311d66b..79b3fcb18 100644 --- a/src/common/key_map.cpp +++ b/src/common/key_map.cpp @@ -3,7 +3,6 @@ // Refer to the license.txt file included. #include <map> - #include "common/emu_window.h" #include "common/key_map.h" @@ -13,11 +12,25 @@ namespace KeyMap { // and map it directly to EmuWindow::ButtonPressed. // It should go the analog input way like circle pad does. const std::array<KeyTarget, Settings::NativeInput::NUM_INPUTS> mapping_targets = {{ - Service::HID::PAD_A, Service::HID::PAD_B, Service::HID::PAD_X, Service::HID::PAD_Y, - Service::HID::PAD_L, Service::HID::PAD_R, Service::HID::PAD_ZL, Service::HID::PAD_ZR, - Service::HID::PAD_START, Service::HID::PAD_SELECT, Service::HID::PAD_NONE, - Service::HID::PAD_UP, Service::HID::PAD_DOWN, Service::HID::PAD_LEFT, Service::HID::PAD_RIGHT, - Service::HID::PAD_C_UP, Service::HID::PAD_C_DOWN, Service::HID::PAD_C_LEFT, Service::HID::PAD_C_RIGHT, + Service::HID::PAD_A, + Service::HID::PAD_B, + Service::HID::PAD_X, + Service::HID::PAD_Y, + Service::HID::PAD_L, + Service::HID::PAD_R, + Service::HID::PAD_ZL, + Service::HID::PAD_ZR, + Service::HID::PAD_START, + Service::HID::PAD_SELECT, + Service::HID::PAD_NONE, + Service::HID::PAD_UP, + Service::HID::PAD_DOWN, + Service::HID::PAD_LEFT, + Service::HID::PAD_RIGHT, + Service::HID::PAD_C_UP, + Service::HID::PAD_C_DOWN, + Service::HID::PAD_C_LEFT, + Service::HID::PAD_C_RIGHT, IndirectTarget::CirclePadUp, IndirectTarget::CirclePadDown, @@ -49,7 +62,8 @@ static void UpdateCirclePad(EmuWindow& emu_window) { --y; float modifier = circle_pad_modifier ? Settings::values.pad_circle_modifier_scale : 1.0; - emu_window.CirclePadUpdated(x * modifier * (y == 0 ? 1.0 : SQRT_HALF), y * modifier * (x == 0 ? 1.0 : SQRT_HALF)); + emu_window.CirclePadUpdated(x * modifier * (y == 0 ? 1.0 : SQRT_HALF), + y * modifier * (x == 0 ? 1.0 : SQRT_HALF)); } int NewDeviceId() { @@ -103,7 +117,7 @@ void PressKey(EmuWindow& emu_window, HostDeviceKey key) { } } -void ReleaseKey(EmuWindow& emu_window,HostDeviceKey key) { +void ReleaseKey(EmuWindow& emu_window, HostDeviceKey key) { auto target = key_map.find(key); if (target == key_map.end()) return; @@ -135,5 +149,4 @@ void ReleaseKey(EmuWindow& emu_window,HostDeviceKey key) { } } } - } diff --git a/src/common/key_map.h b/src/common/key_map.h index b62f017c6..040794578 100644 --- a/src/common/key_map.h +++ b/src/common/key_map.h @@ -55,14 +55,12 @@ struct HostDeviceKey { int key_code; int device_id; ///< Uniquely identifies a host device - bool operator<(const HostDeviceKey &other) const { - return std::tie(key_code, device_id) < - std::tie(other.key_code, other.device_id); + bool operator<(const HostDeviceKey& other) const { + return std::tie(key_code, device_id) < std::tie(other.key_code, other.device_id); } - bool operator==(const HostDeviceKey &other) const { - return std::tie(key_code, device_id) == - std::tie(other.key_code, other.device_id); + bool operator==(const HostDeviceKey& other) const { + return std::tie(key_code, device_id) == std::tie(other.key_code, other.device_id); } }; @@ -92,5 +90,4 @@ void PressKey(EmuWindow& emu_window, HostDeviceKey key); * Maps a key release action and call the corresponding function in EmuWindow */ void ReleaseKey(EmuWindow& emu_window, HostDeviceKey key); - } diff --git a/src/common/linear_disk_cache.h b/src/common/linear_disk_cache.h index 48529cf42..94c695163 100644 --- a/src/common/linear_disk_cache.h +++ b/src/common/linear_disk_cache.h @@ -4,31 +4,30 @@ #pragma once -#include "common/common_types.h" #include <fstream> +#include "common/common_types.h" // defined in Version.cpp -extern const char *scm_rev_git_str; +extern const char* scm_rev_git_str; // On disk format: -//header{ +// header{ // u32 'DCAC'; // u32 version; // svn_rev // u16 sizeof(key_type); // u16 sizeof(value_type); //} -//key_value_pair{ +// key_value_pair{ // u32 value_size; // key_type key; // value_type[value_size] value; //} template <typename K, typename V> -class LinearDiskCacheReader -{ +class LinearDiskCacheReader { public: - virtual void Read(const K &key, const V *value, u32 value_size) = 0; + virtual void Read(const K& key, const V* value, u32 value_size) = 0; }; // Dead simple unsorted key-value store with append functionality. @@ -44,12 +43,10 @@ public: // K : the key type // V : value array type template <typename K, typename V> -class LinearDiskCache -{ +class LinearDiskCache { public: // return number of read entries - u32 OpenAndRead(const char *filename, LinearDiskCacheReader<K, V> &reader) - { + u32 OpenAndRead(const char* filename, LinearDiskCacheReader<K, V>& reader) { using std::ios_base; // close any currently opened file @@ -65,20 +62,19 @@ public: std::fstream::pos_type start_pos = m_file.tellg(); std::streamoff file_size = end_pos - start_pos; - if (m_file.is_open() && ValidateHeader()) - { + if (m_file.is_open() && ValidateHeader()) { // good header, read some key/value pairs K key; - V *value = nullptr; + V* value = nullptr; u32 value_size; u32 entry_number; std::fstream::pos_type last_pos = m_file.tellg(); - while (Read(&value_size)) - { - std::streamoff next_extent = (last_pos - start_pos) + sizeof(value_size) + value_size; + while (Read(&value_size)) { + std::streamoff next_extent = + (last_pos - start_pos) + sizeof(value_size) + value_size; if (next_extent > file_size) break; @@ -86,15 +82,10 @@ public: value = new V[value_size]; // read key/value and pass to reader - if (Read(&key) && - Read(value, value_size) && - Read(&entry_number) && - entry_number == m_num_entries+1) - { + if (Read(&key) && Read(value, value_size) && Read(&entry_number) && + entry_number == m_num_entries + 1) { reader.Read(key, value, value_size); - } - else - { + } else { break; } @@ -116,13 +107,11 @@ public: return 0; } - void Sync() - { + void Sync() { m_file.flush(); } - void Close() - { + void Close() { if (m_file.is_open()) m_file.close(); // clear any error flags @@ -130,9 +119,9 @@ public: } // Appends a key-value pair to the store. - void Append(const K &key, const V *value, u32 value_size) - { - // TODO: Should do a check that we don't already have "key"? (I think each caller does that already.) + void Append(const K& key, const V* value, u32 value_size) { + // TODO: Should do a check that we don't already have "key"? (I think each caller does that + // already.) Write(&value_size); Write(&key); Write(value, value_size); @@ -141,38 +130,29 @@ public: } private: - void WriteHeader() - { + void WriteHeader() { Write(&m_header); } - bool ValidateHeader() - { + bool ValidateHeader() { char file_header[sizeof(Header)]; - return (Read(file_header, sizeof(Header)) - && !memcmp((const char*)&m_header, file_header, sizeof(Header))); + return (Read(file_header, sizeof(Header)) && + !memcmp((const char*)&m_header, file_header, sizeof(Header))); } template <typename D> - bool Write(const D *data, u32 count = 1) - { + bool Write(const D* data, u32 count = 1) { return m_file.write((const char*)data, count * sizeof(D)).good(); } template <typename D> - bool Read(const D *data, u32 count = 1) - { + bool Read(const D* data, u32 count = 1) { return m_file.read((char*)data, count * sizeof(D)).good(); } - struct Header - { - Header() - : id(*(u32*)"DCAC") - , key_t_size(sizeof(K)) - , value_t_size(sizeof(V)) - { + struct Header { + Header() : id(*(u32*)"DCAC"), key_t_size(sizeof(K)), value_t_size(sizeof(V)) { memcpy(ver, scm_rev_git_str, 40); } diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 0b2fabec9..9a13a9e90 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -5,7 +5,6 @@ #include <algorithm> #include <array> #include <cstdio> - #include "common/assert.h" #include "common/common_funcs.h" // snprintf compatibility define #include "common/logging/backend.h" @@ -16,73 +15,79 @@ namespace Log { /// Macro listing all log classes. Code should define CLS and SUB as desired before invoking this. -#define ALL_LOG_CLASSES() \ - CLS(Log) \ - CLS(Common) \ - SUB(Common, Filesystem) \ - SUB(Common, Memory) \ - CLS(Core) \ - SUB(Core, ARM11) \ - SUB(Core, Timing) \ - CLS(Config) \ - CLS(Debug) \ - SUB(Debug, Emulated) \ - SUB(Debug, GPU) \ - SUB(Debug, Breakpoint) \ - SUB(Debug, GDBStub) \ - CLS(Kernel) \ - SUB(Kernel, SVC) \ - CLS(Service) \ - SUB(Service, SRV) \ - SUB(Service, FRD) \ - SUB(Service, FS) \ - SUB(Service, ERR) \ - SUB(Service, APT) \ - SUB(Service, GSP) \ - SUB(Service, AC) \ - SUB(Service, AM) \ - SUB(Service, PTM) \ - SUB(Service, LDR) \ - SUB(Service, NDM) \ - SUB(Service, NIM) \ - SUB(Service, NWM) \ - SUB(Service, CAM) \ - SUB(Service, CECD) \ - SUB(Service, CFG) \ - SUB(Service, DSP) \ - SUB(Service, DLP) \ - SUB(Service, HID) \ - SUB(Service, SOC) \ - SUB(Service, IR) \ - SUB(Service, Y2R) \ - CLS(HW) \ - SUB(HW, Memory) \ - SUB(HW, LCD) \ - SUB(HW, GPU) \ - CLS(Frontend) \ - CLS(Render) \ - SUB(Render, Software) \ - SUB(Render, OpenGL) \ - CLS(Audio) \ - SUB(Audio, DSP) \ - SUB(Audio, Sink) \ - CLS(Loader) +#define ALL_LOG_CLASSES() \ + CLS(Log) \ + CLS(Common) \ + SUB(Common, Filesystem) \ + SUB(Common, Memory) \ + CLS(Core) \ + SUB(Core, ARM11) \ + SUB(Core, Timing) \ + CLS(Config) \ + CLS(Debug) \ + SUB(Debug, Emulated) \ + SUB(Debug, GPU) \ + SUB(Debug, Breakpoint) \ + SUB(Debug, GDBStub) \ + CLS(Kernel) \ + SUB(Kernel, SVC) \ + CLS(Service) \ + SUB(Service, SRV) \ + SUB(Service, FRD) \ + SUB(Service, FS) \ + SUB(Service, ERR) \ + SUB(Service, APT) \ + SUB(Service, GSP) \ + SUB(Service, AC) \ + SUB(Service, AM) \ + SUB(Service, PTM) \ + SUB(Service, LDR) \ + SUB(Service, NDM) \ + SUB(Service, NIM) \ + SUB(Service, NWM) \ + SUB(Service, CAM) \ + SUB(Service, CECD) \ + SUB(Service, CFG) \ + SUB(Service, DSP) \ + SUB(Service, DLP) \ + SUB(Service, HID) \ + SUB(Service, SOC) \ + SUB(Service, IR) \ + SUB(Service, Y2R) \ + CLS(HW) \ + SUB(HW, Memory) \ + SUB(HW, LCD) \ + SUB(HW, GPU) \ + CLS(Frontend) \ + CLS(Render) \ + SUB(Render, Software) \ + SUB(Render, OpenGL) \ + CLS(Audio) \ + SUB(Audio, DSP) \ + SUB(Audio, Sink) \ + CLS(Loader) // GetClassName is a macro defined by Windows.h, grrr... const char* GetLogClassName(Class log_class) { switch (log_class) { -#define CLS(x) case Class::x: return #x; -#define SUB(x, y) case Class::x##_##y: return #x "." #y; +#define CLS(x) \ + case Class::x: \ + return #x; +#define SUB(x, y) \ + case Class::x##_##y: \ + return #x "." #y; ALL_LOG_CLASSES() #undef CLS #undef SUB - case Class::Count: - UNREACHABLE(); + case Class::Count: + UNREACHABLE(); } } const char* GetLevelName(Level log_level) { -#define LVL(x) case Level::x: return #x +#define LVL(x) \ + case Level::x: \ + return #x switch (log_level) { LVL(Trace); LVL(Debug); @@ -90,15 +95,14 @@ const char* GetLevelName(Level log_level) { LVL(Warning); LVL(Error); LVL(Critical); - case Level::Count: - UNREACHABLE(); + case Level::Count: + UNREACHABLE(); } #undef LVL } -Entry CreateEntry(Class log_class, Level log_level, - const char* filename, unsigned int line_nr, const char* function, - const char* format, va_list args) { +Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, + const char* function, const char* format, va_list args) { using std::chrono::steady_clock; using std::chrono::duration_cast; @@ -111,7 +115,8 @@ Entry CreateEntry(Class log_class, Level log_level, entry.log_class = log_class; entry.log_level = log_level; - snprintf(formatting_buffer.data(), formatting_buffer.size(), "%s:%s:%u", filename, function, line_nr); + snprintf(formatting_buffer.data(), formatting_buffer.size(), "%s:%s:%u", filename, function, + line_nr); entry.location = std::string(formatting_buffer.data()); vsnprintf(formatting_buffer.data(), formatting_buffer.size(), format, args); @@ -126,19 +131,16 @@ void SetFilter(Filter* new_filter) { filter = new_filter; } -void LogMessage(Class log_class, Level log_level, - const char* filename, unsigned int line_nr, const char* function, - const char* format, ...) { +void LogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_nr, + const char* function, const char* format, ...) { if (filter != nullptr && !filter->CheckMessage(log_class, log_level)) return; va_list args; va_start(args, format); - Entry entry = CreateEntry(log_class, log_level, - filename, line_nr, function, format, args); + Entry entry = CreateEntry(log_class, log_level, filename, line_nr, function, format, args); va_end(args); PrintColoredMessage(entry); } - } diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h index 795d42ebd..c4fe2acbf 100644 --- a/src/common/logging/backend.h +++ b/src/common/logging/backend.h @@ -8,7 +8,6 @@ #include <cstdarg> #include <string> #include <utility> - #include "common/logging/log.h" namespace Log { @@ -44,10 +43,8 @@ const char* GetLogClassName(Class log_class); const char* GetLevelName(Level log_level); /// Creates a log entry by formatting the given source location, and message. -Entry CreateEntry(Class log_class, Level log_level, - const char* filename, unsigned int line_nr, const char* function, - const char* format, va_list args); +Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr, + const char* function, const char* format, va_list args); void SetFilter(Filter* filter); - } diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp index 55cc8888a..12e5bb45d 100644 --- a/src/common/logging/filter.cpp +++ b/src/common/logging/filter.cpp @@ -3,9 +3,8 @@ // Refer to the license.txt file included. #include <algorithm> - -#include "common/logging/filter.h" #include "common/logging/backend.h" +#include "common/logging/filter.h" #include "common/string_util.h" namespace Log { @@ -63,11 +62,11 @@ static Class GetClassByName(const It begin, const It end) { } bool Filter::ParseFilterRule(const std::string::const_iterator begin, - const std::string::const_iterator end) { + const std::string::const_iterator end) { auto level_separator = std::find(begin, end, ':'); if (level_separator == end) { LOG_ERROR(Log, "Invalid log filter. Must specify a log level after `:`: %s", - std::string(begin, end).c_str()); + std::string(begin, end).c_str()); return false; } @@ -95,5 +94,4 @@ bool Filter::ParseFilterRule(const std::string::const_iterator begin, bool Filter::CheckMessage(Class log_class, Level level) const { return static_cast<u8>(level) >= static_cast<u8>(class_levels[static_cast<size_t>(log_class)]); } - } diff --git a/src/common/logging/filter.h b/src/common/logging/filter.h index a2b4eca43..b51df61de 100644 --- a/src/common/logging/filter.h +++ b/src/common/logging/filter.h @@ -7,7 +7,6 @@ #include <array> #include <cstddef> #include <string> - #include "common/logging/log.h" namespace Log { @@ -42,7 +41,8 @@ public: * - `Service.FS:Trace` -- Sets the level of the Service.FS class to Trace. */ void ParseFilterString(const std::string& filter_str); - bool ParseFilterRule(const std::string::const_iterator start, const std::string::const_iterator end); + bool ParseFilterRule(const std::string::const_iterator start, + const std::string::const_iterator end); /// Matches class/level combination against the filter, returning true if it passed. bool CheckMessage(Class log_class, Level level) const; @@ -50,5 +50,4 @@ public: private: std::array<Level, (size_t)Class::Count> class_levels; }; - } diff --git a/src/common/logging/log.h b/src/common/logging/log.h index c6910b1c7..a4b4750de 100644 --- a/src/common/logging/log.h +++ b/src/common/logging/log.h @@ -28,71 +28,73 @@ typedef u8 ClassType; /** * Specifies the sub-system that generated the log message. * - * @note If you add a new entry here, also add a corresponding one to `ALL_LOG_CLASSES` in backend.cpp. + * @note If you add a new entry here, also add a corresponding one to `ALL_LOG_CLASSES` in + * backend.cpp. */ enum class Class : ClassType { - Log, ///< Messages about the log system itself - Common, ///< Library routines - Common_Filesystem, ///< Filesystem interface library - Common_Memory, ///< Memory mapping and management functions - Core, ///< LLE emulation core - Core_ARM11, ///< ARM11 CPU core - Core_Timing, ///< CoreTiming functions - Config, ///< Emulator configuration (including commandline) - Debug, ///< Debugging tools - Debug_Emulated, ///< Debug messages from the emulated programs - Debug_GPU, ///< GPU debugging tools - Debug_Breakpoint, ///< Logging breakpoints and watchpoints - Debug_GDBStub, ///< GDB Stub - Kernel, ///< The HLE implementation of the CTR kernel - Kernel_SVC, ///< Kernel system calls - Service, ///< HLE implementation of system services. Each major service - /// should have its own subclass. - Service_SRV, ///< The SRV (Service Directory) implementation - Service_FRD, ///< The FRD (Friends) service - Service_FS, ///< The FS (Filesystem) service implementation - Service_ERR, ///< The ERR (Error) port implementation - Service_APT, ///< The APT (Applets) service - Service_GSP, ///< The GSP (GPU control) service - Service_AC, ///< The AC (WiFi status) service - Service_AM, ///< The AM (Application manager) service - Service_PTM, ///< The PTM (Power status & misc.) service - Service_LDR, ///< The LDR (3ds dll loader) service - Service_NDM, ///< The NDM (Network daemon manager) service - Service_NIM, ///< The NIM (Network interface manager) service - Service_NWM, ///< The NWM (Network wlan manager) service - Service_CAM, ///< The CAM (Camera) service - Service_CECD, ///< The CECD (StreetPass) service - Service_CFG, ///< The CFG (Configuration) service - Service_DSP, ///< The DSP (DSP control) service - Service_DLP, ///< The DLP (Download Play) service - Service_HID, ///< The HID (Human interface device) service - Service_SOC, ///< The SOC (Socket) service - Service_IR, ///< The IR service - Service_Y2R, ///< The Y2R (YUV to RGB conversion) service - HW, ///< Low-level hardware emulation - HW_Memory, ///< Memory-map and address translation - HW_LCD, ///< LCD register emulation - HW_GPU, ///< GPU control emulation - Frontend, ///< Emulator UI - Render, ///< Emulator video output and hardware acceleration - Render_Software, ///< Software renderer backend - Render_OpenGL, ///< OpenGL backend - Audio, ///< Audio emulation - Audio_DSP, ///< The HLE implementation of the DSP - Audio_Sink, ///< Emulator audio output backend - Loader, ///< ROM loader + Log, ///< Messages about the log system itself + Common, ///< Library routines + Common_Filesystem, ///< Filesystem interface library + Common_Memory, ///< Memory mapping and management functions + Core, ///< LLE emulation core + Core_ARM11, ///< ARM11 CPU core + Core_Timing, ///< CoreTiming functions + Config, ///< Emulator configuration (including commandline) + Debug, ///< Debugging tools + Debug_Emulated, ///< Debug messages from the emulated programs + Debug_GPU, ///< GPU debugging tools + Debug_Breakpoint, ///< Logging breakpoints and watchpoints + Debug_GDBStub, ///< GDB Stub + Kernel, ///< The HLE implementation of the CTR kernel + Kernel_SVC, ///< Kernel system calls + Service, ///< HLE implementation of system services. Each major service + /// should have its own subclass. + Service_SRV, ///< The SRV (Service Directory) implementation + Service_FRD, ///< The FRD (Friends) service + Service_FS, ///< The FS (Filesystem) service implementation + Service_ERR, ///< The ERR (Error) port implementation + Service_APT, ///< The APT (Applets) service + Service_GSP, ///< The GSP (GPU control) service + Service_AC, ///< The AC (WiFi status) service + Service_AM, ///< The AM (Application manager) service + Service_PTM, ///< The PTM (Power status & misc.) service + Service_LDR, ///< The LDR (3ds dll loader) service + Service_NDM, ///< The NDM (Network daemon manager) service + Service_NIM, ///< The NIM (Network interface manager) service + Service_NWM, ///< The NWM (Network wlan manager) service + Service_CAM, ///< The CAM (Camera) service + Service_CECD, ///< The CECD (StreetPass) service + Service_CFG, ///< The CFG (Configuration) service + Service_DSP, ///< The DSP (DSP control) service + Service_DLP, ///< The DLP (Download Play) service + Service_HID, ///< The HID (Human interface device) service + Service_SOC, ///< The SOC (Socket) service + Service_IR, ///< The IR service + Service_Y2R, ///< The Y2R (YUV to RGB conversion) service + HW, ///< Low-level hardware emulation + HW_Memory, ///< Memory-map and address translation + HW_LCD, ///< LCD register emulation + HW_GPU, ///< GPU control emulation + Frontend, ///< Emulator UI + Render, ///< Emulator video output and hardware acceleration + Render_Software, ///< Software renderer backend + Render_OpenGL, ///< OpenGL backend + Audio, ///< Audio emulation + Audio_DSP, ///< The HLE implementation of the DSP + Audio_Sink, ///< Emulator audio output backend + Loader, ///< ROM loader Count ///< Total number of logging classes }; /// Logs a message to the global logger. -void LogMessage(Class log_class, Level log_level, - const char* filename, unsigned int line_nr, const char* function, +void LogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_nr, + const char* function, #ifdef _MSC_VER - _Printf_format_string_ + _Printf_format_string_ #endif - const char* format, ...) + const char* format, + ...) #ifdef __GNUC__ __attribute__((format(printf, 6, 7))) #endif @@ -100,17 +102,23 @@ void LogMessage(Class log_class, Level log_level, } // namespace Log -#define LOG_GENERIC(log_class, log_level, ...) \ +#define LOG_GENERIC(log_class, log_level, ...) \ ::Log::LogMessage(log_class, log_level, __FILE__, __LINE__, __func__, __VA_ARGS__) #ifdef _DEBUG -#define LOG_TRACE( log_class, ...) LOG_GENERIC(::Log::Class::log_class, ::Log::Level::Trace, __VA_ARGS__) +#define LOG_TRACE(log_class, ...) \ + LOG_GENERIC(::Log::Class::log_class, ::Log::Level::Trace, __VA_ARGS__) #else -#define LOG_TRACE( log_class, ...) (void(0)) +#define LOG_TRACE(log_class, ...) (void(0)) #endif -#define LOG_DEBUG( log_class, ...) LOG_GENERIC(::Log::Class::log_class, ::Log::Level::Debug, __VA_ARGS__) -#define LOG_INFO( log_class, ...) LOG_GENERIC(::Log::Class::log_class, ::Log::Level::Info, __VA_ARGS__) -#define LOG_WARNING( log_class, ...) LOG_GENERIC(::Log::Class::log_class, ::Log::Level::Warning, __VA_ARGS__) -#define LOG_ERROR( log_class, ...) LOG_GENERIC(::Log::Class::log_class, ::Log::Level::Error, __VA_ARGS__) -#define LOG_CRITICAL(log_class, ...) LOG_GENERIC(::Log::Class::log_class, ::Log::Level::Critical, __VA_ARGS__) +#define LOG_DEBUG(log_class, ...) \ + LOG_GENERIC(::Log::Class::log_class, ::Log::Level::Debug, __VA_ARGS__) +#define LOG_INFO(log_class, ...) \ + LOG_GENERIC(::Log::Class::log_class, ::Log::Level::Info, __VA_ARGS__) +#define LOG_WARNING(log_class, ...) \ + LOG_GENERIC(::Log::Class::log_class, ::Log::Level::Warning, __VA_ARGS__) +#define LOG_ERROR(log_class, ...) \ + LOG_GENERIC(::Log::Class::log_class, ::Log::Level::Error, __VA_ARGS__) +#define LOG_CRITICAL(log_class, ...) \ + LOG_GENERIC(::Log::Class::log_class, ::Log::Level::Critical, __VA_ARGS__) diff --git a/src/common/logging/text_formatter.cpp b/src/common/logging/text_formatter.cpp index de195b0f7..d61c1696b 100644 --- a/src/common/logging/text_formatter.cpp +++ b/src/common/logging/text_formatter.cpp @@ -6,16 +6,15 @@ #include <cstdio> #ifdef _WIN32 -# define WIN32_LEAN_AND_MEAN -# include <Windows.h> +#define WIN32_LEAN_AND_MEAN +#include <Windows.h> #endif +#include "common/assert.h" +#include "common/common_funcs.h" #include "common/logging/backend.h" #include "common/logging/log.h" #include "common/logging/text_formatter.h" - -#include "common/assert.h" -#include "common/common_funcs.h" #include "common/string_util.h" namespace Log { @@ -44,15 +43,14 @@ const char* TrimSourcePath(const char* path, const char* root) { } void FormatLogMessage(const Entry& entry, char* out_text, size_t text_len) { - unsigned int time_seconds = static_cast<unsigned int>(entry.timestamp.count() / 1000000); + unsigned int time_seconds = static_cast<unsigned int>(entry.timestamp.count() / 1000000); unsigned int time_fractional = static_cast<unsigned int>(entry.timestamp.count() % 1000000); const char* class_name = GetLogClassName(entry.log_class); const char* level_name = GetLevelName(entry.log_level); - snprintf(out_text, text_len, "[%4u.%06u] %s <%s> %s: %s", - time_seconds, time_fractional, class_name, level_name, - TrimSourcePath(entry.location.c_str()), entry.message.c_str()); + snprintf(out_text, text_len, "[%4u.%06u] %s <%s> %s: %s", time_seconds, time_fractional, + class_name, level_name, TrimSourcePath(entry.location.c_str()), entry.message.c_str()); } void PrintMessage(const Entry& entry) { @@ -72,38 +70,50 @@ void PrintColoredMessage(const Entry& entry) { WORD color = 0; switch (entry.log_level) { case Level::Trace: // Grey - color = FOREGROUND_INTENSITY; break; + color = FOREGROUND_INTENSITY; + break; case Level::Debug: // Cyan - color = FOREGROUND_GREEN | FOREGROUND_BLUE; break; + color = FOREGROUND_GREEN | FOREGROUND_BLUE; + break; case Level::Info: // Bright gray - color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; break; + color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; + break; case Level::Warning: // Bright yellow - color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; break; + color = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; + break; case Level::Error: // Bright red - color = FOREGROUND_RED | FOREGROUND_INTENSITY; break; + color = FOREGROUND_RED | FOREGROUND_INTENSITY; + break; case Level::Critical: // Bright magenta - color = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY; break; + color = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY; + break; case Level::Count: UNREACHABLE(); } SetConsoleTextAttribute(console_handle, color); #else -# define ESC "\x1b" +#define ESC "\x1b" const char* color = ""; switch (entry.log_level) { case Level::Trace: // Grey - color = ESC "[1;30m"; break; + color = ESC "[1;30m"; + break; case Level::Debug: // Cyan - color = ESC "[0;36m"; break; + color = ESC "[0;36m"; + break; case Level::Info: // Bright gray - color = ESC "[0;37m"; break; + color = ESC "[0;37m"; + break; case Level::Warning: // Bright yellow - color = ESC "[1;33m"; break; + color = ESC "[1;33m"; + break; case Level::Error: // Bright red - color = ESC "[1;31m"; break; + color = ESC "[1;31m"; + break; case Level::Critical: // Bright magenta - color = ESC "[1;35m"; break; + color = ESC "[1;35m"; + break; case Level::Count: UNREACHABLE(); } @@ -117,8 +127,7 @@ void PrintColoredMessage(const Entry& entry) { SetConsoleTextAttribute(console_handle, original_info.wAttributes); #else fputs(ESC "[0m", stderr); -# undef ESC +#undef ESC #endif } - } diff --git a/src/common/logging/text_formatter.h b/src/common/logging/text_formatter.h index 5b82f043f..0da102bc6 100644 --- a/src/common/logging/text_formatter.h +++ b/src/common/logging/text_formatter.h @@ -28,5 +28,4 @@ void FormatLogMessage(const Entry& entry, char* out_text, size_t text_len); void PrintMessage(const Entry& entry); /// Prints the same message as `PrintMessage`, but colored acoording to the severity level. void PrintColoredMessage(const Entry& entry); - } diff --git a/src/common/math_util.h b/src/common/math_util.h index d44b06e74..41d89666c 100644 --- a/src/common/math_util.h +++ b/src/common/math_util.h @@ -8,22 +8,20 @@ #include <cstdlib> #include <type_traits> -namespace MathUtil -{ +namespace MathUtil { -inline bool IntervalsIntersect(unsigned start0, unsigned length0, unsigned start1, unsigned length1) { +inline bool IntervalsIntersect(unsigned start0, unsigned length0, unsigned start1, + unsigned length1) { return (std::max(start0, start1) < std::min(start0 + length0, start1 + length1)); } -template<typename T> -inline T Clamp(const T val, const T& min, const T& max) -{ +template <typename T> +inline T Clamp(const T val, const T& min, const T& max) { return std::max(min, std::min(max, val)); } -template<class T> -struct Rectangle -{ +template <class T> +struct Rectangle { T left; T top; T right; @@ -31,10 +29,15 @@ struct Rectangle Rectangle() {} - Rectangle(T left, T top, T right, T bottom) : left(left), top(top), right(right), bottom(bottom) {} + Rectangle(T left, T top, T right, T bottom) + : left(left), top(top), right(right), bottom(bottom) {} - T GetWidth() const { return std::abs(static_cast<typename std::make_signed<T>::type>(right - left)); } - T GetHeight() const { return std::abs(static_cast<typename std::make_signed<T>::type>(bottom - top)); } + T GetWidth() const { + return std::abs(static_cast<typename std::make_signed<T>::type>(right - left)); + } + T GetHeight() const { + return std::abs(static_cast<typename std::make_signed<T>::type>(bottom - top)); + } }; -} // namespace MathUtil +} // namespace MathUtil diff --git a/src/common/memory_util.cpp b/src/common/memory_util.cpp index 07c7f79c8..c19729b21 100644 --- a/src/common/memory_util.cpp +++ b/src/common/memory_util.cpp @@ -2,31 +2,30 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. - #include "common/logging/log.h" #include "common/memory_util.h" #ifdef _WIN32 - #include <windows.h> - #include <psapi.h> - #include "common/common_funcs.h" - #include "common/string_util.h" +#include <windows.h> +// Windows.h needs to be included before psapi.h +#include <psapi.h> +#include "common/common_funcs.h" +#include "common/string_util.h" #else - #include <cstdlib> - #include <sys/mman.h> +#include <cstdlib> +#include <sys/mman.h> #endif #if !defined(_WIN32) && defined(ARCHITECTURE_X64) && !defined(MAP_32BIT) #include <unistd.h> -#define PAGE_MASK (getpagesize() - 1) +#define PAGE_MASK (getpagesize() - 1) #define round_page(x) ((((unsigned long)(x)) + PAGE_MASK) & ~(PAGE_MASK)) #endif // This is purposely not a full wrapper for virtualalloc/mmap, but it // provides exactly the primitive operations that Dolphin needs. -void* AllocateExecutableMemory(size_t size, bool low) -{ +void* AllocateExecutableMemory(size_t size, bool low) { #if defined(_WIN32) void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); #else @@ -39,31 +38,27 @@ void* AllocateExecutableMemory(size_t size, bool low) // effect of discarding already mapped pages that happen to be in the // requested virtual memory range (such as the emulated RAM, sometimes). if (low && (!map_hint)) - map_hint = (char*)round_page(512*1024*1024); /* 0.5 GB rounded up to the next page */ + map_hint = (char*)round_page(512 * 1024 * 1024); /* 0.5 GB rounded up to the next page */ #endif - void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_ANON | MAP_PRIVATE + void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE #if defined(ARCHITECTURE_X64) && defined(MAP_32BIT) - | (low ? MAP_32BIT : 0) + | (low ? MAP_32BIT : 0) #endif - , -1, 0); + , + -1, 0); #endif /* defined(_WIN32) */ #ifdef _WIN32 - if (ptr == nullptr) - { + if (ptr == nullptr) { #else - if (ptr == MAP_FAILED) - { + if (ptr == MAP_FAILED) { ptr = nullptr; #endif LOG_ERROR(Common_Memory, "Failed to allocate executable memory"); } #if !defined(_WIN32) && defined(ARCHITECTURE_X64) && !defined(MAP_32BIT) - else - { - if (low) - { + else { + if (low) { map_hint += size; map_hint = (char*)round_page(map_hint); /* round up to the next page */ } @@ -78,13 +73,11 @@ void* AllocateExecutableMemory(size_t size, bool low) return ptr; } -void* AllocateMemoryPages(size_t size) -{ +void* AllocateMemoryPages(size_t size) { #ifdef _WIN32 void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_READWRITE); #else - void* ptr = mmap(nullptr, size, PROT_READ | PROT_WRITE, - MAP_ANON | MAP_PRIVATE, -1, 0); + void* ptr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); if (ptr == MAP_FAILED) ptr = nullptr; @@ -96,10 +89,9 @@ void* AllocateMemoryPages(size_t size) return ptr; } -void* AllocateAlignedMemory(size_t size,size_t alignment) -{ +void* AllocateAlignedMemory(size_t size, size_t alignment) { #ifdef _WIN32 - void* ptr = _aligned_malloc(size,alignment); + void* ptr = _aligned_malloc(size, alignment); #else void* ptr = nullptr; #ifdef ANDROID @@ -116,10 +108,8 @@ void* AllocateAlignedMemory(size_t size,size_t alignment) return ptr; } -void FreeMemoryPages(void* ptr, size_t size) -{ - if (ptr) - { +void FreeMemoryPages(void* ptr, size_t size) { + if (ptr) { #ifdef _WIN32 if (!VirtualFree(ptr, 0, MEM_RELEASE)) LOG_ERROR(Common_Memory, "FreeMemoryPages failed!\n%s", GetLastErrorMsg()); @@ -129,20 +119,17 @@ void FreeMemoryPages(void* ptr, size_t size) } } -void FreeAlignedMemory(void* ptr) -{ - if (ptr) - { +void FreeAlignedMemory(void* ptr) { + if (ptr) { #ifdef _WIN32 - _aligned_free(ptr); + _aligned_free(ptr); #else - free(ptr); + free(ptr); #endif } } -void WriteProtectMemory(void* ptr, size_t size, bool allowExecute) -{ +void WriteProtectMemory(void* ptr, size_t size, bool allowExecute) { #ifdef _WIN32 DWORD oldValue; if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue)) @@ -152,19 +139,19 @@ void WriteProtectMemory(void* ptr, size_t size, bool allowExecute) #endif } -void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute) -{ +void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute) { #ifdef _WIN32 DWORD oldValue; - if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, &oldValue)) + if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, + &oldValue)) LOG_ERROR(Common_Memory, "UnWriteProtectMemory failed!\n%s", GetLastErrorMsg()); #else - mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_WRITE | PROT_EXEC) : PROT_WRITE | PROT_READ); + mprotect(ptr, size, + allowExecute ? (PROT_READ | PROT_WRITE | PROT_EXEC) : PROT_WRITE | PROT_READ); #endif } -std::string MemUsage() -{ +std::string MemUsage() { #ifdef _WIN32 #pragma comment(lib, "psapi") DWORD processID = GetCurrentProcessId(); @@ -175,10 +162,12 @@ std::string MemUsage() // Print information about the memory usage of the process. hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID); - if (nullptr == hProcess) return "MemUsage Error"; + if (nullptr == hProcess) + return "MemUsage Error"; if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) - Ret = Common::StringFromFormat("%s K", Common::ThousandSeparate(pmc.WorkingSetSize / 1024, 7).c_str()); + Ret = Common::StringFromFormat( + "%s K", Common::ThousandSeparate(pmc.WorkingSetSize / 1024, 7).c_str()); CloseHandle(hProcess); return Ret; diff --git a/src/common/memory_util.h b/src/common/memory_util.h index 9bf37c44f..76ca5a30c 100644 --- a/src/common/memory_util.h +++ b/src/common/memory_util.h @@ -10,10 +10,12 @@ void* AllocateExecutableMemory(size_t size, bool low = true); void* AllocateMemoryPages(size_t size); void FreeMemoryPages(void* ptr, size_t size); -void* AllocateAlignedMemory(size_t size,size_t alignment); +void* AllocateAlignedMemory(size_t size, size_t alignment); void FreeAlignedMemory(void* ptr); void WriteProtectMemory(void* ptr, size_t size, bool executable = false); void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute = false); std::string MemUsage(); -inline int GetPageSize() { return 4096; } +inline int GetPageSize() { + return 4096; +} diff --git a/src/common/microprofile.h b/src/common/microprofile.h index 670a58fe5..54e7f3cc4 100644 --- a/src/common/microprofile.h +++ b/src/common/microprofile.h @@ -13,7 +13,7 @@ #define MICROPROFILE_WEBSERVER 0 #define MICROPROFILE_GPU_TIMERS 0 // TODO: Implement timer queries when we upgrade to OpenGL 3.3 #define MICROPROFILE_CONTEXT_SWITCH_TRACE 0 -#define MICROPROFILE_PER_THREAD_BUFFER_SIZE (2048<<13) // 16 MB +#define MICROPROFILE_PER_THREAD_BUFFER_SIZE (2048 << 13) // 16 MB #ifdef _WIN32 // This isn't defined by the standard library in MSVC2015 diff --git a/src/common/misc.cpp b/src/common/misc.cpp index d2a049b63..7be2235b0 100644 --- a/src/common/misc.cpp +++ b/src/common/misc.cpp @@ -3,7 +3,6 @@ // Refer to the license.txt file included. #include <cstddef> - #ifdef _WIN32 #include <windows.h> #else @@ -12,23 +11,21 @@ #endif // Neither Android nor OS X support TLS -#if defined(__APPLE__) || (ANDROID && __clang__) +#if defined(__APPLE__) || (ANDROID && __clang__) #define __thread #endif // Generic function to get last error message. // Call directly after the command or use the error num. // This function might change the error code. -const char* GetLastErrorMsg() -{ +const char* GetLastErrorMsg() { static const size_t buff_size = 255; #ifdef _WIN32 static __declspec(thread) char err_str[buff_size] = {}; FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - err_str, buff_size, nullptr); + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err_str, buff_size, nullptr); #else static __thread char err_str[buff_size] = {}; diff --git a/src/common/platform.h b/src/common/platform.h index 9ba4db11b..c62fb7c8f 100644 --- a/src/common/platform.h +++ b/src/common/platform.h @@ -28,7 +28,7 @@ // Platform detection #if defined(ARCHITECTURE_x86_64) || defined(__aarch64__) - #define EMU_ARCH_BITS 64 +#define EMU_ARCH_BITS 64 #elif defined(__i386) || defined(_M_IX86) || defined(__arm__) || defined(_M_ARM) - #define EMU_ARCH_BITS 32 +#define EMU_ARCH_BITS 32 #endif diff --git a/src/common/profiler.cpp b/src/common/profiler.cpp index 49eb3f40c..b40e7205d 100644 --- a/src/common/profiler.cpp +++ b/src/common/profiler.cpp @@ -5,7 +5,6 @@ #include <algorithm> #include <cstddef> #include <vector> - #include "common/assert.h" #include "common/profiler_reporting.h" #include "common/synchronized_wrapper.h" @@ -14,8 +13,7 @@ namespace Common { namespace Profiling { ProfilingManager::ProfilingManager() - : last_frame_end(Clock::now()), this_frame_start(Clock::now()) { -} + : last_frame_end(Clock::now()), this_frame_start(Clock::now()) {} void ProfilingManager::BeginFrame() { this_frame_start = Clock::now(); @@ -31,7 +29,7 @@ void ProfilingManager::FinishFrame() { } TimingResultsAggregator::TimingResultsAggregator(size_t window_size) - : max_window_size(window_size), window_size(0) { + : max_window_size(window_size), window_size(0) { interframe_times.resize(window_size, Duration::zero()); frame_times.resize(window_size, Duration::zero()); } diff --git a/src/common/profiler_reporting.h b/src/common/profiler_reporting.h index fa1ac883f..e9ce6d41c 100644 --- a/src/common/profiler_reporting.h +++ b/src/common/profiler_reporting.h @@ -7,7 +7,6 @@ #include <chrono> #include <cstddef> #include <vector> - #include "common/synchronized_wrapper.h" namespace Common { diff --git a/src/common/scope_exit.h b/src/common/scope_exit.h index 08f09a8c8..072ab285d 100644 --- a/src/common/scope_exit.h +++ b/src/common/scope_exit.h @@ -4,20 +4,24 @@ #pragma once -#include "common/common_funcs.h" #include <utility> +#include "common/common_funcs.h" namespace detail { - template <typename Func> - struct ScopeExitHelper { - explicit ScopeExitHelper(Func&& func) : func(std::move(func)) {} - ~ScopeExitHelper() { func(); } +template <typename Func> +struct ScopeExitHelper { + explicit ScopeExitHelper(Func&& func) : func(std::move(func)) {} + ~ScopeExitHelper() { + func(); + } - Func func; - }; + Func func; +}; - template <typename Func> - ScopeExitHelper<Func> ScopeExit(Func&& func) { return ScopeExitHelper<Func>(std::move(func)); } +template <typename Func> +ScopeExitHelper<Func> ScopeExit(Func&& func) { + return ScopeExitHelper<Func>(std::move(func)); +} } /** diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp index f0aa072db..596ae01bf 100644 --- a/src/common/string_util.cpp +++ b/src/common/string_util.cpp @@ -8,17 +8,15 @@ #include <cstdlib> #include <cstring> #include <boost/range/algorithm/transform.hpp> - #include "common/common_paths.h" #include "common/logging/log.h" #include "common/string_util.h" - #ifdef _MSC_VER - #include <Windows.h> - #include <codecvt> - #include "common/common_funcs.h" +#include <codecvt> +#include <Windows.h> +#include "common/common_funcs.h" #else - #include <iconv.h> +#include <iconv.h> #endif namespace Common { @@ -36,9 +34,8 @@ std::string ToUpper(std::string str) { } // faster than sscanf -bool AsciiToHex(const char* _szValue, u32& result) -{ - char *endptr = nullptr; +bool AsciiToHex(const char* _szValue, u32& result) { + char* endptr = nullptr; const u32 value = strtoul(_szValue, &endptr, 16); if (!endptr || *endptr) @@ -48,8 +45,7 @@ bool AsciiToHex(const char* _szValue, u32& result) return true; } -bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list args) -{ +bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list args) { int writtenCount; #ifdef _MSC_VER @@ -84,22 +80,18 @@ bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list ar writtenCount = vsnprintf(out, outsize, format, args); #endif - if (writtenCount > 0 && writtenCount < outsize) - { + if (writtenCount > 0 && writtenCount < outsize) { out[writtenCount] = '\0'; return true; - } - else - { + } else { out[outsize - 1] = '\0'; return false; } } -std::string StringFromFormat(const char* format, ...) -{ +std::string StringFromFormat(const char* format, ...) { va_list args; - char *buf = nullptr; + char* buf = nullptr; #ifdef _WIN32 int required = 0; @@ -124,21 +116,17 @@ std::string StringFromFormat(const char* format, ...) } // For Debugging. Read out an u8 array. -std::string ArrayToString(const u8 *data, u32 size, int line_len, bool spaces) -{ +std::string ArrayToString(const u8* data, u32 size, int line_len, bool spaces) { std::ostringstream oss; oss << std::setfill('0') << std::hex; - for (int line = 0; size; ++data, --size) - { + for (int line = 0; size; ++data, --size) { oss << std::setw(2) << (int)*data; - if (line_len == ++line) - { + if (line_len == ++line) { oss << '\n'; line = 0; - } - else if (spaces) + } else if (spaces) oss << ' '; } @@ -146,8 +134,7 @@ std::string ArrayToString(const u8 *data, u32 size, int line_len, bool spaces) } // Turns " hej " into "hej". Also handles tabs. -std::string StripSpaces(const std::string &str) -{ +std::string StripSpaces(const std::string& str) { const size_t s = str.find_first_not_of(" \t\r\n"); if (str.npos != s) @@ -159,17 +146,15 @@ std::string StripSpaces(const std::string &str) // "\"hello\"" is turned to "hello" // This one assumes that the string has already been space stripped in both // ends, as done by StripSpaces above, for example. -std::string StripQuotes(const std::string& s) -{ +std::string StripQuotes(const std::string& s) { if (s.size() && '\"' == s[0] && '\"' == *s.rbegin()) return s.substr(1, s.size() - 2); else return s; } -bool TryParse(const std::string &str, u32 *const output) -{ - char *endptr = nullptr; +bool TryParse(const std::string& str, u32* const output) { + char* endptr = nullptr; // Reset errno to a value other than ERANGE errno = 0; @@ -183,8 +168,7 @@ bool TryParse(const std::string &str, u32 *const output) return false; #if ULONG_MAX > UINT_MAX - if (value >= 0x100000000ull - && value <= 0xFFFFFFFF00000000ull) + if (value >= 0x100000000ull && value <= 0xFFFFFFFF00000000ull) return false; #endif @@ -192,8 +176,7 @@ bool TryParse(const std::string &str, u32 *const output) return true; } -bool TryParse(const std::string &str, bool *const output) -{ +bool TryParse(const std::string& str, bool* const output) { if ("1" == str || "true" == ToLower(str)) *output = true; else if ("0" == str || "false" == ToLower(str)) @@ -204,22 +187,21 @@ bool TryParse(const std::string &str, bool *const output) return true; } -std::string StringFromBool(bool value) -{ +std::string StringFromBool(bool value) { return value ? "True" : "False"; } -bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _pFilename, std::string* _pExtension) -{ +bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _pFilename, + std::string* _pExtension) { if (full_path.empty()) return false; size_t dir_end = full_path.find_last_of("/" - // windows needs the : included for something like just "C:" to be considered a directory +// windows needs the : included for something like just "C:" to be considered a directory #ifdef _WIN32 - ":" + ":" #endif - ); + ); if (std::string::npos == dir_end) dir_end = 0; else @@ -241,8 +223,8 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _ return true; } -void BuildCompleteFilename(std::string& _CompleteFilename, const std::string& _Path, const std::string& _Filename) -{ +void BuildCompleteFilename(std::string& _CompleteFilename, const std::string& _Path, + const std::string& _Filename) { _CompleteFilename = _Path; // check for seperator @@ -253,8 +235,7 @@ void BuildCompleteFilename(std::string& _CompleteFilename, const std::string& _P _CompleteFilename += _Filename; } -void SplitString(const std::string& str, const char delim, std::vector<std::string>& output) -{ +void SplitString(const std::string& str, const char delim, std::vector<std::string>& output) { std::istringstream iss(str); output.resize(1); @@ -264,8 +245,7 @@ void SplitString(const std::string& str, const char delim, std::vector<std::stri output.pop_back(); } -std::string TabsToSpaces(int tab_size, const std::string &in) -{ +std::string TabsToSpaces(int tab_size, const std::string& in) { const std::string spaces(tab_size, ' '); std::string out(in); @@ -276,15 +256,13 @@ std::string TabsToSpaces(int tab_size, const std::string &in) return out; } -std::string ReplaceAll(std::string result, const std::string& src, const std::string& dest) -{ +std::string ReplaceAll(std::string result, const std::string& src, const std::string& dest) { size_t pos = 0; if (src == dest) return result; - while ((pos = result.find(src, pos)) != std::string::npos) - { + while ((pos = result.find(src, pos)) != std::string::npos) { result.replace(pos, src.size(), dest); pos += dest.length(); } @@ -294,8 +272,7 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st #ifdef _MSC_VER -std::string UTF16ToUTF8(const std::u16string& input) -{ +std::string UTF16ToUTF8(const std::u16string& input) { #if _MSC_VER >= 1900 // Workaround for missing char16_t/char32_t instantiations in MSVC2015 std::wstring_convert<std::codecvt_utf8_utf16<__int16>, __int16> convert; @@ -307,8 +284,7 @@ std::string UTF16ToUTF8(const std::u16string& input) #endif } -std::u16string UTF8ToUTF16(const std::string& input) -{ +std::u16string UTF8ToUTF16(const std::string& input) { #if _MSC_VER >= 1900 // Workaround for missing char16_t/char32_t instantiations in MSVC2015 std::wstring_convert<std::codecvt_utf8_utf16<__int16>, __int16> convert; @@ -320,57 +296,56 @@ std::u16string UTF8ToUTF16(const std::string& input) #endif } -static std::wstring CPToUTF16(u32 code_page, const std::string& input) -{ - auto const size = MultiByteToWideChar(code_page, 0, input.data(), static_cast<int>(input.size()), nullptr, 0); +static std::wstring CPToUTF16(u32 code_page, const std::string& input) { + auto const size = + MultiByteToWideChar(code_page, 0, input.data(), static_cast<int>(input.size()), nullptr, 0); std::wstring output; output.resize(size); - if (size == 0 || size != MultiByteToWideChar(code_page, 0, input.data(), static_cast<int>(input.size()), &output[0], static_cast<int>(output.size()))) + if (size == 0 || + size != MultiByteToWideChar(code_page, 0, input.data(), static_cast<int>(input.size()), + &output[0], static_cast<int>(output.size()))) output.clear(); return output; } -std::string UTF16ToUTF8(const std::wstring& input) -{ - auto const size = WideCharToMultiByte(CP_UTF8, 0, input.data(), static_cast<int>(input.size()), nullptr, 0, nullptr, nullptr); +std::string UTF16ToUTF8(const std::wstring& input) { + auto const size = WideCharToMultiByte(CP_UTF8, 0, input.data(), static_cast<int>(input.size()), + nullptr, 0, nullptr, nullptr); std::string output; output.resize(size); - if (size == 0 || size != WideCharToMultiByte(CP_UTF8, 0, input.data(), static_cast<int>(input.size()), &output[0], static_cast<int>(output.size()), nullptr, nullptr)) + if (size == 0 || + size != WideCharToMultiByte(CP_UTF8, 0, input.data(), static_cast<int>(input.size()), + &output[0], static_cast<int>(output.size()), nullptr, nullptr)) output.clear(); return output; } -std::wstring UTF8ToUTF16W(const std::string &input) -{ +std::wstring UTF8ToUTF16W(const std::string& input) { return CPToUTF16(CP_UTF8, input); } -std::string SHIFTJISToUTF8(const std::string& input) -{ +std::string SHIFTJISToUTF8(const std::string& input) { return UTF16ToUTF8(CPToUTF16(932, input)); } -std::string CP1252ToUTF8(const std::string& input) -{ +std::string CP1252ToUTF8(const std::string& input) { return UTF16ToUTF8(CPToUTF16(1252, input)); } #else template <typename T> -static std::string CodeToUTF8(const char* fromcode, const std::basic_string<T>& input) -{ +static std::string CodeToUTF8(const char* fromcode, const std::basic_string<T>& input) { std::string result; iconv_t const conv_desc = iconv_open("UTF-8", fromcode); - if ((iconv_t)(-1) == conv_desc) - { + if ((iconv_t)(-1) == conv_desc) { LOG_ERROR(Common, "Iconv initialization failure [%s]: %s", fromcode, strerror(errno)); iconv_close(conv_desc); return {}; @@ -388,24 +363,18 @@ static std::string CodeToUTF8(const char* fromcode, const std::basic_string<T>& auto dst_buffer = &out_buffer[0]; size_t dst_bytes = out_buffer.size(); - while (0 != src_bytes) - { - size_t const iconv_result = iconv(conv_desc, (char**)(&src_buffer), &src_bytes, - &dst_buffer, &dst_bytes); + while (0 != src_bytes) { + size_t const iconv_result = + iconv(conv_desc, (char**)(&src_buffer), &src_bytes, &dst_buffer, &dst_bytes); - if (static_cast<size_t>(-1) == iconv_result) - { - if (EILSEQ == errno || EINVAL == errno) - { + if (static_cast<size_t>(-1) == iconv_result) { + if (EILSEQ == errno || EINVAL == errno) { // Try to skip the bad character - if (0 != src_bytes) - { + if (0 != src_bytes) { --src_bytes; ++src_buffer; } - } - else - { + } else { LOG_ERROR(Common, "iconv failure [%s]: %s", fromcode, strerror(errno)); break; } @@ -420,13 +389,11 @@ static std::string CodeToUTF8(const char* fromcode, const std::basic_string<T>& return result; } -std::u16string UTF8ToUTF16(const std::string& input) -{ +std::u16string UTF8ToUTF16(const std::string& input) { std::u16string result; iconv_t const conv_desc = iconv_open("UTF-16LE", "UTF-8"); - if ((iconv_t)(-1) == conv_desc) - { + if ((iconv_t)(-1) == conv_desc) { LOG_ERROR(Common, "Iconv initialization failure [UTF-8]: %s", strerror(errno)); iconv_close(conv_desc); return {}; @@ -444,24 +411,18 @@ std::u16string UTF8ToUTF16(const std::string& input) char* dst_buffer = (char*)(&out_buffer[0]); size_t dst_bytes = out_buffer.size(); - while (0 != src_bytes) - { - size_t const iconv_result = iconv(conv_desc, &src_buffer, &src_bytes, - &dst_buffer, &dst_bytes); + while (0 != src_bytes) { + size_t const iconv_result = + iconv(conv_desc, &src_buffer, &src_bytes, &dst_buffer, &dst_bytes); - if (static_cast<size_t>(-1) == iconv_result) - { - if (EILSEQ == errno || EINVAL == errno) - { + if (static_cast<size_t>(-1) == iconv_result) { + if (EILSEQ == errno || EINVAL == errno) { // Try to skip the bad character - if (0 != src_bytes) - { + if (0 != src_bytes) { --src_bytes; ++src_buffer; } - } - else - { + } else { LOG_ERROR(Common, "iconv failure [UTF-8]: %s", strerror(errno)); break; } @@ -476,32 +437,28 @@ std::u16string UTF8ToUTF16(const std::string& input) return result; } -std::string UTF16ToUTF8(const std::u16string& input) -{ +std::string UTF16ToUTF8(const std::u16string& input) { return CodeToUTF8("UTF-16LE", input); } -std::string CP1252ToUTF8(const std::string& input) -{ - //return CodeToUTF8("CP1252//TRANSLIT", input); - //return CodeToUTF8("CP1252//IGNORE", input); +std::string CP1252ToUTF8(const std::string& input) { + // return CodeToUTF8("CP1252//TRANSLIT", input); + // return CodeToUTF8("CP1252//IGNORE", input); return CodeToUTF8("CP1252", input); } -std::string SHIFTJISToUTF8(const std::string& input) -{ - //return CodeToUTF8("CP932", input); +std::string SHIFTJISToUTF8(const std::string& input) { + // return CodeToUTF8("CP932", input); return CodeToUTF8("SJIS", input); } #endif -std::string StringFromFixedZeroTerminatedBuffer(const char * buffer, size_t max_len) { +std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, size_t max_len) { size_t len = 0; while (len < max_len && buffer[len] != '\0') ++len; return std::string(buffer, len); } - } diff --git a/src/common/string_util.h b/src/common/string_util.h index 89d9f133e..075bf4ecb 100644 --- a/src/common/string_util.h +++ b/src/common/string_util.h @@ -10,7 +10,6 @@ #include <sstream> #include <string> #include <vector> - #include "common/common_types.h" namespace Common { @@ -25,9 +24,8 @@ std::string StringFromFormat(const char* format, ...); // Cheap! bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list args); -template<size_t Count> -inline void CharArrayFromFormat(char (& out)[Count], const char* format, ...) -{ +template <size_t Count> +inline void CharArrayFromFormat(char (&out)[Count], const char* format, ...) { va_list args; va_start(args, format); CharArrayFromFormatV(out, Count, format, args); @@ -35,15 +33,14 @@ inline void CharArrayFromFormat(char (& out)[Count], const char* format, ...) } // Good -std::string ArrayToString(const u8 *data, u32 size, int line_len = 20, bool spaces = true); +std::string ArrayToString(const u8* data, u32 size, int line_len = 20, bool spaces = true); -std::string StripSpaces(const std::string &s); -std::string StripQuotes(const std::string &s); +std::string StripSpaces(const std::string& s); +std::string StripQuotes(const std::string& s); // Thousand separator. Turns 12345678 into 12,345,678 template <typename I> -std::string ThousandSeparate(I value, int spaces = 0) -{ +std::string ThousandSeparate(I value, int spaces = 0) { std::ostringstream oss; // std::locale("") seems to be broken on many platforms @@ -57,35 +54,34 @@ std::string ThousandSeparate(I value, int spaces = 0) std::string StringFromBool(bool value); -bool TryParse(const std::string &str, bool *output); -bool TryParse(const std::string &str, u32 *output); +bool TryParse(const std::string& str, bool* output); +bool TryParse(const std::string& str, u32* output); template <typename N> -static bool TryParse(const std::string &str, N *const output) -{ +static bool TryParse(const std::string& str, N* const output) { std::istringstream iss(str); N tmp = 0; - if (iss >> tmp) - { + if (iss >> tmp) { *output = tmp; return true; - } - else + } else return false; } // TODO: kill this bool AsciiToHex(const char* _szValue, u32& result); -std::string TabsToSpaces(int tab_size, const std::string &in); +std::string TabsToSpaces(int tab_size, const std::string& in); void SplitString(const std::string& str, char delim, std::vector<std::string>& output); // "C:/Windows/winhelp.exe" to "C:/Windows/", "winhelp", ".exe" -bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _pFilename, std::string* _pExtension); +bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _pFilename, + std::string* _pExtension); -void BuildCompleteFilename(std::string& _CompleteFilename, const std::string& _Path, const std::string& _Filename); +void BuildCompleteFilename(std::string& _CompleteFilename, const std::string& _Path, + const std::string& _Filename); std::string ReplaceAll(std::string result, const std::string& src, const std::string& dest); std::string UTF16ToUTF8(const std::u16string& input); @@ -99,17 +95,21 @@ std::string UTF16ToUTF8(const std::wstring& input); std::wstring UTF8ToUTF16W(const std::string& str); #ifdef _UNICODE -inline std::string TStrToUTF8(const std::wstring& str) -{ return UTF16ToUTF8(str); } +inline std::string TStrToUTF8(const std::wstring& str) { + return UTF16ToUTF8(str); +} -inline std::wstring UTF8ToTStr(const std::string& str) -{ return UTF8ToUTF16W(str); } +inline std::wstring UTF8ToTStr(const std::string& str) { + return UTF8ToUTF16W(str); +} #else -inline std::string TStrToUTF8(const std::string& str) -{ return str; } +inline std::string TStrToUTF8(const std::string& str) { + return str; +} -inline std::string UTF8ToTStr(const std::string& str) -{ return str; } +inline std::string UTF8ToTStr(const std::string& str) { + return str; +} #endif #endif @@ -134,5 +134,4 @@ bool ComparePartialString(InIt begin, InIt end, const char* other) { * NUL-terminated then the string ends at max_len characters. */ std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, size_t max_len); - } diff --git a/src/common/swap.h b/src/common/swap.h index 1749bd7a4..e241c9f73 100644 --- a/src/common/swap.h +++ b/src/common/swap.h @@ -18,15 +18,13 @@ #pragma once #if defined(_MSC_VER) - #include <cstdlib> +#include <cstdlib> #elif defined(__linux__) - #include <byteswap.h> +#include <byteswap.h> #elif defined(__FreeBSD__) - #include <sys/endian.h> +#include <sys/endian.h> #endif - #include <cstring> - #include "common/common_types.h" // GCC 4.6+ @@ -61,38 +59,73 @@ namespace Common { #ifdef _MSC_VER -inline u16 swap16(u16 _data) {return _byteswap_ushort(_data);} -inline u32 swap32(u32 _data) {return _byteswap_ulong (_data);} -inline u64 swap64(u64 _data) {return _byteswap_uint64(_data);} +inline u16 swap16(u16 _data) { + return _byteswap_ushort(_data); +} +inline u32 swap32(u32 _data) { + return _byteswap_ulong(_data); +} +inline u64 swap64(u64 _data) { + return _byteswap_uint64(_data); +} #elif _M_ARM -inline u16 swap16 (u16 _data) { u32 data = _data; __asm__ ("rev16 %0, %1\n" : "=l" (data) : "l" (data)); return (u16)data;} -inline u32 swap32 (u32 _data) {__asm__ ("rev %0, %1\n" : "=l" (_data) : "l" (_data)); return _data;} -inline u64 swap64(u64 _data) {return ((u64)swap32(_data) << 32) | swap32(_data >> 32);} +inline u16 swap16(u16 _data) { + u32 data = _data; + __asm__("rev16 %0, %1\n" : "=l"(data) : "l"(data)); + return (u16)data; +} +inline u32 swap32(u32 _data) { + __asm__("rev %0, %1\n" : "=l"(_data) : "l"(_data)); + return _data; +} +inline u64 swap64(u64 _data) { + return ((u64)swap32(_data) << 32) | swap32(_data >> 32); +} #elif __linux__ -inline u16 swap16(u16 _data) {return bswap_16(_data);} -inline u32 swap32(u32 _data) {return bswap_32(_data);} -inline u64 swap64(u64 _data) {return bswap_64(_data);} +inline u16 swap16(u16 _data) { + return bswap_16(_data); +} +inline u32 swap32(u32 _data) { + return bswap_32(_data); +} +inline u64 swap64(u64 _data) { + return bswap_64(_data); +} #elif __APPLE__ -inline __attribute__((always_inline)) u16 swap16(u16 _data) -{return (_data >> 8) | (_data << 8);} -inline __attribute__((always_inline)) u32 swap32(u32 _data) -{return __builtin_bswap32(_data);} -inline __attribute__((always_inline)) u64 swap64(u64 _data) -{return __builtin_bswap64(_data);} +inline __attribute__((always_inline)) u16 swap16(u16 _data) { + return (_data >> 8) | (_data << 8); +} +inline __attribute__((always_inline)) u32 swap32(u32 _data) { + return __builtin_bswap32(_data); +} +inline __attribute__((always_inline)) u64 swap64(u64 _data) { + return __builtin_bswap64(_data); +} #elif __FreeBSD__ -inline u16 swap16(u16 _data) {return bswap16(_data);} -inline u32 swap32(u32 _data) {return bswap32(_data);} -inline u64 swap64(u64 _data) {return bswap64(_data);} +inline u16 swap16(u16 _data) { + return bswap16(_data); +} +inline u32 swap32(u32 _data) { + return bswap32(_data); +} +inline u64 swap64(u64 _data) { + return bswap64(_data); +} #else // Slow generic implementation. -inline u16 swap16(u16 data) {return (data >> 8) | (data << 8);} -inline u32 swap32(u32 data) {return (swap16(data) << 16) | swap16(data >> 16);} -inline u64 swap64(u64 data) {return ((u64)swap32(data) << 32) | swap32(data >> 32);} +inline u16 swap16(u16 data) { + return (data >> 8) | (data << 8); +} +inline u32 swap32(u32 data) { + return (swap16(data) << 16) | swap16(data >> 16); +} +inline u64 swap64(u64 data) { + return ((u64)swap32(data) << 32) | swap32(data >> 32); +} #endif inline float swapf(float f) { - static_assert(sizeof(u32) == sizeof(float), - "float must be the same size as uint32_t."); + static_assert(sizeof(u32) == sizeof(float), "float must be the same size as uint32_t."); u32 value; std::memcpy(&value, &f, sizeof(u32)); @@ -104,8 +137,7 @@ inline float swapf(float f) { } inline double swapd(double f) { - static_assert(sizeof(u64) == sizeof(double), - "double must be the same size as uint64_t."); + static_assert(sizeof(u64) == sizeof(double), "double must be the same size as uint64_t."); u64 value; std::memcpy(&value, &f, sizeof(u64)); @@ -116,8 +148,7 @@ inline double swapd(double f) { return f; } -} // Namespace Common - +} // Namespace Common template <typename T, typename F> struct swap_struct_t { @@ -129,251 +160,271 @@ protected: static T swap(T v) { return F::swap(v); } + public: T const swap() const { return swap(value); - } swap_struct_t() = default; - swap_struct_t(const T &v): value(swap(v)) {} + swap_struct_t(const T& v) : value(swap(v)) {} template <typename S> - swapped_t& operator=(const S &source) { + swapped_t& operator=(const S& source) { value = swap((T)source); return *this; } - operator s8() const { return (s8)swap(); } - operator u8() const { return (u8)swap(); } - operator s16() const { return (s16)swap(); } - operator u16() const { return (u16)swap(); } - operator s32() const { return (s32)swap(); } - operator u32() const { return (u32)swap(); } - operator s64() const { return (s64)swap(); } - operator u64() const { return (u64)swap(); } - operator float() const { return (float)swap(); } - operator double() const { return (double)swap(); } + operator s8() const { + return (s8)swap(); + } + operator u8() const { + return (u8)swap(); + } + operator s16() const { + return (s16)swap(); + } + operator u16() const { + return (u16)swap(); + } + operator s32() const { + return (s32)swap(); + } + operator u32() const { + return (u32)swap(); + } + operator s64() const { + return (s64)swap(); + } + operator u64() const { + return (u64)swap(); + } + operator float() const { + return (float)swap(); + } + operator double() const { + return (double)swap(); + } // +v - swapped_t operator +() const { + swapped_t operator+() const { return +swap(); } // -v - swapped_t operator -() const { + swapped_t operator-() const { return -swap(); } // v / 5 - swapped_t operator/(const swapped_t &i) const { + swapped_t operator/(const swapped_t& i) const { return swap() / i.swap(); } template <typename S> - swapped_t operator/(const S &i) const { + swapped_t operator/(const S& i) const { return swap() / i; } // v * 5 - swapped_t operator*(const swapped_t &i) const { + swapped_t operator*(const swapped_t& i) const { return swap() * i.swap(); } template <typename S> - swapped_t operator*(const S &i) const { + swapped_t operator*(const S& i) const { return swap() * i; } // v + 5 - swapped_t operator+(const swapped_t &i) const { + swapped_t operator+(const swapped_t& i) const { return swap() + i.swap(); } template <typename S> - swapped_t operator+(const S &i) const { + swapped_t operator+(const S& i) const { return swap() + (T)i; } // v - 5 - swapped_t operator-(const swapped_t &i) const { + swapped_t operator-(const swapped_t& i) const { return swap() - i.swap(); } template <typename S> - swapped_t operator-(const S &i) const { + swapped_t operator-(const S& i) const { return swap() - (T)i; } // v += 5 - swapped_t& operator+=(const swapped_t &i) { + swapped_t& operator+=(const swapped_t& i) { value = swap(swap() + i.swap()); return *this; } template <typename S> - swapped_t& operator+=(const S &i) { + swapped_t& operator+=(const S& i) { value = swap(swap() + (T)i); return *this; } // v -= 5 - swapped_t& operator-=(const swapped_t &i) { + swapped_t& operator-=(const swapped_t& i) { value = swap(swap() - i.swap()); return *this; } template <typename S> - swapped_t& operator-=(const S &i) { + swapped_t& operator-=(const S& i) { value = swap(swap() - (T)i); return *this; } // ++v swapped_t& operator++() { - value = swap(swap()+1); + value = swap(swap() + 1); return *this; } // --v - swapped_t& operator--() { - value = swap(swap()-1); + swapped_t& operator--() { + value = swap(swap() - 1); return *this; } // v++ swapped_t operator++(int) { swapped_t old = *this; - value = swap(swap()+1); + value = swap(swap() + 1); return old; } // v-- swapped_t operator--(int) { swapped_t old = *this; - value = swap(swap()-1); + value = swap(swap() - 1); return old; } // Comparaison // v == i - bool operator==(const swapped_t &i) const { + bool operator==(const swapped_t& i) const { return swap() == i.swap(); } template <typename S> - bool operator==(const S &i) const { + bool operator==(const S& i) const { return swap() == i; } // v != i - bool operator!=(const swapped_t &i) const { + bool operator!=(const swapped_t& i) const { return swap() != i.swap(); } template <typename S> - bool operator!=(const S &i) const { + bool operator!=(const S& i) const { return swap() != i; } // v > i - bool operator>(const swapped_t &i) const { + bool operator>(const swapped_t& i) const { return swap() > i.swap(); } template <typename S> - bool operator>(const S &i) const { + bool operator>(const S& i) const { return swap() > i; } // v < i - bool operator<(const swapped_t &i) const { + bool operator<(const swapped_t& i) const { return swap() < i.swap(); } template <typename S> - bool operator<(const S &i) const { + bool operator<(const S& i) const { return swap() < i; } // v >= i - bool operator>=(const swapped_t &i) const { + bool operator>=(const swapped_t& i) const { return swap() >= i.swap(); } template <typename S> - bool operator>=(const S &i) const { + bool operator>=(const S& i) const { return swap() >= i; } // v <= i - bool operator<=(const swapped_t &i) const { + bool operator<=(const swapped_t& i) const { return swap() <= i.swap(); } template <typename S> - bool operator<=(const S &i) const { + bool operator<=(const S& i) const { return swap() <= i; } // logical - swapped_t operator !() const { + swapped_t operator!() const { return !swap(); } // bitmath - swapped_t operator ~() const { + swapped_t operator~() const { return ~swap(); } - swapped_t operator &(const swapped_t &b) const { + swapped_t operator&(const swapped_t& b) const { return swap() & b.swap(); } template <typename S> - swapped_t operator &(const S &b) const { + swapped_t operator&(const S& b) const { return swap() & b; } - swapped_t& operator &=(const swapped_t &b) { + swapped_t& operator&=(const swapped_t& b) { value = swap(swap() & b.swap()); return *this; } template <typename S> - swapped_t& operator &=(const S b) { + swapped_t& operator&=(const S b) { value = swap(swap() & b); return *this; } - swapped_t operator |(const swapped_t &b) const { + swapped_t operator|(const swapped_t& b) const { return swap() | b.swap(); } template <typename S> - swapped_t operator |(const S &b) const { + swapped_t operator|(const S& b) const { return swap() | b; } - swapped_t& operator |=(const swapped_t &b) { + swapped_t& operator|=(const swapped_t& b) { value = swap(swap() | b.swap()); return *this; } template <typename S> - swapped_t& operator |=(const S &b) { + swapped_t& operator|=(const S& b) { value = swap(swap() | b); return *this; } - swapped_t operator ^(const swapped_t &b) const { + swapped_t operator^(const swapped_t& b) const { return swap() ^ b.swap(); } template <typename S> - swapped_t operator ^(const S &b) const { + swapped_t operator^(const S& b) const { return swap() ^ b; } - swapped_t& operator ^=(const swapped_t &b) { + swapped_t& operator^=(const swapped_t& b) { value = swap(swap() ^ b.swap()); return *this; } template <typename S> - swapped_t& operator ^=(const S &b) { + swapped_t& operator^=(const S& b) { value = swap(swap() ^ b); return *this; } template <typename S> - swapped_t operator <<(const S &b) const { + swapped_t operator<<(const S& b) const { return swap() << b; } template <typename S> - swapped_t& operator <<=(const S &b) const { + swapped_t& operator<<=(const S& b) const { value = swap(swap() << b); return *this; } template <typename S> - swapped_t operator >>(const S &b) const { + swapped_t operator>>(const S& b) const { return swap() >> b; } template <typename S> - swapped_t& operator >>=(const S &b) const { + swapped_t& operator>>=(const S& b) const { value = swap(swap() >> b); return *this; } @@ -381,129 +432,126 @@ public: // Member /** todo **/ - // Arithmetics template <typename S, typename T2, typename F2> - friend S operator+(const S &p, const swapped_t v); + friend S operator+(const S& p, const swapped_t v); template <typename S, typename T2, typename F2> - friend S operator-(const S &p, const swapped_t v); + friend S operator-(const S& p, const swapped_t v); template <typename S, typename T2, typename F2> - friend S operator/(const S &p, const swapped_t v); + friend S operator/(const S& p, const swapped_t v); template <typename S, typename T2, typename F2> - friend S operator*(const S &p, const swapped_t v); + friend S operator*(const S& p, const swapped_t v); template <typename S, typename T2, typename F2> - friend S operator%(const S &p, const swapped_t v); + friend S operator%(const S& p, const swapped_t v); // Arithmetics + assignements template <typename S, typename T2, typename F2> - friend S operator+=(const S &p, const swapped_t v); + friend S operator+=(const S& p, const swapped_t v); template <typename S, typename T2, typename F2> - friend S operator-=(const S &p, const swapped_t v); + friend S operator-=(const S& p, const swapped_t v); // Bitmath template <typename S, typename T2, typename F2> - friend S operator&(const S &p, const swapped_t v); + friend S operator&(const S& p, const swapped_t v); // Comparison template <typename S, typename T2, typename F2> - friend bool operator<(const S &p, const swapped_t v); + friend bool operator<(const S& p, const swapped_t v); template <typename S, typename T2, typename F2> - friend bool operator>(const S &p, const swapped_t v); + friend bool operator>(const S& p, const swapped_t v); template <typename S, typename T2, typename F2> - friend bool operator<=(const S &p, const swapped_t v); + friend bool operator<=(const S& p, const swapped_t v); template <typename S, typename T2, typename F2> - friend bool operator>=(const S &p, const swapped_t v); + friend bool operator>=(const S& p, const swapped_t v); template <typename S, typename T2, typename F2> - friend bool operator!=(const S &p, const swapped_t v); + friend bool operator!=(const S& p, const swapped_t v); template <typename S, typename T2, typename F2> - friend bool operator==(const S &p, const swapped_t v); + friend bool operator==(const S& p, const swapped_t v); }; - // Arithmetics template <typename S, typename T, typename F> -S operator+(const S &i, const swap_struct_t<T, F> v) { +S operator+(const S& i, const swap_struct_t<T, F> v) { return i + v.swap(); } template <typename S, typename T, typename F> -S operator-(const S &i, const swap_struct_t<T, F> v) { +S operator-(const S& i, const swap_struct_t<T, F> v) { return i - v.swap(); } template <typename S, typename T, typename F> -S operator/(const S &i, const swap_struct_t<T, F> v) { +S operator/(const S& i, const swap_struct_t<T, F> v) { return i / v.swap(); } template <typename S, typename T, typename F> -S operator*(const S &i, const swap_struct_t<T, F> v) { +S operator*(const S& i, const swap_struct_t<T, F> v) { return i * v.swap(); } template <typename S, typename T, typename F> -S operator%(const S &i, const swap_struct_t<T, F> v) { +S operator%(const S& i, const swap_struct_t<T, F> v) { return i % v.swap(); } // Arithmetics + assignements template <typename S, typename T, typename F> -S &operator+=(S &i, const swap_struct_t<T, F> v) { +S& operator+=(S& i, const swap_struct_t<T, F> v) { i += v.swap(); return i; } template <typename S, typename T, typename F> -S &operator-=(S &i, const swap_struct_t<T, F> v) { +S& operator-=(S& i, const swap_struct_t<T, F> v) { i -= v.swap(); return i; } // Logical template <typename S, typename T, typename F> -S operator&(const S &i, const swap_struct_t<T, F> v) { +S operator&(const S& i, const swap_struct_t<T, F> v) { return i & v.swap(); } template <typename S, typename T, typename F> -S operator&(const swap_struct_t<T, F> v, const S &i) { +S operator&(const swap_struct_t<T, F> v, const S& i) { return (S)(v.swap() & i); } - // Comparaison template <typename S, typename T, typename F> -bool operator<(const S &p, const swap_struct_t<T, F> v) { +bool operator<(const S& p, const swap_struct_t<T, F> v) { return p < v.swap(); } template <typename S, typename T, typename F> -bool operator>(const S &p, const swap_struct_t<T, F> v) { +bool operator>(const S& p, const swap_struct_t<T, F> v) { return p > v.swap(); } template <typename S, typename T, typename F> -bool operator<=(const S &p, const swap_struct_t<T, F> v) { +bool operator<=(const S& p, const swap_struct_t<T, F> v) { return p <= v.swap(); } template <typename S, typename T, typename F> -bool operator>=(const S &p, const swap_struct_t<T, F> v) { +bool operator>=(const S& p, const swap_struct_t<T, F> v) { return p >= v.swap(); } template <typename S, typename T, typename F> -bool operator!=(const S &p, const swap_struct_t<T, F> v) { +bool operator!=(const S& p, const swap_struct_t<T, F> v) { return p != v.swap(); } template <typename S, typename T, typename F> -bool operator==(const S &p, const swap_struct_t<T, F> v) { +bool operator==(const S& p, const swap_struct_t<T, F> v) { return p == v.swap(); } @@ -554,30 +602,30 @@ typedef s64 s64_le; typedef float float_le; typedef double double_le; -typedef swap_struct_t<u64, swap_64_t<u64> > u64_be; -typedef swap_struct_t<s64, swap_64_t<s64> > s64_be; +typedef swap_struct_t<u64, swap_64_t<u64>> u64_be; +typedef swap_struct_t<s64, swap_64_t<s64>> s64_be; -typedef swap_struct_t<u32, swap_32_t<u32> > u32_be; -typedef swap_struct_t<s32, swap_32_t<s32> > s32_be; +typedef swap_struct_t<u32, swap_32_t<u32>> u32_be; +typedef swap_struct_t<s32, swap_32_t<s32>> s32_be; -typedef swap_struct_t<u16, swap_16_t<u16> > u16_be; -typedef swap_struct_t<s16, swap_16_t<s16> > s16_be; +typedef swap_struct_t<u16, swap_16_t<u16>> u16_be; +typedef swap_struct_t<s16, swap_16_t<s16>> s16_be; -typedef swap_struct_t<float, swap_float_t<float> > float_be; -typedef swap_struct_t<double, swap_double_t<double> > double_be; +typedef swap_struct_t<float, swap_float_t<float>> float_be; +typedef swap_struct_t<double, swap_double_t<double>> double_be; #else -typedef swap_struct_t<u64, swap_64_t<u64> > u64_le; -typedef swap_struct_t<s64, swap_64_t<s64> > s64_le; +typedef swap_struct_t<u64, swap_64_t<u64>> u64_le; +typedef swap_struct_t<s64, swap_64_t<s64>> s64_le; -typedef swap_struct_t<u32, swap_32_t<u32> > u32_le; -typedef swap_struct_t<s32, swap_32_t<s32> > s32_le; +typedef swap_struct_t<u32, swap_32_t<u32>> u32_le; +typedef swap_struct_t<s32, swap_32_t<s32>> s32_le; -typedef swap_struct_t<u16, swap_16_t<u16> > u16_le; -typedef swap_struct_t< s16, swap_16_t<s16> > s16_le; +typedef swap_struct_t<u16, swap_16_t<u16>> u16_le; +typedef swap_struct_t<s16, swap_16_t<s16>> s16_le; -typedef swap_struct_t<float, swap_float_t<float> > float_le; -typedef swap_struct_t<double, swap_double_t<double> > double_le; +typedef swap_struct_t<float, swap_float_t<float>> float_le; +typedef swap_struct_t<double, swap_double_t<double>> double_le; typedef u32 u32_be; typedef u16 u16_be; diff --git a/src/common/symbols.cpp b/src/common/symbols.cpp index db8340043..c4d16af85 100644 --- a/src/common/symbols.cpp +++ b/src/common/symbols.cpp @@ -6,49 +6,41 @@ TSymbolsMap g_symbols; -namespace Symbols -{ - bool HasSymbol(u32 address) - { - return g_symbols.find(address) != g_symbols.end(); - } +namespace Symbols { +bool HasSymbol(u32 address) { + return g_symbols.find(address) != g_symbols.end(); +} + +void Add(u32 address, const std::string& name, u32 size, u32 type) { + if (!HasSymbol(address)) { + TSymbol symbol; + symbol.address = address; + symbol.name = name; + symbol.size = size; + symbol.type = type; - void Add(u32 address, const std::string& name, u32 size, u32 type) - { - if (!HasSymbol(address)) - { - TSymbol symbol; - symbol.address = address; - symbol.name = name; - symbol.size = size; - symbol.type = type; - - g_symbols.emplace(address, symbol); - } + g_symbols.emplace(address, symbol); } +} - TSymbol GetSymbol(u32 address) - { - const auto iter = g_symbols.find(address); +TSymbol GetSymbol(u32 address) { + const auto iter = g_symbols.find(address); - if (iter != g_symbols.end()) - return iter->second; + if (iter != g_symbols.end()) + return iter->second; - return {}; - } + return {}; +} - const std::string GetName(u32 address) - { - return GetSymbol(address).name; - } +const std::string GetName(u32 address) { + return GetSymbol(address).name; +} - void Remove(u32 address) - { - g_symbols.erase(address); - } +void Remove(u32 address) { + g_symbols.erase(address); +} - void Clear() - { - g_symbols.clear(); - } +void Clear() { + g_symbols.clear(); +} } diff --git a/src/common/symbols.h b/src/common/symbols.h index 5ed16009c..f5a48e05a 100644 --- a/src/common/symbols.h +++ b/src/common/symbols.h @@ -7,28 +7,24 @@ #include <map> #include <string> #include <utility> - #include "common/common_types.h" -struct TSymbol -{ - u32 address = 0; +struct TSymbol { + u32 address = 0; std::string name; - u32 size = 0; - u32 type = 0; + u32 size = 0; + u32 type = 0; }; typedef std::map<u32, TSymbol> TSymbolsMap; typedef std::pair<u32, TSymbol> TSymbolsPair; -namespace Symbols -{ - bool HasSymbol(u32 address); +namespace Symbols { +bool HasSymbol(u32 address); - void Add(u32 address, const std::string& name, u32 size, u32 type); - TSymbol GetSymbol(u32 address); - const std::string GetName(u32 address); - void Remove(u32 address); - void Clear(); +void Add(u32 address, const std::string& name, u32 size, u32 type); +TSymbol GetSymbol(u32 address); +const std::string GetName(u32 address); +void Remove(u32 address); +void Clear(); } - diff --git a/src/common/synchronized_wrapper.h b/src/common/synchronized_wrapper.h index 07105a198..04b4f2e51 100644 --- a/src/common/synchronized_wrapper.h +++ b/src/common/synchronized_wrapper.h @@ -12,15 +12,14 @@ namespace Common { /** * Wraps an object, only allowing access to it via a locking reference wrapper. Good to ensure no * one forgets to lock a mutex before acessing an object. To access the wrapped object construct a - * SyncronizedRef on this wrapper. Inspired by Rust's Mutex type (http://doc.rust-lang.org/std/sync/struct.Mutex.html). + * SyncronizedRef on this wrapper. Inspired by Rust's Mutex type + * (http://doc.rust-lang.org/std/sync/struct.Mutex.html). */ template <typename T> class SynchronizedWrapper { public: template <typename... Args> - SynchronizedWrapper(Args&&... args) : - data(std::forward<Args>(args)...) { - } + SynchronizedWrapper(Args&&... args) : data(std::forward<Args>(args)...) {} private: template <typename U> @@ -58,11 +57,19 @@ public: return *this; } - T& operator*() { return wrapper->data; } - const T& operator*() const { return wrapper->data; } + T& operator*() { + return wrapper->data; + } + const T& operator*() const { + return wrapper->data; + } - T* operator->() { return &wrapper->data; } - const T* operator->() const { return &wrapper->data; } + T* operator->() { + return &wrapper->data; + } + const T* operator->() const { + return &wrapper->data; + } private: SynchronizedWrapper<T>* wrapper; diff --git a/src/common/thread.cpp b/src/common/thread.cpp index 7bbf080bc..6e7b39b9a 100644 --- a/src/common/thread.cpp +++ b/src/common/thread.cpp @@ -3,29 +3,25 @@ // Refer to the license.txt file included. #include "common/thread.h" - #ifdef __APPLE__ - #include <mach/mach.h> +#include <mach/mach.h> #elif defined(_WIN32) - #include <Windows.h> +#include <Windows.h> +#else +#if defined(BSD4_4) || defined(__OpenBSD__) +#include <pthread_np.h> #else - #if defined(BSD4_4) || defined(__OpenBSD__) - #include <pthread_np.h> - #else - #include <pthread.h> - #endif - #include <sched.h> +#include <pthread.h> +#endif +#include <sched.h> #endif - #ifndef _WIN32 - #include <unistd.h> +#include <unistd.h> #endif -namespace Common -{ +namespace Common { -int CurrentThreadId() -{ +int CurrentThreadId() { #ifdef _MSC_VER return GetCurrentThreadId(); #elif defined __APPLE__ @@ -37,26 +33,22 @@ int CurrentThreadId() #ifdef _WIN32 // Supporting functions -void SleepCurrentThread(int ms) -{ +void SleepCurrentThread(int ms) { Sleep(ms); } #endif #ifdef _MSC_VER -void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask) -{ +void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask) { SetThreadAffinityMask(thread, mask); } -void SetCurrentThreadAffinity(u32 mask) -{ +void SetCurrentThreadAffinity(u32 mask) { SetThreadAffinityMask(GetCurrentThread(), mask); } -void SwitchCurrentThread() -{ +void SwitchCurrentThread() { SwitchToThread(); } @@ -66,40 +58,34 @@ void SwitchCurrentThread() // This is implemented much nicer in upcoming msvc++, see: // http://msdn.microsoft.com/en-us/library/xcb2z8hs(VS.100).aspx -void SetCurrentThreadName(const char* szThreadName) -{ +void SetCurrentThreadName(const char* szThreadName) { static const DWORD MS_VC_EXCEPTION = 0x406D1388; - #pragma pack(push,8) - struct THREADNAME_INFO - { - DWORD dwType; // must be 0x1000 - LPCSTR szName; // pointer to name (in user addr space) +#pragma pack(push, 8) + struct THREADNAME_INFO { + DWORD dwType; // must be 0x1000 + LPCSTR szName; // pointer to name (in user addr space) DWORD dwThreadID; // thread ID (-1=caller thread) - DWORD dwFlags; // reserved for future use, must be zero + DWORD dwFlags; // reserved for future use, must be zero } info; - #pragma pack(pop) +#pragma pack(pop) info.dwType = 0x1000; info.szName = szThreadName; - info.dwThreadID = -1; //dwThreadID; + info.dwThreadID = -1; // dwThreadID; info.dwFlags = 0; - __try - { - RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info); + __try { + RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info); + } __except (EXCEPTION_CONTINUE_EXECUTION) { } - __except(EXCEPTION_CONTINUE_EXECUTION) - {} } #else // !MSVC_VER, so must be POSIX threads -void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask) -{ +void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask) { #ifdef __APPLE__ - thread_policy_set(pthread_mach_thread_np(thread), - THREAD_AFFINITY_POLICY, (integer_t *)&mask, 1); + thread_policy_set(pthread_mach_thread_np(thread), THREAD_AFFINITY_POLICY, (integer_t*)&mask, 1); #elif (defined __linux__ || defined BSD4_4) && !(defined ANDROID) cpu_set_t cpu_set; CPU_ZERO(&cpu_set); @@ -112,27 +98,23 @@ void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask) #endif } -void SetCurrentThreadAffinity(u32 mask) -{ +void SetCurrentThreadAffinity(u32 mask) { SetThreadAffinity(pthread_self(), mask); } #ifndef _WIN32 -void SleepCurrentThread(int ms) -{ +void SleepCurrentThread(int ms) { usleep(1000 * ms); } -void SwitchCurrentThread() -{ +void SwitchCurrentThread() { usleep(1000 * 1); } #endif // MinGW with the POSIX threading model does not support pthread_setname_np #if !defined(_WIN32) || defined(_MSC_VER) -void SetCurrentThreadName(const char* szThreadName) -{ +void SetCurrentThreadName(const char* szThreadName) { #ifdef __APPLE__ pthread_setname_np(szThreadName); #elif defined(__OpenBSD__) diff --git a/src/common/thread.h b/src/common/thread.h index bbfa8befa..9c08be7e3 100644 --- a/src/common/thread.h +++ b/src/common/thread.h @@ -4,11 +4,10 @@ #pragma once -#include <cstddef> -#include <thread> #include <condition_variable> +#include <cstddef> #include <mutex> - +#include <thread> #include "common/common_types.h" // Support for C++11's thread_local keyword was surprisingly spotty in compilers until very @@ -17,17 +16,17 @@ // backwards compat support. // WARNING: This only works correctly with POD types. #if defined(__clang__) -# if !__has_feature(cxx_thread_local) -# define thread_local __thread -# endif +#if !__has_feature(cxx_thread_local) +#define thread_local __thread +#endif #elif defined(__GNUC__) -# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8) -# define thread_local __thread -# endif +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8) +#define thread_local __thread +#endif #elif defined(_MSC_VER) -# if _MSC_VER < 1900 -# define thread_local __declspec(thread) -# endif +#if _MSC_VER < 1900 +#define thread_local __declspec(thread) +#endif #endif namespace Common { @@ -51,13 +50,14 @@ public: void Wait() { std::unique_lock<std::mutex> lk(mutex); - condvar.wait(lk, [&]{ return is_set; }); + condvar.wait(lk, [&] { return is_set; }); is_set = false; } void Reset() { std::unique_lock<std::mutex> lk(mutex); - // no other action required, since wait loops on the predicate and any lingering signal will get cleared on the first iteration + // no other action required, since wait loops on the predicate and any lingering signal will + // get cleared on the first iteration is_set = false; } @@ -81,7 +81,8 @@ public: waiting = 0; condvar.notify_all(); } else { - condvar.wait(lk, [this, current_generation]{ return current_generation != generation; }); + condvar.wait(lk, + [this, current_generation] { return current_generation != generation; }); } } @@ -94,7 +95,7 @@ private: }; void SleepCurrentThread(int ms); -void SwitchCurrentThread(); // On Linux, this is equal to sleep 1ms +void SwitchCurrentThread(); // On Linux, this is equal to sleep 1ms // Use this function during a spin-wait to make the current thread // relax while another thread is working. This may be more efficient @@ -103,6 +104,6 @@ inline void YieldCPU() { std::this_thread::yield(); } -void SetCurrentThreadName(const char *name); +void SetCurrentThreadName(const char* name); } // namespace Common diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h index 12455d7c4..edd0e4a3f 100644 --- a/src/common/thread_queue_list.h +++ b/src/common/thread_queue_list.h @@ -6,12 +6,11 @@ #include <array> #include <deque> - #include <boost/range/algorithm_ext/erase.hpp> namespace Common { -template<class T, unsigned int N> +template <class T, unsigned int N> struct ThreadQueueList { // TODO(yuriks): If performance proves to be a problem, the std::deques can be replaced with // (dynamically resizable) circular buffers to remove their overhead when @@ -39,7 +38,7 @@ struct ThreadQueueList { } T get_first() { - Queue *cur = first; + Queue* cur = first; while (cur != nullptr) { if (!cur->data.empty()) { return cur->data.front(); @@ -51,7 +50,7 @@ struct ThreadQueueList { } T pop_first() { - Queue *cur = first; + Queue* cur = first; while (cur != nullptr) { if (!cur->data.empty()) { auto tmp = std::move(cur->data.front()); @@ -65,8 +64,8 @@ struct ThreadQueueList { } T pop_first_better(Priority priority) { - Queue *cur = first; - Queue *stop = &queues[priority]; + Queue* cur = first; + Queue* stop = &queues[priority]; while (cur < stop) { if (!cur->data.empty()) { auto tmp = std::move(cur->data.front()); @@ -80,12 +79,12 @@ struct ThreadQueueList { } void push_front(Priority priority, const T& thread_id) { - Queue *cur = &queues[priority]; + Queue* cur = &queues[priority]; cur->data.push_front(thread_id); } void push_back(Priority priority, const T& thread_id) { - Queue *cur = &queues[priority]; + Queue* cur = &queues[priority]; cur->data.push_back(thread_id); } @@ -96,12 +95,12 @@ struct ThreadQueueList { } void remove(Priority priority, const T& thread_id) { - Queue *cur = &queues[priority]; + Queue* cur = &queues[priority]; boost::remove_erase(cur->data, thread_id); } void rotate(Priority priority) { - Queue *cur = &queues[priority]; + Queue* cur = &queues[priority]; if (cur->data.size() > 1) { cur->data.push_back(std::move(cur->data.front())); @@ -115,7 +114,7 @@ struct ThreadQueueList { } bool empty(Priority priority) const { - const Queue *cur = &queues[priority]; + const Queue* cur = &queues[priority]; return cur->data.empty(); } @@ -139,7 +138,7 @@ private: } void link(Priority priority) { - Queue *cur = &queues[priority]; + Queue* cur = &queues[priority]; for (int i = priority - 1; i >= 0; --i) { if (queues[i].next_nonempty != UnlinkedTag()) { diff --git a/src/common/timer.cpp b/src/common/timer.cpp index b99835ac7..e843cbd9c 100644 --- a/src/common/timer.cpp +++ b/src/common/timer.cpp @@ -3,7 +3,6 @@ // Refer to the license.txt file included. #include <time.h> - #ifdef _WIN32 #include <Windows.h> #include <mmsystem.h> @@ -11,16 +10,13 @@ #else #include <sys/time.h> #endif - #include "common/common_types.h" #include "common/string_util.h" #include "common/timer.h" -namespace Common -{ +namespace Common { -u32 Timer::GetTimeMs() -{ +u32 Timer::GetTimeMs() { #ifdef _WIN32 return timeGetTime(); #else @@ -35,32 +31,27 @@ u32 Timer::GetTimeMs() // -------------------------------------------- // Set initial values for the class -Timer::Timer() - : m_LastTime(0), m_StartTime(0), m_Running(false) -{ +Timer::Timer() : m_LastTime(0), m_StartTime(0), m_Running(false) { Update(); } // Write the starting time -void Timer::Start() -{ +void Timer::Start() { m_StartTime = GetTimeMs(); m_Running = true; } // Stop the timer -void Timer::Stop() -{ +void Timer::Stop() { // Write the final time m_LastTime = GetTimeMs(); m_Running = false; } // Update the last time variable -void Timer::Update() -{ +void Timer::Update() { m_LastTime = GetTimeMs(); - //TODO(ector) - QPF + // TODO(ector) - QPF } // ------------------------------------- @@ -68,34 +59,32 @@ void Timer::Update() // ------------------------------------- // Get the number of milliseconds since the last Update() -u64 Timer::GetTimeDifference() -{ +u64 Timer::GetTimeDifference() { return GetTimeMs() - m_LastTime; } // Add the time difference since the last Update() to the starting time. // This is used to compensate for a paused game. -void Timer::AddTimeDifference() -{ +void Timer::AddTimeDifference() { m_StartTime += GetTimeDifference(); } // Get the time elapsed since the Start() -u64 Timer::GetTimeElapsed() -{ +u64 Timer::GetTimeElapsed() { // If we have not started yet, return 1 (because then I don't // have to change the FPS calculation in CoreRerecording.cpp . - if (m_StartTime == 0) return 1; + if (m_StartTime == 0) + return 1; // Return the final timer time if the timer is stopped - if (!m_Running) return (m_LastTime - m_StartTime); + if (!m_Running) + return (m_LastTime - m_StartTime); return (GetTimeMs() - m_StartTime); } // Get the formatted time elapsed since the Start() -std::string Timer::GetTimeElapsedFormatted() const -{ +std::string Timer::GetTimeElapsedFormatted() const { // If we have not started yet, return zero if (m_StartTime == 0) return "00:00:00:000"; @@ -114,50 +103,46 @@ std::string Timer::GetTimeElapsedFormatted() const // Hours u32 Hours = Minutes / 60; - std::string TmpStr = StringFromFormat("%02i:%02i:%02i:%03i", - Hours, Minutes % 60, Seconds % 60, Milliseconds % 1000); + std::string TmpStr = StringFromFormat("%02i:%02i:%02i:%03i", Hours, Minutes % 60, Seconds % 60, + Milliseconds % 1000); return TmpStr; } // Get current time -void Timer::IncreaseResolution() -{ +void Timer::IncreaseResolution() { #ifdef _WIN32 timeBeginPeriod(1); #endif } -void Timer::RestoreResolution() -{ +void Timer::RestoreResolution() { #ifdef _WIN32 timeEndPeriod(1); #endif } // Get the number of seconds since January 1 1970 -u64 Timer::GetTimeSinceJan1970() -{ +u64 Timer::GetTimeSinceJan1970() { time_t ltime; time(<ime); - return((u64)ltime); + return ((u64)ltime); } -u64 Timer::GetLocalTimeSinceJan1970() -{ +u64 Timer::GetLocalTimeSinceJan1970() { time_t sysTime, tzDiff, tzDST; - struct tm * gmTime; + struct tm* gmTime; time(&sysTime); // Account for DST where needed gmTime = localtime(&sysTime); - if(gmTime->tm_isdst == 1) + if (gmTime->tm_isdst == 1) tzDST = 3600; else tzDST = 0; // Lazy way to get local time in sec - gmTime = gmtime(&sysTime); + gmTime = gmtime(&sysTime); tzDiff = sysTime - mktime(gmTime); return (u64)(sysTime + tzDiff + tzDST); @@ -165,10 +150,9 @@ u64 Timer::GetLocalTimeSinceJan1970() // Return the current time formatted as Minutes:Seconds:Milliseconds // in the form 00:00:000. -std::string Timer::GetTimeFormatted() -{ +std::string Timer::GetTimeFormatted() { time_t sysTime; - struct tm * gmTime; + struct tm* gmTime; char tmp[13]; time(&sysTime); @@ -176,7 +160,7 @@ std::string Timer::GetTimeFormatted() strftime(tmp, 6, "%M:%S", gmTime); - // Now tack on the milliseconds +// Now tack on the milliseconds #ifdef _WIN32 struct timeb tp; (void)::ftime(&tp); @@ -190,8 +174,7 @@ std::string Timer::GetTimeFormatted() // Returns a timestamp with decimals for precise time comparisons // ---------------- -double Timer::GetDoubleTime() -{ +double Timer::GetDoubleTime() { #ifdef _WIN32 struct timeb tp; (void)::ftime(&tp); diff --git a/src/common/timer.h b/src/common/timer.h index b5f0f2585..78d37426b 100644 --- a/src/common/timer.h +++ b/src/common/timer.h @@ -4,13 +4,11 @@ #pragma once -#include "common/common_types.h" #include <string> +#include "common/common_types.h" -namespace Common -{ -class Timer -{ +namespace Common { +class Timer { public: Timer(); @@ -18,7 +16,8 @@ public: void Stop(); void Update(); - // The time difference is always returned in milliseconds, regardless of alternative internal representation + // The time difference is always returned in milliseconds, regardless of alternative internal + // representation u64 GetTimeDifference(); void AddTimeDifference(); diff --git a/src/common/vector_math.h b/src/common/vector_math.h index cfb9481b6..2d56f168c 100644 --- a/src/common/vector_math.h +++ b/src/common/vector_math.h @@ -1,7 +1,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. - // Copyright 2014 Tony Wasserka // All rights reserved. // @@ -36,158 +35,174 @@ namespace Math { -template<typename T> class Vec2; -template<typename T> class Vec3; -template<typename T> class Vec4; +template <typename T> +class Vec2; +template <typename T> +class Vec3; +template <typename T> +class Vec4; -template<typename T> +template <typename T> static inline Vec2<T> MakeVec(const T& x, const T& y); -template<typename T> +template <typename T> static inline Vec3<T> MakeVec(const T& x, const T& y, const T& z); -template<typename T> +template <typename T> static inline Vec4<T> MakeVec(const T& x, const T& y, const T& z, const T& w); - -template<typename T> +template <typename T> class Vec2 { public: T x; T y; - T* AsArray() { return &x; } + T* AsArray() { + return &x; + } Vec2() = default; Vec2(const T a[2]) : x(a[0]), y(a[1]) {} Vec2(const T& _x, const T& _y) : x(_x), y(_y) {} - template<typename T2> + template <typename T2> Vec2<T2> Cast() const { return Vec2<T2>((T2)x, (T2)y); } - static Vec2 AssignToAll(const T& f) - { + static Vec2 AssignToAll(const T& f) { return Vec2<T>(f, f); } - void Write(T a[2]) - { - a[0] = x; a[1] = y; + void Write(T a[2]) { + a[0] = x; + a[1] = y; } - Vec2<decltype(T{}+T{})> operator +(const Vec2& other) const - { - return MakeVec(x+other.x, y+other.y); + Vec2<decltype(T{} + T{})> operator+(const Vec2& other) const { + return MakeVec(x + other.x, y + other.y); } - void operator += (const Vec2 &other) - { - x+=other.x; y+=other.y; + void operator+=(const Vec2& other) { + x += other.x; + y += other.y; } - Vec2<decltype(T{}-T{})> operator -(const Vec2& other) const - { - return MakeVec(x-other.x, y-other.y); + Vec2<decltype(T{} - T{})> operator-(const Vec2& other) const { + return MakeVec(x - other.x, y - other.y); } - void operator -= (const Vec2& other) - { - x-=other.x; y-=other.y; + void operator-=(const Vec2& other) { + x -= other.x; + y -= other.y; } - template<typename Q = T,class = typename std::enable_if<std::is_signed<Q>::value>::type> - Vec2<decltype(-T{})> operator -() const - { - return MakeVec(-x,-y); + template <typename Q = T, class = typename std::enable_if<std::is_signed<Q>::value>::type> + Vec2<decltype(-T{})> operator-() const { + return MakeVec(-x, -y); } - Vec2<decltype(T{}*T{})> operator * (const Vec2& other) const - { - return MakeVec(x*other.x, y*other.y); + Vec2<decltype(T{} * T{})> operator*(const Vec2& other) const { + return MakeVec(x * other.x, y * other.y); } - template<typename V> - Vec2<decltype(T{}*V{})> operator * (const V& f) const - { - return MakeVec(x*f,y*f); + template <typename V> + Vec2<decltype(T{} * V{})> operator*(const V& f) const { + return MakeVec(x * f, y * f); } - template<typename V> - void operator *= (const V& f) - { - x*=f; y*=f; + template <typename V> + void operator*=(const V& f) { + x *= f; + y *= f; } - template<typename V> - Vec2<decltype(T{}/V{})> operator / (const V& f) const - { - return MakeVec(x/f,y/f); + template <typename V> + Vec2<decltype(T{} / V{})> operator/(const V& f) const { + return MakeVec(x / f, y / f); } - template<typename V> - void operator /= (const V& f) - { + template <typename V> + void operator/=(const V& f) { *this = *this / f; } - T Length2() const - { - return x*x + y*y; + T Length2() const { + return x * x + y * y; } // Only implemented for T=float float Length() const; void SetLength(const float l); Vec2 WithLength(const float l) const; - float Distance2To(Vec2 &other); + float Distance2To(Vec2& other); Vec2 Normalized() const; float Normalize(); // returns the previous length, which is often useful - T& operator [] (int i) //allow vector[1] = 3 (vector.y=3) + T& operator[](int i) // allow vector[1] = 3 (vector.y=3) { return *((&x) + i); } - T operator [] (const int i) const - { + T operator[](const int i) const { return *((&x) + i); } - void SetZero() - { - x=0; y=0; + void SetZero() { + x = 0; + y = 0; } // Common aliases: UV (texel coordinates), ST (texture coordinates) - T& u() { return x; } - T& v() { return y; } - T& s() { return x; } - T& t() { return y; } + T& u() { + return x; + } + T& v() { + return y; + } + T& s() { + return x; + } + T& t() { + return y; + } - const T& u() const { return x; } - const T& v() const { return y; } - const T& s() const { return x; } - const T& t() const { return y; } + const T& u() const { + return x; + } + const T& v() const { + return y; + } + const T& s() const { + return x; + } + const T& t() const { + return y; + } // swizzlers - create a subvector of specific components - const Vec2 yx() const { return Vec2(y, x); } - const Vec2 vu() const { return Vec2(y, x); } - const Vec2 ts() const { return Vec2(y, x); } + const Vec2 yx() const { + return Vec2(y, x); + } + const Vec2 vu() const { + return Vec2(y, x); + } + const Vec2 ts() const { + return Vec2(y, x); + } }; -template<typename T, typename V> -Vec2<T> operator * (const V& f, const Vec2<T>& vec) -{ - return Vec2<T>(f*vec.x,f*vec.y); +template <typename T, typename V> +Vec2<T> operator*(const V& f, const Vec2<T>& vec) { + return Vec2<T>(f * vec.x, f * vec.y); } typedef Vec2<float> Vec2f; -template<typename T> -class Vec3 -{ +template <typename T> +class Vec3 { public: T x; T y; T z; - T* AsArray() { return &x; } + T* AsArray() { + return &x; + } Vec3() = default; Vec3(const T a[3]) : x(a[0]), y(a[1]), z(a[2]) {} Vec3(const T& _x, const T& _y, const T& _z) : x(_x), y(_y), z(_z) {} - template<typename T2> + template <typename T2> Vec3<T2> Cast() const { return MakeVec<T2>((T2)x, (T2)y, (T2)z); } @@ -196,126 +211,161 @@ public: static Vec3 FromRGB(unsigned int rgb); unsigned int ToRGB() const; // alpha bits set to zero - static Vec3 AssignToAll(const T& f) - { + static Vec3 AssignToAll(const T& f) { return MakeVec(f, f, f); } - void Write(T a[3]) - { - a[0] = x; a[1] = y; a[2] = z; + void Write(T a[3]) { + a[0] = x; + a[1] = y; + a[2] = z; } - Vec3<decltype(T{}+T{})> operator +(const Vec3 &other) const - { - return MakeVec(x+other.x, y+other.y, z+other.z); + Vec3<decltype(T{} + T{})> operator+(const Vec3& other) const { + return MakeVec(x + other.x, y + other.y, z + other.z); } - void operator += (const Vec3 &other) - { - x+=other.x; y+=other.y; z+=other.z; + void operator+=(const Vec3& other) { + x += other.x; + y += other.y; + z += other.z; } - Vec3<decltype(T{}-T{})> operator -(const Vec3 &other) const - { - return MakeVec(x-other.x, y-other.y, z-other.z); + Vec3<decltype(T{} - T{})> operator-(const Vec3& other) const { + return MakeVec(x - other.x, y - other.y, z - other.z); } - void operator -= (const Vec3 &other) - { - x-=other.x; y-=other.y; z-=other.z; + void operator-=(const Vec3& other) { + x -= other.x; + y -= other.y; + z -= other.z; } - template<typename Q = T,class = typename std::enable_if<std::is_signed<Q>::value>::type> - Vec3<decltype(-T{})> operator -() const - { - return MakeVec(-x,-y,-z); + template <typename Q = T, class = typename std::enable_if<std::is_signed<Q>::value>::type> + Vec3<decltype(-T{})> operator-() const { + return MakeVec(-x, -y, -z); } - Vec3<decltype(T{}*T{})> operator * (const Vec3 &other) const - { - return MakeVec(x*other.x, y*other.y, z*other.z); + Vec3<decltype(T{} * T{})> operator*(const Vec3& other) const { + return MakeVec(x * other.x, y * other.y, z * other.z); } - template<typename V> - Vec3<decltype(T{}*V{})> operator * (const V& f) const - { - return MakeVec(x*f,y*f,z*f); + template <typename V> + Vec3<decltype(T{} * V{})> operator*(const V& f) const { + return MakeVec(x * f, y * f, z * f); } - template<typename V> - void operator *= (const V& f) - { - x*=f; y*=f; z*=f; + template <typename V> + void operator*=(const V& f) { + x *= f; + y *= f; + z *= f; } - template<typename V> - Vec3<decltype(T{}/V{})> operator / (const V& f) const - { - return MakeVec(x/f,y/f,z/f); + template <typename V> + Vec3<decltype(T{} / V{})> operator/(const V& f) const { + return MakeVec(x / f, y / f, z / f); } - template<typename V> - void operator /= (const V& f) - { + template <typename V> + void operator/=(const V& f) { *this = *this / f; } - T Length2() const - { - return x*x + y*y + z*z; + T Length2() const { + return x * x + y * y + z * z; } // Only implemented for T=float float Length() const; void SetLength(const float l); Vec3 WithLength(const float l) const; - float Distance2To(Vec3 &other); + float Distance2To(Vec3& other); Vec3 Normalized() const; float Normalize(); // returns the previous length, which is often useful - T& operator [] (int i) //allow vector[2] = 3 (vector.z=3) + T& operator[](int i) // allow vector[2] = 3 (vector.z=3) { return *((&x) + i); } - T operator [] (const int i) const - { + T operator[](const int i) const { return *((&x) + i); } - void SetZero() - { - x=0; y=0; z=0; + void SetZero() { + x = 0; + y = 0; + z = 0; } // Common aliases: UVW (texel coordinates), RGB (colors), STQ (texture coordinates) - T& u() { return x; } - T& v() { return y; } - T& w() { return z; } + T& u() { + return x; + } + T& v() { + return y; + } + T& w() { + return z; + } - T& r() { return x; } - T& g() { return y; } - T& b() { return z; } + T& r() { + return x; + } + T& g() { + return y; + } + T& b() { + return z; + } - T& s() { return x; } - T& t() { return y; } - T& q() { return z; } + T& s() { + return x; + } + T& t() { + return y; + } + T& q() { + return z; + } - const T& u() const { return x; } - const T& v() const { return y; } - const T& w() const { return z; } + const T& u() const { + return x; + } + const T& v() const { + return y; + } + const T& w() const { + return z; + } - const T& r() const { return x; } - const T& g() const { return y; } - const T& b() const { return z; } + const T& r() const { + return x; + } + const T& g() const { + return y; + } + const T& b() const { + return z; + } - const T& s() const { return x; } - const T& t() const { return y; } - const T& q() const { return z; } + const T& s() const { + return x; + } + const T& t() const { + return y; + } + const T& q() const { + return z; + } - // swizzlers - create a subvector of specific components - // e.g. Vec2 uv() { return Vec2(x,y); } - // _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all component names (x<->r) and permutations (xy<->yx) -#define _DEFINE_SWIZZLER2(a, b, name) const Vec2<T> name() const { return Vec2<T>(a, b); } -#define DEFINE_SWIZZLER2(a, b, a2, b2, a3, b3, a4, b4) \ - _DEFINE_SWIZZLER2(a, b, a##b); \ - _DEFINE_SWIZZLER2(a, b, a2##b2); \ - _DEFINE_SWIZZLER2(a, b, a3##b3); \ - _DEFINE_SWIZZLER2(a, b, a4##b4); \ - _DEFINE_SWIZZLER2(b, a, b##a); \ - _DEFINE_SWIZZLER2(b, a, b2##a2); \ - _DEFINE_SWIZZLER2(b, a, b3##a3); \ +// swizzlers - create a subvector of specific components +// e.g. Vec2 uv() { return Vec2(x,y); } +// _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all +// component names (x<->r) and permutations (xy<->yx) +#define _DEFINE_SWIZZLER2(a, b, name) \ + const Vec2<T> name() const { \ + return Vec2<T>(a, b); \ + } +#define DEFINE_SWIZZLER2(a, b, a2, b2, a3, b3, a4, b4) \ + _DEFINE_SWIZZLER2(a, b, a##b); \ + _DEFINE_SWIZZLER2(a, b, a2##b2); \ + _DEFINE_SWIZZLER2(a, b, a3##b3); \ + _DEFINE_SWIZZLER2(a, b, a4##b4); \ + _DEFINE_SWIZZLER2(b, a, b##a); \ + _DEFINE_SWIZZLER2(b, a, b2##a2); \ + _DEFINE_SWIZZLER2(b, a, b3##a3); \ _DEFINE_SWIZZLER2(b, a, b4##a4) DEFINE_SWIZZLER2(x, y, r, g, u, v, s, t); @@ -325,41 +375,40 @@ public: #undef _DEFINE_SWIZZLER2 }; -template<typename T, typename V> -Vec3<T> operator * (const V& f, const Vec3<T>& vec) -{ - return Vec3<T>(f*vec.x,f*vec.y,f*vec.z); +template <typename T, typename V> +Vec3<T> operator*(const V& f, const Vec3<T>& vec) { + return Vec3<T>(f * vec.x, f * vec.y, f * vec.z); } -template<> +template <> inline float Vec3<float>::Length() const { return std::sqrt(x * x + y * y + z * z); } -template<> +template <> inline Vec3<float> Vec3<float>::Normalized() const { return *this / Length(); } - typedef Vec3<float> Vec3f; -template<typename T> -class Vec4 -{ +template <typename T> +class Vec4 { public: T x; T y; T z; T w; - T* AsArray() { return &x; } + T* AsArray() { + return &x; + } Vec4() = default; Vec4(const T a[4]) : x(a[0]), y(a[1]), z(a[2]), w(a[3]) {} Vec4(const T& _x, const T& _y, const T& _z, const T& _w) : x(_x), y(_y), z(_z), w(_w) {} - template<typename T2> + template <typename T2> Vec4<T2> Cast() const { return Vec4<T2>((T2)x, (T2)y, (T2)z, (T2)w); } @@ -372,81 +421,79 @@ public: return Vec4<T>(f, f, f, f); } - void Write(T a[4]) - { - a[0] = x; a[1] = y; a[2] = z; a[3] = w; + void Write(T a[4]) { + a[0] = x; + a[1] = y; + a[2] = z; + a[3] = w; } - Vec4<decltype(T{}+T{})> operator +(const Vec4& other) const - { - return MakeVec(x+other.x, y+other.y, z+other.z, w+other.w); + Vec4<decltype(T{} + T{})> operator+(const Vec4& other) const { + return MakeVec(x + other.x, y + other.y, z + other.z, w + other.w); } - void operator += (const Vec4& other) - { - x+=other.x; y+=other.y; z+=other.z; w+=other.w; + void operator+=(const Vec4& other) { + x += other.x; + y += other.y; + z += other.z; + w += other.w; } - Vec4<decltype(T{}-T{})> operator -(const Vec4 &other) const - { - return MakeVec(x-other.x, y-other.y, z-other.z, w-other.w); + Vec4<decltype(T{} - T{})> operator-(const Vec4& other) const { + return MakeVec(x - other.x, y - other.y, z - other.z, w - other.w); } - void operator -= (const Vec4 &other) - { - x-=other.x; y-=other.y; z-=other.z; w-=other.w; + void operator-=(const Vec4& other) { + x -= other.x; + y -= other.y; + z -= other.z; + w -= other.w; } - template<typename Q = T,class = typename std::enable_if<std::is_signed<Q>::value>::type> - Vec4<decltype(-T{})> operator -() const - { - return MakeVec(-x,-y,-z,-w); + template <typename Q = T, class = typename std::enable_if<std::is_signed<Q>::value>::type> + Vec4<decltype(-T{})> operator-() const { + return MakeVec(-x, -y, -z, -w); } - Vec4<decltype(T{}*T{})> operator * (const Vec4 &other) const - { - return MakeVec(x*other.x, y*other.y, z*other.z, w*other.w); + Vec4<decltype(T{} * T{})> operator*(const Vec4& other) const { + return MakeVec(x * other.x, y * other.y, z * other.z, w * other.w); } - template<typename V> - Vec4<decltype(T{}*V{})> operator * (const V& f) const - { - return MakeVec(x*f,y*f,z*f,w*f); + template <typename V> + Vec4<decltype(T{} * V{})> operator*(const V& f) const { + return MakeVec(x * f, y * f, z * f, w * f); } - template<typename V> - void operator *= (const V& f) - { - x*=f; y*=f; z*=f; w*=f; + template <typename V> + void operator*=(const V& f) { + x *= f; + y *= f; + z *= f; + w *= f; } - template<typename V> - Vec4<decltype(T{}/V{})> operator / (const V& f) const - { - return MakeVec(x/f,y/f,z/f,w/f); + template <typename V> + Vec4<decltype(T{} / V{})> operator/(const V& f) const { + return MakeVec(x / f, y / f, z / f, w / f); } - template<typename V> - void operator /= (const V& f) - { + template <typename V> + void operator/=(const V& f) { *this = *this / f; } - T Length2() const - { - return x*x + y*y + z*z + w*w; + T Length2() const { + return x * x + y * y + z * z + w * w; } // Only implemented for T=float float Length() const; void SetLength(const float l); Vec4 WithLength(const float l) const; - float Distance2To(Vec4 &other); + float Distance2To(Vec4& other); Vec4 Normalized() const; float Normalize(); // returns the previous length, which is often useful - T& operator [] (int i) //allow vector[2] = 3 (vector.z=3) + T& operator[](int i) // allow vector[2] = 3 (vector.z=3) { return *((&x) + i); } - T operator [] (const int i) const - { + T operator[](const int i) const { return *((&x) + i); } - void SetZero() - { + void SetZero() { x = 0; y = 0; z = 0; @@ -454,30 +501,50 @@ public: } // Common alias: RGBA (colors) - T& r() { return x; } - T& g() { return y; } - T& b() { return z; } - T& a() { return w; } - - const T& r() const { return x; } - const T& g() const { return y; } - const T& b() const { return z; } - const T& a() const { return w; } - - // Swizzlers - Create a subvector of specific components - // e.g. Vec2 uv() { return Vec2(x,y); } - - // _DEFINE_SWIZZLER2 defines a single such function - // DEFINE_SWIZZLER2_COMP1 defines one-component functions for all component names (x<->r) - // DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and permutations (xy<->yx) -#define _DEFINE_SWIZZLER2(a, b, name) const Vec2<T> name() const { return Vec2<T>(a, b); } -#define DEFINE_SWIZZLER2_COMP1(a, a2) \ - _DEFINE_SWIZZLER2(a, a, a##a); \ + T& r() { + return x; + } + T& g() { + return y; + } + T& b() { + return z; + } + T& a() { + return w; + } + + const T& r() const { + return x; + } + const T& g() const { + return y; + } + const T& b() const { + return z; + } + const T& a() const { + return w; + } + +// Swizzlers - Create a subvector of specific components +// e.g. Vec2 uv() { return Vec2(x,y); } + +// _DEFINE_SWIZZLER2 defines a single such function +// DEFINE_SWIZZLER2_COMP1 defines one-component functions for all component names (x<->r) +// DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and +// permutations (xy<->yx) +#define _DEFINE_SWIZZLER2(a, b, name) \ + const Vec2<T> name() const { \ + return Vec2<T>(a, b); \ + } +#define DEFINE_SWIZZLER2_COMP1(a, a2) \ + _DEFINE_SWIZZLER2(a, a, a##a); \ _DEFINE_SWIZZLER2(a, a, a2##a2) -#define DEFINE_SWIZZLER2_COMP2(a, b, a2, b2) \ - _DEFINE_SWIZZLER2(a, b, a##b); \ - _DEFINE_SWIZZLER2(a, b, a2##b2); \ - _DEFINE_SWIZZLER2(b, a, b##a); \ +#define DEFINE_SWIZZLER2_COMP2(a, b, a2, b2) \ + _DEFINE_SWIZZLER2(a, b, a##b); \ + _DEFINE_SWIZZLER2(a, b, a2##b2); \ + _DEFINE_SWIZZLER2(b, a, b##a); \ _DEFINE_SWIZZLER2(b, a, b2##a2) DEFINE_SWIZZLER2_COMP2(x, y, r, g); @@ -494,22 +561,25 @@ public: #undef DEFINE_SWIZZLER2_COMP2 #undef _DEFINE_SWIZZLER2 -#define _DEFINE_SWIZZLER3(a, b, c, name) const Vec3<T> name() const { return Vec3<T>(a, b, c); } -#define DEFINE_SWIZZLER3_COMP1(a, a2) \ - _DEFINE_SWIZZLER3(a, a, a, a##a##a); \ +#define _DEFINE_SWIZZLER3(a, b, c, name) \ + const Vec3<T> name() const { \ + return Vec3<T>(a, b, c); \ + } +#define DEFINE_SWIZZLER3_COMP1(a, a2) \ + _DEFINE_SWIZZLER3(a, a, a, a##a##a); \ _DEFINE_SWIZZLER3(a, a, a, a2##a2##a2) -#define DEFINE_SWIZZLER3_COMP3(a, b, c, a2, b2, c2) \ - _DEFINE_SWIZZLER3(a, b, c, a##b##c); \ - _DEFINE_SWIZZLER3(a, c, b, a##c##b); \ - _DEFINE_SWIZZLER3(b, a, c, b##a##c); \ - _DEFINE_SWIZZLER3(b, c, a, b##c##a); \ - _DEFINE_SWIZZLER3(c, a, b, c##a##b); \ - _DEFINE_SWIZZLER3(c, b, a, c##b##a); \ - _DEFINE_SWIZZLER3(a, b, c, a2##b2##c2); \ - _DEFINE_SWIZZLER3(a, c, b, a2##c2##b2); \ - _DEFINE_SWIZZLER3(b, a, c, b2##a2##c2); \ - _DEFINE_SWIZZLER3(b, c, a, b2##c2##a2); \ - _DEFINE_SWIZZLER3(c, a, b, c2##a2##b2); \ +#define DEFINE_SWIZZLER3_COMP3(a, b, c, a2, b2, c2) \ + _DEFINE_SWIZZLER3(a, b, c, a##b##c); \ + _DEFINE_SWIZZLER3(a, c, b, a##c##b); \ + _DEFINE_SWIZZLER3(b, a, c, b##a##c); \ + _DEFINE_SWIZZLER3(b, c, a, b##c##a); \ + _DEFINE_SWIZZLER3(c, a, b, c##a##b); \ + _DEFINE_SWIZZLER3(c, b, a, c##b##a); \ + _DEFINE_SWIZZLER3(a, b, c, a2##b2##c2); \ + _DEFINE_SWIZZLER3(a, c, b, a2##c2##b2); \ + _DEFINE_SWIZZLER3(b, a, c, b2##a2##c2); \ + _DEFINE_SWIZZLER3(b, c, a, b2##c2##a2); \ + _DEFINE_SWIZZLER3(c, a, b, c2##a2##b2); \ _DEFINE_SWIZZLER3(c, b, a, c2##b2##a2) DEFINE_SWIZZLER3_COMP3(x, y, z, r, g, b); @@ -525,123 +595,104 @@ public: #undef _DEFINE_SWIZZLER3 }; - -template<typename T, typename V> -Vec4<decltype(V{}*T{})> operator * (const V& f, const Vec4<T>& vec) -{ - return MakeVec(f*vec.x,f*vec.y,f*vec.z,f*vec.w); +template <typename T, typename V> +Vec4<decltype(V{} * T{})> operator*(const V& f, const Vec4<T>& vec) { + return MakeVec(f * vec.x, f * vec.y, f * vec.z, f * vec.w); } typedef Vec4<float> Vec4f; - -template<typename T> -static inline decltype(T{}*T{}+T{}*T{}) Dot(const Vec2<T>& a, const Vec2<T>& b) -{ - return a.x*b.x + a.y*b.y; +template <typename T> +static inline decltype(T{} * T{} + T{} * T{}) Dot(const Vec2<T>& a, const Vec2<T>& b) { + return a.x * b.x + a.y * b.y; } -template<typename T> -static inline decltype(T{}*T{}+T{}*T{}) Dot(const Vec3<T>& a, const Vec3<T>& b) -{ - return a.x*b.x + a.y*b.y + a.z*b.z; +template <typename T> +static inline decltype(T{} * T{} + T{} * T{}) Dot(const Vec3<T>& a, const Vec3<T>& b) { + return a.x * b.x + a.y * b.y + a.z * b.z; } -template<typename T> -static inline decltype(T{}*T{}+T{}*T{}) Dot(const Vec4<T>& a, const Vec4<T>& b) -{ - return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w; +template <typename T> +static inline decltype(T{} * T{} + T{} * T{}) Dot(const Vec4<T>& a, const Vec4<T>& b) { + return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; } -template<typename T> -static inline Vec3<decltype(T{}*T{}-T{}*T{})> Cross(const Vec3<T>& a, const Vec3<T>& b) -{ - return MakeVec(a.y*b.z-a.z*b.y, a.z*b.x-a.x*b.z, a.x*b.y-a.y*b.x); +template <typename T> +static inline Vec3<decltype(T{} * T{} - T{} * T{})> Cross(const Vec3<T>& a, const Vec3<T>& b) { + return MakeVec(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); } // linear interpolation via float: 0.0=begin, 1.0=end -template<typename X> -static inline decltype(X{}*float{}+X{}*float{}) Lerp(const X& begin, const X& end, const float t) -{ - return begin*(1.f-t) + end*t; +template <typename X> +static inline decltype(X{} * float{} + X{} * float{}) Lerp(const X& begin, const X& end, + const float t) { + return begin * (1.f - t) + end * t; } // linear interpolation via int: 0=begin, base=end -template<typename X, int base> -static inline decltype((X{}*int{}+X{}*int{}) / base) LerpInt(const X& begin, const X& end, const int t) -{ - return (begin*(base-t) + end*t) / base; +template <typename X, int base> +static inline decltype((X{} * int{} + X{} * int{}) / base) LerpInt(const X& begin, const X& end, + const int t) { + return (begin * (base - t) + end * t) / base; } // Utility vector factories -template<typename T> -static inline Vec2<T> MakeVec(const T& x, const T& y) -{ +template <typename T> +static inline Vec2<T> MakeVec(const T& x, const T& y) { return Vec2<T>{x, y}; } -template<typename T> -static inline Vec3<T> MakeVec(const T& x, const T& y, const T& z) -{ +template <typename T> +static inline Vec3<T> MakeVec(const T& x, const T& y, const T& z) { return Vec3<T>{x, y, z}; } -template<typename T> -static inline Vec4<T> MakeVec(const T& x, const T& y, const Vec2<T>& zw) -{ +template <typename T> +static inline Vec4<T> MakeVec(const T& x, const T& y, const Vec2<T>& zw) { return MakeVec(x, y, zw[0], zw[1]); } -template<typename T> -static inline Vec3<T> MakeVec(const Vec2<T>& xy, const T& z) -{ +template <typename T> +static inline Vec3<T> MakeVec(const Vec2<T>& xy, const T& z) { return MakeVec(xy[0], xy[1], z); } -template<typename T> -static inline Vec3<T> MakeVec(const T& x, const Vec2<T>& yz) -{ +template <typename T> +static inline Vec3<T> MakeVec(const T& x, const Vec2<T>& yz) { return MakeVec(x, yz[0], yz[1]); } -template<typename T> -static inline Vec4<T> MakeVec(const T& x, const T& y, const T& z, const T& w) -{ +template <typename T> +static inline Vec4<T> MakeVec(const T& x, const T& y, const T& z, const T& w) { return Vec4<T>{x, y, z, w}; } -template<typename T> -static inline Vec4<T> MakeVec(const Vec2<T>& xy, const T& z, const T& w) -{ +template <typename T> +static inline Vec4<T> MakeVec(const Vec2<T>& xy, const T& z, const T& w) { return MakeVec(xy[0], xy[1], z, w); } -template<typename T> -static inline Vec4<T> MakeVec(const T& x, const Vec2<T>& yz, const T& w) -{ +template <typename T> +static inline Vec4<T> MakeVec(const T& x, const Vec2<T>& yz, const T& w) { return MakeVec(x, yz[0], yz[1], w); } // NOTE: This has priority over "Vec2<Vec2<T>> MakeVec(const Vec2<T>& x, const Vec2<T>& y)". // Even if someone wanted to use an odd object like Vec2<Vec2<T>>, the compiler would error // out soon enough due to misuse of the returned structure. -template<typename T> -static inline Vec4<T> MakeVec(const Vec2<T>& xy, const Vec2<T>& zw) -{ +template <typename T> +static inline Vec4<T> MakeVec(const Vec2<T>& xy, const Vec2<T>& zw) { return MakeVec(xy[0], xy[1], zw[0], zw[1]); } -template<typename T> -static inline Vec4<T> MakeVec(const Vec3<T>& xyz, const T& w) -{ +template <typename T> +static inline Vec4<T> MakeVec(const Vec3<T>& xyz, const T& w) { return MakeVec(xyz[0], xyz[1], xyz[2], w); } -template<typename T> -static inline Vec4<T> MakeVec(const T& x, const Vec3<T>& yzw) -{ +template <typename T> +static inline Vec4<T> MakeVec(const T& x, const Vec3<T>& yzw) { return MakeVec(x, yzw[0], yzw[1], yzw[2]); } - } // namespace diff --git a/src/common/x64/abi.cpp b/src/common/x64/abi.cpp index 955eb86ce..504b9c940 100644 --- a/src/common/x64/abi.cpp +++ b/src/common/x64/abi.cpp @@ -22,7 +22,8 @@ using namespace Gen; // Shared code between Win64 and Unix64 -void XEmitter::ABI_CalculateFrameSize(BitSet32 mask, size_t rsp_alignment, size_t needed_frame_size, size_t* shadowp, size_t* subtractionp, size_t* xmm_offsetp) { +void XEmitter::ABI_CalculateFrameSize(BitSet32 mask, size_t rsp_alignment, size_t needed_frame_size, + size_t* shadowp, size_t* subtractionp, size_t* xmm_offsetp) { size_t shadow = 0; #if defined(_WIN32) shadow = 0x20; @@ -49,17 +50,19 @@ void XEmitter::ABI_CalculateFrameSize(BitSet32 mask, size_t rsp_alignment, size_ *xmm_offsetp = subtraction - xmm_base_subtraction; } -size_t XEmitter::ABI_PushRegistersAndAdjustStack(BitSet32 mask, size_t rsp_alignment, size_t needed_frame_size) { +size_t XEmitter::ABI_PushRegistersAndAdjustStack(BitSet32 mask, size_t rsp_alignment, + size_t needed_frame_size) { size_t shadow, subtraction, xmm_offset; - ABI_CalculateFrameSize(mask, rsp_alignment, needed_frame_size, &shadow, &subtraction, &xmm_offset); + ABI_CalculateFrameSize(mask, rsp_alignment, needed_frame_size, &shadow, &subtraction, + &xmm_offset); - for (int r : mask & ABI_ALL_GPRS) + for (int r : mask& ABI_ALL_GPRS) PUSH((X64Reg)r); if (subtraction) SUB(64, R(RSP), subtraction >= 0x80 ? Imm32((u32)subtraction) : Imm8((u8)subtraction)); - for (int x : mask & ABI_ALL_FPRS) { + for (int x : mask& ABI_ALL_FPRS) { MOVAPD(MDisp(RSP, (int)xmm_offset), (X64Reg)(x - 16)); xmm_offset += 16; } @@ -67,12 +70,14 @@ size_t XEmitter::ABI_PushRegistersAndAdjustStack(BitSet32 mask, size_t rsp_align return shadow; } -void XEmitter::ABI_PopRegistersAndAdjustStack(BitSet32 mask, size_t rsp_alignment, size_t needed_frame_size) { +void XEmitter::ABI_PopRegistersAndAdjustStack(BitSet32 mask, size_t rsp_alignment, + size_t needed_frame_size) { size_t shadow, subtraction, xmm_offset; - ABI_CalculateFrameSize(mask, rsp_alignment, needed_frame_size, &shadow, &subtraction, &xmm_offset); + ABI_CalculateFrameSize(mask, rsp_alignment, needed_frame_size, &shadow, &subtraction, + &xmm_offset); - for (int x : mask & ABI_ALL_FPRS) { - MOVAPD((X64Reg) (x - 16), MDisp(RSP, (int)xmm_offset)); + for (int x : mask& ABI_ALL_FPRS) { + MOVAPD((X64Reg)(x - 16), MDisp(RSP, (int)xmm_offset)); xmm_offset += 16; } @@ -86,10 +91,9 @@ void XEmitter::ABI_PopRegistersAndAdjustStack(BitSet32 mask, size_t rsp_alignmen } // Common functions -void XEmitter::ABI_CallFunction(const void *func) { +void XEmitter::ABI_CallFunction(const void* func) { u64 distance = u64(func) - (u64(code) + 5); - if (distance >= 0x0000000080000000ULL - && distance < 0xFFFFFFFF80000000ULL) { + if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { // Far call MOV(64, R(RAX), ImmPtr(func)); CALLptr(R(RAX)); @@ -98,11 +102,10 @@ void XEmitter::ABI_CallFunction(const void *func) { } } -void XEmitter::ABI_CallFunctionC16(const void *func, u16 param1) { +void XEmitter::ABI_CallFunctionC16(const void* func, u16 param1) { MOV(32, R(ABI_PARAM1), Imm32((u32)param1)); u64 distance = u64(func) - (u64(code) + 5); - if (distance >= 0x0000000080000000ULL - && distance < 0xFFFFFFFF80000000ULL) { + if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { // Far call MOV(64, R(RAX), ImmPtr(func)); CALLptr(R(RAX)); @@ -111,25 +114,23 @@ void XEmitter::ABI_CallFunctionC16(const void *func, u16 param1) { } } -void XEmitter::ABI_CallFunctionCC16(const void *func, u32 param1, u16 param2) { +void XEmitter::ABI_CallFunctionCC16(const void* func, u32 param1, u16 param2) { MOV(32, R(ABI_PARAM1), Imm32(param1)); MOV(32, R(ABI_PARAM2), Imm32((u32)param2)); u64 distance = u64(func) - (u64(code) + 5); - if (distance >= 0x0000000080000000ULL - && distance < 0xFFFFFFFF80000000ULL) { - // Far call - MOV(64, R(RAX), ImmPtr(func)); - CALLptr(R(RAX)); + if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { + // Far call + MOV(64, R(RAX), ImmPtr(func)); + CALLptr(R(RAX)); } else { CALL(func); } } -void XEmitter::ABI_CallFunctionC(const void *func, u32 param1) { +void XEmitter::ABI_CallFunctionC(const void* func, u32 param1) { MOV(32, R(ABI_PARAM1), Imm32(param1)); u64 distance = u64(func) - (u64(code) + 5); - if (distance >= 0x0000000080000000ULL - && distance < 0xFFFFFFFF80000000ULL) { + if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { // Far call MOV(64, R(RAX), ImmPtr(func)); CALLptr(R(RAX)); @@ -138,12 +139,11 @@ void XEmitter::ABI_CallFunctionC(const void *func, u32 param1) { } } -void XEmitter::ABI_CallFunctionCC(const void *func, u32 param1, u32 param2) { +void XEmitter::ABI_CallFunctionCC(const void* func, u32 param1, u32 param2) { MOV(32, R(ABI_PARAM1), Imm32(param1)); MOV(32, R(ABI_PARAM2), Imm32(param2)); u64 distance = u64(func) - (u64(code) + 5); - if (distance >= 0x0000000080000000ULL - && distance < 0xFFFFFFFF80000000ULL) { + if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { // Far call MOV(64, R(RAX), ImmPtr(func)); CALLptr(R(RAX)); @@ -152,13 +152,12 @@ void XEmitter::ABI_CallFunctionCC(const void *func, u32 param1, u32 param2) { } } -void XEmitter::ABI_CallFunctionCCC(const void *func, u32 param1, u32 param2, u32 param3) { +void XEmitter::ABI_CallFunctionCCC(const void* func, u32 param1, u32 param2, u32 param3) { MOV(32, R(ABI_PARAM1), Imm32(param1)); MOV(32, R(ABI_PARAM2), Imm32(param2)); MOV(32, R(ABI_PARAM3), Imm32(param3)); u64 distance = u64(func) - (u64(code) + 5); - if (distance >= 0x0000000080000000ULL - && distance < 0xFFFFFFFF80000000ULL) { + if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { // Far call MOV(64, R(RAX), ImmPtr(func)); CALLptr(R(RAX)); @@ -167,13 +166,12 @@ void XEmitter::ABI_CallFunctionCCC(const void *func, u32 param1, u32 param2, u32 } } -void XEmitter::ABI_CallFunctionCCP(const void *func, u32 param1, u32 param2, void *param3) { +void XEmitter::ABI_CallFunctionCCP(const void* func, u32 param1, u32 param2, void* param3) { MOV(32, R(ABI_PARAM1), Imm32(param1)); MOV(32, R(ABI_PARAM2), Imm32(param2)); MOV(64, R(ABI_PARAM3), ImmPtr(param3)); u64 distance = u64(func) - (u64(code) + 5); - if (distance >= 0x0000000080000000ULL - && distance < 0xFFFFFFFF80000000ULL) { + if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { // Far call MOV(64, R(RAX), ImmPtr(func)); CALLptr(R(RAX)); @@ -182,14 +180,14 @@ void XEmitter::ABI_CallFunctionCCP(const void *func, u32 param1, u32 param2, voi } } -void XEmitter::ABI_CallFunctionCCCP(const void *func, u32 param1, u32 param2, u32 param3, void *param4) { +void XEmitter::ABI_CallFunctionCCCP(const void* func, u32 param1, u32 param2, u32 param3, + void* param4) { MOV(32, R(ABI_PARAM1), Imm32(param1)); MOV(32, R(ABI_PARAM2), Imm32(param2)); MOV(32, R(ABI_PARAM3), Imm32(param3)); MOV(64, R(ABI_PARAM4), ImmPtr(param4)); u64 distance = u64(func) - (u64(code) + 5); - if (distance >= 0x0000000080000000ULL - && distance < 0xFFFFFFFF80000000ULL) { + if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { // Far call MOV(64, R(RAX), ImmPtr(func)); CALLptr(R(RAX)); @@ -198,11 +196,10 @@ void XEmitter::ABI_CallFunctionCCCP(const void *func, u32 param1, u32 param2, u3 } } -void XEmitter::ABI_CallFunctionP(const void *func, void *param1) { +void XEmitter::ABI_CallFunctionP(const void* func, void* param1) { MOV(64, R(ABI_PARAM1), ImmPtr(param1)); u64 distance = u64(func) - (u64(code) + 5); - if (distance >= 0x0000000080000000ULL - && distance < 0xFFFFFFFF80000000ULL) { + if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { // Far call MOV(64, R(RAX), ImmPtr(func)); CALLptr(R(RAX)); @@ -211,13 +208,12 @@ void XEmitter::ABI_CallFunctionP(const void *func, void *param1) { } } -void XEmitter::ABI_CallFunctionPA(const void *func, void *param1, const Gen::OpArg &arg2) { +void XEmitter::ABI_CallFunctionPA(const void* func, void* param1, const Gen::OpArg& arg2) { MOV(64, R(ABI_PARAM1), ImmPtr(param1)); if (!arg2.IsSimpleReg(ABI_PARAM2)) MOV(32, R(ABI_PARAM2), arg2); u64 distance = u64(func) - (u64(code) + 5); - if (distance >= 0x0000000080000000ULL - && distance < 0xFFFFFFFF80000000ULL) { + if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { // Far call MOV(64, R(RAX), ImmPtr(func)); CALLptr(R(RAX)); @@ -226,15 +222,15 @@ void XEmitter::ABI_CallFunctionPA(const void *func, void *param1, const Gen::OpA } } -void XEmitter::ABI_CallFunctionPAA(const void *func, void *param1, const Gen::OpArg &arg2, const Gen::OpArg &arg3) { +void XEmitter::ABI_CallFunctionPAA(const void* func, void* param1, const Gen::OpArg& arg2, + const Gen::OpArg& arg3) { MOV(64, R(ABI_PARAM1), ImmPtr(param1)); if (!arg2.IsSimpleReg(ABI_PARAM2)) MOV(32, R(ABI_PARAM2), arg2); if (!arg3.IsSimpleReg(ABI_PARAM3)) MOV(32, R(ABI_PARAM3), arg3); u64 distance = u64(func) - (u64(code) + 5); - if (distance >= 0x0000000080000000ULL - && distance < 0xFFFFFFFF80000000ULL) { + if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { // Far call MOV(64, R(RAX), ImmPtr(func)); CALLptr(R(RAX)); @@ -243,13 +239,12 @@ void XEmitter::ABI_CallFunctionPAA(const void *func, void *param1, const Gen::Op } } -void XEmitter::ABI_CallFunctionPPC(const void *func, void *param1, void *param2, u32 param3) { +void XEmitter::ABI_CallFunctionPPC(const void* func, void* param1, void* param2, u32 param3) { MOV(64, R(ABI_PARAM1), ImmPtr(param1)); MOV(64, R(ABI_PARAM2), ImmPtr(param2)); MOV(32, R(ABI_PARAM3), Imm32(param3)); u64 distance = u64(func) - (u64(code) + 5); - if (distance >= 0x0000000080000000ULL - && distance < 0xFFFFFFFF80000000ULL) { + if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { // Far call MOV(64, R(RAX), ImmPtr(func)); CALLptr(R(RAX)); @@ -259,12 +254,11 @@ void XEmitter::ABI_CallFunctionPPC(const void *func, void *param1, void *param2, } // Pass a register as a parameter. -void XEmitter::ABI_CallFunctionR(const void *func, X64Reg reg1) { +void XEmitter::ABI_CallFunctionR(const void* func, X64Reg reg1) { if (reg1 != ABI_PARAM1) MOV(32, R(ABI_PARAM1), R(reg1)); u64 distance = u64(func) - (u64(code) + 5); - if (distance >= 0x0000000080000000ULL - && distance < 0xFFFFFFFF80000000ULL) { + if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { // Far call MOV(64, R(RAX), ImmPtr(func)); CALLptr(R(RAX)); @@ -274,7 +268,7 @@ void XEmitter::ABI_CallFunctionR(const void *func, X64Reg reg1) { } // Pass two registers as parameters. -void XEmitter::ABI_CallFunctionRR(const void *func, X64Reg reg1, X64Reg reg2) { +void XEmitter::ABI_CallFunctionRR(const void* func, X64Reg reg1, X64Reg reg2) { if (reg2 != ABI_PARAM1) { if (reg1 != ABI_PARAM1) MOV(64, R(ABI_PARAM1), R(reg1)); @@ -287,8 +281,7 @@ void XEmitter::ABI_CallFunctionRR(const void *func, X64Reg reg1, X64Reg reg2) { MOV(64, R(ABI_PARAM1), R(reg1)); } u64 distance = u64(func) - (u64(code) + 5); - if (distance >= 0x0000000080000000ULL - && distance < 0xFFFFFFFF80000000ULL) { + if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { // Far call MOV(64, R(RAX), ImmPtr(func)); CALLptr(R(RAX)); @@ -297,14 +290,12 @@ void XEmitter::ABI_CallFunctionRR(const void *func, X64Reg reg1, X64Reg reg2) { } } -void XEmitter::ABI_CallFunctionAC(const void *func, const Gen::OpArg &arg1, u32 param2) -{ +void XEmitter::ABI_CallFunctionAC(const void* func, const Gen::OpArg& arg1, u32 param2) { if (!arg1.IsSimpleReg(ABI_PARAM1)) MOV(32, R(ABI_PARAM1), arg1); MOV(32, R(ABI_PARAM2), Imm32(param2)); u64 distance = u64(func) - (u64(code) + 5); - if (distance >= 0x0000000080000000ULL - && distance < 0xFFFFFFFF80000000ULL) { + if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { // Far call MOV(64, R(RAX), ImmPtr(func)); CALLptr(R(RAX)); @@ -313,15 +304,14 @@ void XEmitter::ABI_CallFunctionAC(const void *func, const Gen::OpArg &arg1, u32 } } -void XEmitter::ABI_CallFunctionACC(const void *func, const Gen::OpArg &arg1, u32 param2, u32 param3) -{ +void XEmitter::ABI_CallFunctionACC(const void* func, const Gen::OpArg& arg1, u32 param2, + u32 param3) { if (!arg1.IsSimpleReg(ABI_PARAM1)) MOV(32, R(ABI_PARAM1), arg1); MOV(32, R(ABI_PARAM2), Imm32(param2)); MOV(64, R(ABI_PARAM3), Imm64(param3)); u64 distance = u64(func) - (u64(code) + 5); - if (distance >= 0x0000000080000000ULL - && distance < 0xFFFFFFFF80000000ULL) { + if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { // Far call MOV(64, R(RAX), ImmPtr(func)); CALLptr(R(RAX)); @@ -330,13 +320,11 @@ void XEmitter::ABI_CallFunctionACC(const void *func, const Gen::OpArg &arg1, u32 } } -void XEmitter::ABI_CallFunctionA(const void *func, const Gen::OpArg &arg1) -{ +void XEmitter::ABI_CallFunctionA(const void* func, const Gen::OpArg& arg1) { if (!arg1.IsSimpleReg(ABI_PARAM1)) MOV(32, R(ABI_PARAM1), arg1); u64 distance = u64(func) - (u64(code) + 5); - if (distance >= 0x0000000080000000ULL - && distance < 0xFFFFFFFF80000000ULL) { + if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { // Far call MOV(64, R(RAX), ImmPtr(func)); CALLptr(R(RAX)); @@ -345,15 +333,14 @@ void XEmitter::ABI_CallFunctionA(const void *func, const Gen::OpArg &arg1) } } -void XEmitter::ABI_CallFunctionAA(const void *func, const Gen::OpArg &arg1, const Gen::OpArg &arg2) -{ +void XEmitter::ABI_CallFunctionAA(const void* func, const Gen::OpArg& arg1, + const Gen::OpArg& arg2) { if (!arg1.IsSimpleReg(ABI_PARAM1)) MOV(32, R(ABI_PARAM1), arg1); if (!arg2.IsSimpleReg(ABI_PARAM2)) MOV(32, R(ABI_PARAM2), arg2); u64 distance = u64(func) - (u64(code) + 5); - if (distance >= 0x0000000080000000ULL - && distance < 0xFFFFFFFF80000000ULL) { + if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) { // Far call MOV(64, R(RAX), ImmPtr(func)); CALLptr(R(RAX)); diff --git a/src/common/x64/abi.h b/src/common/x64/abi.h index de6d62fdd..eaaf81d89 100644 --- a/src/common/x64/abi.h +++ b/src/common/x64/abi.h @@ -12,7 +12,8 @@ // Windows 64-bit // * 4-reg "fastcall" variant, very new-skool stack handling -// * Callee moves stack pointer, to make room for shadow regs for the biggest function _it itself calls_ +// * Callee moves stack pointer, to make room for shadow regs for the biggest function _it itself +// calls_ // * Parameters passed in RCX, RDX, ... further parameters are MOVed into the allocated stack space. // Scratch: RAX RCX RDX R8 R9 R10 R11 // Callee-save: RBX RSI RDI RBP R12 R13 R14 R15 @@ -35,10 +36,10 @@ #define ABI_PARAM4 R9 // xmm0-xmm15 use the upper 16 bits in the functions that push/pop registers. -#define ABI_ALL_CALLER_SAVED \ - (BitSet32 { RAX, RCX, RDX, R8, R9, R10, R11, \ - XMM0+16, XMM1+16, XMM2+16, XMM3+16, XMM4+16, XMM5+16 }) -#else //64-bit Unix / OS X +#define ABI_ALL_CALLER_SAVED \ + (BitSet32{RAX, RCX, RDX, R8, R9, R10, R11, XMM0 + 16, XMM1 + 16, XMM2 + 16, XMM3 + 16, \ + XMM4 + 16, XMM5 + 16}) +#else // 64-bit Unix / OS X #define ABI_PARAM1 RDI #define ABI_PARAM2 RSI @@ -49,9 +50,7 @@ // TODO: Avoid pushing all 16 XMM registers when possible. Most functions we call probably // don't actually clobber them. -#define ABI_ALL_CALLER_SAVED \ - (BitSet32 { RAX, RCX, RDX, RDI, RSI, R8, R9, R10, R11 } | \ - ABI_ALL_FPRS) +#define ABI_ALL_CALLER_SAVED (BitSet32{RAX, RCX, RDX, RDI, RSI, R8, R9, R10, R11} | ABI_ALL_FPRS) #endif // WIN32 #define ABI_ALL_CALLEE_SAVED (~ABI_ALL_CALLER_SAVED) diff --git a/src/common/x64/cpu_detect.cpp b/src/common/x64/cpu_detect.cpp index d9c430c67..6ddf9b70c 100644 --- a/src/common/x64/cpu_detect.cpp +++ b/src/common/x64/cpu_detect.cpp @@ -5,9 +5,7 @@ #include <cstring> #include <string> #include <thread> - #include "common/common_types.h" - #include "cpu_detect.h" namespace Common { @@ -15,8 +13,8 @@ namespace Common { #ifndef _MSC_VER #ifdef __FreeBSD__ -#include <sys/types.h> #include <machine/cpufunc.h> +#include <sys/types.h> #endif static inline void __cpuidex(int info[4], int function_id, int subfunction_id) { @@ -26,15 +24,9 @@ static inline void __cpuidex(int info[4], int function_id, int subfunction_id) { #else info[0] = function_id; // eax info[2] = subfunction_id; // ecx - __asm__( - "cpuid" - : "=a" (info[0]), - "=b" (info[1]), - "=c" (info[2]), - "=d" (info[3]) - : "a" (function_id), - "c" (subfunction_id) - ); + __asm__("cpuid" + : "=a"(info[0]), "=b"(info[1]), "=c"(info[2]), "=d"(info[3]) + : "a"(function_id), "c"(subfunction_id)); #endif } @@ -88,14 +80,22 @@ static CPUCaps Detect() { if (max_std_fn >= 1) { __cpuid(cpu_id, 0x00000001); - if ((cpu_id[3] >> 25) & 1) caps.sse = true; - if ((cpu_id[3] >> 26) & 1) caps.sse2 = true; - if ((cpu_id[2]) & 1) caps.sse3 = true; - if ((cpu_id[2] >> 9) & 1) caps.ssse3 = true; - if ((cpu_id[2] >> 19) & 1) caps.sse4_1 = true; - if ((cpu_id[2] >> 20) & 1) caps.sse4_2 = true; - if ((cpu_id[2] >> 22) & 1) caps.movbe = true; - if ((cpu_id[2] >> 25) & 1) caps.aes = true; + if ((cpu_id[3] >> 25) & 1) + caps.sse = true; + if ((cpu_id[3] >> 26) & 1) + caps.sse2 = true; + if ((cpu_id[2]) & 1) + caps.sse3 = true; + if ((cpu_id[2] >> 9) & 1) + caps.ssse3 = true; + if ((cpu_id[2] >> 19) & 1) + caps.sse4_1 = true; + if ((cpu_id[2] >> 20) & 1) + caps.sse4_2 = true; + if ((cpu_id[2] >> 22) & 1) + caps.movbe = true; + if ((cpu_id[2] >> 25) & 1) + caps.aes = true; if ((cpu_id[3] >> 24) & 1) { caps.fxsave_fxrstor = true; @@ -140,10 +140,14 @@ static CPUCaps Detect() { if (max_ex_fn >= 0x80000001) { // Check for more features __cpuid(cpu_id, 0x80000001); - if (cpu_id[2] & 1) caps.lahf_sahf_64 = true; - if ((cpu_id[2] >> 5) & 1) caps.lzcnt = true; - if ((cpu_id[2] >> 16) & 1) caps.fma4 = true; - if ((cpu_id[3] >> 29) & 1) caps.long_mode = true; + if (cpu_id[2] & 1) + caps.lahf_sahf_64 = true; + if ((cpu_id[2] >> 5) & 1) + caps.lzcnt = true; + if ((cpu_id[2] >> 16) & 1) + caps.fma4 = true; + if ((cpu_id[3] >> 29) & 1) + caps.long_mode = true; } return caps; @@ -162,24 +166,38 @@ std::string GetCPUCapsString() { sum += caps.brand_string; sum += ")"; - if (caps.sse) sum += ", SSE"; + if (caps.sse) + sum += ", SSE"; if (caps.sse2) { sum += ", SSE2"; - if (!caps.flush_to_zero) sum += " (without DAZ)"; + if (!caps.flush_to_zero) + sum += " (without DAZ)"; } - if (caps.sse3) sum += ", SSE3"; - if (caps.ssse3) sum += ", SSSE3"; - if (caps.sse4_1) sum += ", SSE4.1"; - if (caps.sse4_2) sum += ", SSE4.2"; - if (caps.avx) sum += ", AVX"; - if (caps.avx2) sum += ", AVX2"; - if (caps.bmi1) sum += ", BMI1"; - if (caps.bmi2) sum += ", BMI2"; - if (caps.fma) sum += ", FMA"; - if (caps.aes) sum += ", AES"; - if (caps.movbe) sum += ", MOVBE"; - if (caps.long_mode) sum += ", 64-bit support"; + if (caps.sse3) + sum += ", SSE3"; + if (caps.ssse3) + sum += ", SSSE3"; + if (caps.sse4_1) + sum += ", SSE4.1"; + if (caps.sse4_2) + sum += ", SSE4.2"; + if (caps.avx) + sum += ", AVX"; + if (caps.avx2) + sum += ", AVX2"; + if (caps.bmi1) + sum += ", BMI1"; + if (caps.bmi2) + sum += ", BMI2"; + if (caps.fma) + sum += ", FMA"; + if (caps.aes) + sum += ", AES"; + if (caps.movbe) + sum += ", MOVBE"; + if (caps.long_mode) + sum += ", 64-bit support"; return sum; } diff --git a/src/common/x64/emitter.cpp b/src/common/x64/emitter.cpp index 5662f7f86..f5930abec 100644 --- a/src/common/x64/emitter.cpp +++ b/src/common/x64/emitter.cpp @@ -17,188 +17,169 @@ #include <cinttypes> #include <cstring> - +#include "abi.h" #include "common/assert.h" #include "common/logging/log.h" #include "common/memory_util.h" - -#include "abi.h" #include "cpu_detect.h" #include "emitter.h" -namespace Gen -{ +namespace Gen { -struct NormalOpDef -{ +struct NormalOpDef { u8 toRm8, toRm32, fromRm8, fromRm32, imm8, imm32, simm8, eaximm8, eaximm32, ext; }; // 0xCC is code for invalid combination of immediates -static const NormalOpDef normalops[11] = -{ - {0x00, 0x01, 0x02, 0x03, 0x80, 0x81, 0x83, 0x04, 0x05, 0}, //ADD - {0x10, 0x11, 0x12, 0x13, 0x80, 0x81, 0x83, 0x14, 0x15, 2}, //ADC +static const NormalOpDef normalops[11] = { + {0x00, 0x01, 0x02, 0x03, 0x80, 0x81, 0x83, 0x04, 0x05, 0}, // ADD + {0x10, 0x11, 0x12, 0x13, 0x80, 0x81, 0x83, 0x14, 0x15, 2}, // ADC - {0x28, 0x29, 0x2A, 0x2B, 0x80, 0x81, 0x83, 0x2C, 0x2D, 5}, //SUB - {0x18, 0x19, 0x1A, 0x1B, 0x80, 0x81, 0x83, 0x1C, 0x1D, 3}, //SBB + {0x28, 0x29, 0x2A, 0x2B, 0x80, 0x81, 0x83, 0x2C, 0x2D, 5}, // SUB + {0x18, 0x19, 0x1A, 0x1B, 0x80, 0x81, 0x83, 0x1C, 0x1D, 3}, // SBB - {0x20, 0x21, 0x22, 0x23, 0x80, 0x81, 0x83, 0x24, 0x25, 4}, //AND - {0x08, 0x09, 0x0A, 0x0B, 0x80, 0x81, 0x83, 0x0C, 0x0D, 1}, //OR + {0x20, 0x21, 0x22, 0x23, 0x80, 0x81, 0x83, 0x24, 0x25, 4}, // AND + {0x08, 0x09, 0x0A, 0x0B, 0x80, 0x81, 0x83, 0x0C, 0x0D, 1}, // OR - {0x30, 0x31, 0x32, 0x33, 0x80, 0x81, 0x83, 0x34, 0x35, 6}, //XOR - {0x88, 0x89, 0x8A, 0x8B, 0xC6, 0xC7, 0xCC, 0xCC, 0xCC, 0}, //MOV + {0x30, 0x31, 0x32, 0x33, 0x80, 0x81, 0x83, 0x34, 0x35, 6}, // XOR + {0x88, 0x89, 0x8A, 0x8B, 0xC6, 0xC7, 0xCC, 0xCC, 0xCC, 0}, // MOV - {0x84, 0x85, 0x84, 0x85, 0xF6, 0xF7, 0xCC, 0xA8, 0xA9, 0}, //TEST (to == from) - {0x38, 0x39, 0x3A, 0x3B, 0x80, 0x81, 0x83, 0x3C, 0x3D, 7}, //CMP + {0x84, 0x85, 0x84, 0x85, 0xF6, 0xF7, 0xCC, 0xA8, 0xA9, 0}, // TEST (to == from) + {0x38, 0x39, 0x3A, 0x3B, 0x80, 0x81, 0x83, 0x3C, 0x3D, 7}, // CMP - {0x86, 0x87, 0x86, 0x87, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 7}, //XCHG + {0x86, 0x87, 0x86, 0x87, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 7}, // XCHG }; -enum NormalSSEOps -{ - sseCMP = 0xC2, - sseADD = 0x58, //ADD - sseSUB = 0x5C, //SUB - sseAND = 0x54, //AND - sseANDN = 0x55, //ANDN - sseOR = 0x56, - sseXOR = 0x57, - sseMUL = 0x59, //MUL - sseDIV = 0x5E, //DIV - sseMIN = 0x5D, //MIN - sseMAX = 0x5F, //MAX - sseCOMIS = 0x2F, //COMIS - sseUCOMIS = 0x2E, //UCOMIS - sseSQRT = 0x51, //SQRT - sseRSQRT = 0x52, //RSQRT (NO DOUBLE PRECISION!!!) - sseRCP = 0x53, //RCP - sseMOVAPfromRM = 0x28, //MOVAP from RM - sseMOVAPtoRM = 0x29, //MOVAP to RM - sseMOVUPfromRM = 0x10, //MOVUP from RM - sseMOVUPtoRM = 0x11, //MOVUP to RM - sseMOVLPfromRM= 0x12, - sseMOVLPtoRM = 0x13, - sseMOVHPfromRM= 0x16, - sseMOVHPtoRM = 0x17, - sseMOVHLPS = 0x12, - sseMOVLHPS = 0x16, +enum NormalSSEOps { + sseCMP = 0xC2, + sseADD = 0x58, // ADD + sseSUB = 0x5C, // SUB + sseAND = 0x54, // AND + sseANDN = 0x55, // ANDN + sseOR = 0x56, + sseXOR = 0x57, + sseMUL = 0x59, // MUL + sseDIV = 0x5E, // DIV + sseMIN = 0x5D, // MIN + sseMAX = 0x5F, // MAX + sseCOMIS = 0x2F, // COMIS + sseUCOMIS = 0x2E, // UCOMIS + sseSQRT = 0x51, // SQRT + sseRSQRT = 0x52, // RSQRT (NO DOUBLE PRECISION!!!) + sseRCP = 0x53, // RCP + sseMOVAPfromRM = 0x28, // MOVAP from RM + sseMOVAPtoRM = 0x29, // MOVAP to RM + sseMOVUPfromRM = 0x10, // MOVUP from RM + sseMOVUPtoRM = 0x11, // MOVUP to RM + sseMOVLPfromRM = 0x12, + sseMOVLPtoRM = 0x13, + sseMOVHPfromRM = 0x16, + sseMOVHPtoRM = 0x17, + sseMOVHLPS = 0x12, + sseMOVLHPS = 0x16, sseMOVDQfromRM = 0x6F, - sseMOVDQtoRM = 0x7F, - sseMASKMOVDQU = 0xF7, - sseLDDQU = 0xF0, - sseSHUF = 0xC6, - sseMOVNTDQ = 0xE7, - sseMOVNTP = 0x2B, - sseHADD = 0x7C, + sseMOVDQtoRM = 0x7F, + sseMASKMOVDQU = 0xF7, + sseLDDQU = 0xF0, + sseSHUF = 0xC6, + sseMOVNTDQ = 0xE7, + sseMOVNTP = 0x2B, + sseHADD = 0x7C, }; - -void XEmitter::SetCodePtr(u8 *ptr) -{ +void XEmitter::SetCodePtr(u8* ptr) { code = ptr; } -const u8 *XEmitter::GetCodePtr() const -{ +const u8* XEmitter::GetCodePtr() const { return code; } -u8 *XEmitter::GetWritableCodePtr() -{ +u8* XEmitter::GetWritableCodePtr() { return code; } -void XEmitter::Write8(u8 value) -{ +void XEmitter::Write8(u8 value) { *code++ = value; } -void XEmitter::Write16(u16 value) -{ +void XEmitter::Write16(u16 value) { std::memcpy(code, &value, sizeof(u16)); code += sizeof(u16); } -void XEmitter::Write32(u32 value) -{ +void XEmitter::Write32(u32 value) { std::memcpy(code, &value, sizeof(u32)); code += sizeof(u32); } -void XEmitter::Write64(u64 value) -{ +void XEmitter::Write64(u64 value) { std::memcpy(code, &value, sizeof(u64)); code += sizeof(u64); } -void XEmitter::ReserveCodeSpace(int bytes) -{ +void XEmitter::ReserveCodeSpace(int bytes) { for (int i = 0; i < bytes; i++) *code++ = 0xCC; } -const u8 *XEmitter::AlignCode4() -{ +const u8* XEmitter::AlignCode4() { int c = int((u64)code & 3); if (c) - ReserveCodeSpace(4-c); + ReserveCodeSpace(4 - c); return code; } -const u8 *XEmitter::AlignCode16() -{ +const u8* XEmitter::AlignCode16() { int c = int((u64)code & 15); if (c) - ReserveCodeSpace(16-c); + ReserveCodeSpace(16 - c); return code; } -const u8 *XEmitter::AlignCodePage() -{ +const u8* XEmitter::AlignCodePage() { int c = int((u64)code & 4095); if (c) - ReserveCodeSpace(4096-c); + ReserveCodeSpace(4096 - c); return code; } // This operation modifies flags; check to see the flags are locked. // If the flags are locked, we should immediately and loudly fail before // causing a subtle JIT bug. -void XEmitter::CheckFlags() -{ +void XEmitter::CheckFlags() { ASSERT_MSG(!flags_locked, "Attempt to modify flags while flags locked!"); } -void XEmitter::WriteModRM(int mod, int reg, int rm) -{ +void XEmitter::WriteModRM(int mod, int reg, int rm) { Write8((u8)((mod << 6) | ((reg & 7) << 3) | (rm & 7))); } -void XEmitter::WriteSIB(int scale, int index, int base) -{ +void XEmitter::WriteSIB(int scale, int index, int base) { Write8((u8)((scale << 6) | ((index & 7) << 3) | (base & 7))); } -void OpArg::WriteRex(XEmitter *emit, int opBits, int bits, int customOp) const -{ - if (customOp == -1) customOp = operandReg; +void OpArg::WriteRex(XEmitter* emit, int opBits, int bits, int customOp) const { + if (customOp == -1) + customOp = operandReg; #ifdef ARCHITECTURE_x86_64 u8 op = 0x40; // REX.W (whether operation is a 64-bit operation) - if (opBits == 64) op |= 8; + if (opBits == 64) + op |= 8; // REX.R (whether ModR/M reg field refers to R8-R15. - if (customOp & 8) op |= 4; + if (customOp & 8) + op |= 4; // REX.X (whether ModR/M SIB index field refers to R8-R15) - if (indexReg & 8) op |= 2; + if (indexReg & 8) + op |= 2; // REX.B (whether ModR/M rm or SIB base or opcode reg field refers to R8-R15) - if (offsetOrBaseReg & 8) op |= 1; + if (offsetOrBaseReg & 8) + op |= 1; // Write REX if wr have REX bits to write, or if the operation accesses // SIL, DIL, BPL, or SPL. - if (op != 0x40 || - (scale == SCALE_NONE && bits == 8 && (offsetOrBaseReg & 0x10c) == 4) || - (opBits == 8 && (customOp & 0x10c) == 4)) - { + if (op != 0x40 || (scale == SCALE_NONE && bits == 8 && (offsetOrBaseReg & 0x10c) == 4) || + (opBits == 8 && (customOp & 0x10c) == 4)) { emit->Write8(op); // Check the operation doesn't access AH, BH, CH, or DH. DEBUG_ASSERT((offsetOrBaseReg & 0x100) == 0); @@ -214,8 +195,8 @@ void OpArg::WriteRex(XEmitter *emit, int opBits, int bits, int customOp) const #endif } -void OpArg::WriteVex(XEmitter* emit, X64Reg regOp1, X64Reg regOp2, int L, int pp, int mmmmm, int W) const -{ +void OpArg::WriteVex(XEmitter* emit, X64Reg regOp1, X64Reg regOp2, int L, int pp, int mmmmm, + int W) const { int R = !(regOp1 & 8); int X = !(indexReg & 8); int B = !(offsetOrBaseReg & 8); @@ -223,14 +204,11 @@ void OpArg::WriteVex(XEmitter* emit, X64Reg regOp1, X64Reg regOp2, int L, int pp int vvvv = (regOp2 == X64Reg::INVALID_REG) ? 0xf : (regOp2 ^ 0xf); // do we need any VEX fields that only appear in the three-byte form? - if (X == 1 && B == 1 && W == 0 && mmmmm == 1) - { + if (X == 1 && B == 1 && W == 0 && mmmmm == 1) { u8 RvvvvLpp = (R << 7) | (vvvv << 3) | (L << 2) | pp; emit->Write8(0xC5); emit->Write8(RvvvvLpp); - } - else - { + } else { u8 RXBmmmmm = (R << 7) | (X << 6) | (B << 5) | mmmmm; u8 WvvvvLpp = (W << 7) | (vvvv << 3) | (L << 2) | pp; emit->Write8(0xC4); @@ -239,9 +217,8 @@ void OpArg::WriteVex(XEmitter* emit, X64Reg regOp1, X64Reg regOp2, int L, int pp } } -void OpArg::WriteRest(XEmitter *emit, int extraBytes, X64Reg _operandReg, - bool warn_64bit_offset) const -{ +void OpArg::WriteRest(XEmitter* emit, int extraBytes, X64Reg _operandReg, + bool warn_64bit_offset) const { if (_operandReg == INVALID_REG) _operandReg = (X64Reg)this->operandReg; int mod = 0; @@ -249,21 +226,18 @@ void OpArg::WriteRest(XEmitter *emit, int extraBytes, X64Reg _operandReg, bool SIB = false; int _offsetOrBaseReg = this->offsetOrBaseReg; - if (scale == SCALE_RIP) //Also, on 32-bit, just an immediate address + if (scale == SCALE_RIP) // Also, on 32-bit, just an immediate address { // Oh, RIP addressing. _offsetOrBaseReg = 5; emit->WriteModRM(0, _operandReg, _offsetOrBaseReg); - //TODO : add some checks +// TODO : add some checks #ifdef ARCHITECTURE_x86_64 u64 ripAddr = (u64)emit->GetCodePtr() + 4 + extraBytes; s64 distance = (s64)offset - (s64)ripAddr; - ASSERT_MSG( - (distance < 0x80000000LL && - distance >= -0x80000000LL) || - !warn_64bit_offset, - "WriteRest: op out of range (0x%" PRIx64 " uses 0x%" PRIx64 ")", - ripAddr, offset); + ASSERT_MSG((distance < 0x80000000LL && distance >= -0x80000000LL) || !warn_64bit_offset, + "WriteRest: op out of range (0x%" PRIx64 " uses 0x%" PRIx64 ")", ripAddr, + offset); s32 offs = (s32)distance; emit->Write32((u32)offs); #else @@ -272,66 +246,49 @@ void OpArg::WriteRest(XEmitter *emit, int extraBytes, X64Reg _operandReg, return; } - if (scale == 0) - { + if (scale == 0) { // Oh, no memory, Just a reg. - mod = 3; //11 - } - else if (scale >= 1) - { - //Ah good, no scaling. - if (scale == SCALE_ATREG && !((_offsetOrBaseReg & 7) == 4 || (_offsetOrBaseReg & 7) == 5)) - { - //Okay, we're good. No SIB necessary. + mod = 3; // 11 + } else if (scale >= 1) { + // Ah good, no scaling. + if (scale == SCALE_ATREG && !((_offsetOrBaseReg & 7) == 4 || (_offsetOrBaseReg & 7) == 5)) { + // Okay, we're good. No SIB necessary. int ioff = (int)offset; - if (ioff == 0) - { + if (ioff == 0) { mod = 0; + } else if (ioff < -128 || ioff > 127) { + mod = 2; // 32-bit displacement + } else { + mod = 1; // 8-bit displacement } - else if (ioff<-128 || ioff>127) - { - mod = 2; //32-bit displacement - } - else - { - mod = 1; //8-bit displacement - } - } - else if (scale >= SCALE_NOBASE_2 && scale <= SCALE_NOBASE_8) - { + } else if (scale >= SCALE_NOBASE_2 && scale <= SCALE_NOBASE_8) { SIB = true; mod = 0; _offsetOrBaseReg = 5; - } - else //if (scale != SCALE_ATREG) + } else // if (scale != SCALE_ATREG) { - if ((_offsetOrBaseReg & 7) == 4) //this would occupy the SIB encoding :( + if ((_offsetOrBaseReg & 7) == 4) // this would occupy the SIB encoding :( { - //So we have to fake it with SIB encoding :( + // So we have to fake it with SIB encoding :( SIB = true; } - if (scale >= SCALE_1 && scale < SCALE_ATREG) - { + if (scale >= SCALE_1 && scale < SCALE_ATREG) { SIB = true; } - if (scale == SCALE_ATREG && ((_offsetOrBaseReg & 7) == 4)) - { + if (scale == SCALE_ATREG && ((_offsetOrBaseReg & 7) == 4)) { SIB = true; ireg = _offsetOrBaseReg; } - //Okay, we're fine. Just disp encoding. - //We need displacement. Which size? + // Okay, we're fine. Just disp encoding. + // We need displacement. Which size? int ioff = (int)(s64)offset; - if (ioff < -128 || ioff > 127) - { - mod = 2; //32-bit displacement - } - else - { - mod = 1; //8-bit displacement + if (ioff < -128 || ioff > 127) { + mod = 2; // 32-bit displacement + } else { + mod = 1; // 8-bit displacement } } } @@ -343,36 +300,55 @@ void OpArg::WriteRest(XEmitter *emit, int extraBytes, X64Reg _operandReg, oreg = 4; // TODO(ector): WTF is this if about? I don't remember writing it :-) - //if (RIP) + // if (RIP) // oreg = 5; - emit->WriteModRM(mod, _operandReg&7, oreg&7); + emit->WriteModRM(mod, _operandReg & 7, oreg & 7); - if (SIB) - { - //SIB byte + if (SIB) { + // SIB byte int ss; - switch (scale) - { - case SCALE_NONE: _offsetOrBaseReg = 4; ss = 0; break; //RSP - case SCALE_1: ss = 0; break; - case SCALE_2: ss = 1; break; - case SCALE_4: ss = 2; break; - case SCALE_8: ss = 3; break; - case SCALE_NOBASE_2: ss = 1; break; - case SCALE_NOBASE_4: ss = 2; break; - case SCALE_NOBASE_8: ss = 3; break; - case SCALE_ATREG: ss = 0; break; - default: ASSERT_MSG(0, "Invalid scale for SIB byte"); ss = 0; break; + switch (scale) { + case SCALE_NONE: + _offsetOrBaseReg = 4; + ss = 0; + break; // RSP + case SCALE_1: + ss = 0; + break; + case SCALE_2: + ss = 1; + break; + case SCALE_4: + ss = 2; + break; + case SCALE_8: + ss = 3; + break; + case SCALE_NOBASE_2: + ss = 1; + break; + case SCALE_NOBASE_4: + ss = 2; + break; + case SCALE_NOBASE_8: + ss = 3; + break; + case SCALE_ATREG: + ss = 0; + break; + default: + ASSERT_MSG(0, "Invalid scale for SIB byte"); + ss = 0; + break; } - emit->Write8((u8)((ss << 6) | ((ireg&7)<<3) | (_offsetOrBaseReg&7))); + emit->Write8((u8)((ss << 6) | ((ireg & 7) << 3) | (_offsetOrBaseReg & 7))); } - if (mod == 1) //8-bit disp + if (mod == 1) // 8-bit disp { emit->Write8((u8)(s8)(s32)offset); - } - else if (mod == 2 || (scale >= SCALE_NOBASE_2 && scale <= SCALE_NOBASE_8)) //32-bit disp + } else if (mod == 2 || (scale >= SCALE_NOBASE_2 && scale <= SCALE_NOBASE_8)) // 32-bit disp { emit->Write32((u32)offset); } @@ -382,8 +358,7 @@ void OpArg::WriteRest(XEmitter *emit, int extraBytes, X64Reg _operandReg, // R = register# upper bit // X = scale amnt upper bit // B = base register# upper bit -void XEmitter::Rex(int w, int r, int x, int b) -{ +void XEmitter::Rex(int w, int r, int x, int b) { w = w ? 1 : 0; r = r ? 1 : 0; x = x ? 1 : 0; @@ -393,70 +368,60 @@ void XEmitter::Rex(int w, int r, int x, int b) Write8(rx); } -void XEmitter::JMP(const u8* addr, bool force5Bytes) -{ +void XEmitter::JMP(const u8* addr, bool force5Bytes) { u64 fn = (u64)addr; - if (!force5Bytes) - { + if (!force5Bytes) { s64 distance = (s64)(fn - ((u64)code + 2)); ASSERT_MSG(distance >= -0x80 && distance < 0x80, - "Jump target too far away, needs force5Bytes = true"); - //8 bits will do + "Jump target too far away, needs force5Bytes = true"); + // 8 bits will do Write8(0xEB); Write8((u8)(s8)distance); - } - else - { + } else { s64 distance = (s64)(fn - ((u64)code + 5)); - ASSERT_MSG( - distance >= -0x80000000LL && distance < 0x80000000LL, - "Jump target too far away, needs indirect register"); + ASSERT_MSG(distance >= -0x80000000LL && distance < 0x80000000LL, + "Jump target too far away, needs indirect register"); Write8(0xE9); Write32((u32)(s32)distance); } } -void XEmitter::JMPptr(const OpArg& arg2) -{ +void XEmitter::JMPptr(const OpArg& arg2) { OpArg arg = arg2; - if (arg.IsImm()) ASSERT_MSG(0, "JMPptr - Imm argument"); + if (arg.IsImm()) + ASSERT_MSG(0, "JMPptr - Imm argument"); arg.operandReg = 4; arg.WriteRex(this, 0, 0); Write8(0xFF); arg.WriteRest(this); } -//Can be used to trap other processors, before overwriting their code +// Can be used to trap other processors, before overwriting their code // not used in dolphin -void XEmitter::JMPself() -{ +void XEmitter::JMPself() { Write8(0xEB); Write8(0xFE); } -void XEmitter::CALLptr(OpArg arg) -{ - if (arg.IsImm()) ASSERT_MSG(0, "CALLptr - Imm argument"); +void XEmitter::CALLptr(OpArg arg) { + if (arg.IsImm()) + ASSERT_MSG(0, "CALLptr - Imm argument"); arg.operandReg = 2; arg.WriteRex(this, 0, 0); Write8(0xFF); arg.WriteRest(this); } -void XEmitter::CALL(const void* fnptr) -{ +void XEmitter::CALL(const void* fnptr) { u64 distance = u64(fnptr) - (u64(code) + 5); - ASSERT_MSG( - distance < 0x0000000080000000ULL || - distance >= 0xFFFFFFFF80000000ULL, - "CALL out of range (%p calls %p)", code, fnptr); + ASSERT_MSG(distance < 0x0000000080000000ULL || distance >= 0xFFFFFFFF80000000ULL, + "CALL out of range (%p calls %p)", code, fnptr); Write8(0xE8); Write32(u32(distance)); } -FixupBranch XEmitter::CALL() -{ +FixupBranch XEmitter::CALL() { FixupBranch branch; branch.type = 1; branch.ptr = code + 5; @@ -467,38 +432,30 @@ FixupBranch XEmitter::CALL() return branch; } -FixupBranch XEmitter::J(bool force5bytes) -{ +FixupBranch XEmitter::J(bool force5bytes) { FixupBranch branch; branch.type = force5bytes ? 1 : 0; branch.ptr = code + (force5bytes ? 5 : 2); - if (!force5bytes) - { - //8 bits will do + if (!force5bytes) { + // 8 bits will do Write8(0xEB); Write8(0); - } - else - { + } else { Write8(0xE9); Write32(0); } return branch; } -FixupBranch XEmitter::J_CC(CCFlags conditionCode, bool force5bytes) -{ +FixupBranch XEmitter::J_CC(CCFlags conditionCode, bool force5bytes) { FixupBranch branch; branch.type = force5bytes ? 1 : 0; branch.ptr = code + (force5bytes ? 6 : 2); - if (!force5bytes) - { - //8 bits will do + if (!force5bytes) { + // 8 bits will do Write8(0x70 + conditionCode); Write8(0); - } - else - { + } else { Write8(0x0F); Write8(0x80 + conditionCode); Write32(0); @@ -506,198 +463,268 @@ FixupBranch XEmitter::J_CC(CCFlags conditionCode, bool force5bytes) return branch; } -void XEmitter::J_CC(CCFlags conditionCode, const u8* addr, bool force5bytes) -{ +void XEmitter::J_CC(CCFlags conditionCode, const u8* addr, bool force5bytes) { u64 fn = (u64)addr; s64 distance = (s64)(fn - ((u64)code + 2)); - if (distance < -0x80 || distance >= 0x80 || force5bytes) - { + if (distance < -0x80 || distance >= 0x80 || force5bytes) { distance = (s64)(fn - ((u64)code + 6)); - ASSERT_MSG( - distance >= -0x80000000LL && distance < 0x80000000LL, - "Jump target too far away, needs indirect register"); + ASSERT_MSG(distance >= -0x80000000LL && distance < 0x80000000LL, + "Jump target too far away, needs indirect register"); Write8(0x0F); Write8(0x80 + conditionCode); Write32((u32)(s32)distance); - } - else - { + } else { Write8(0x70 + conditionCode); Write8((u8)(s8)distance); } } -void XEmitter::SetJumpTarget(const FixupBranch& branch) -{ - if (branch.type == 0) - { +void XEmitter::SetJumpTarget(const FixupBranch& branch) { + if (branch.type == 0) { s64 distance = (s64)(code - branch.ptr); - ASSERT_MSG(distance >= -0x80 && distance < 0x80, "Jump target too far away, needs force5Bytes = true"); + ASSERT_MSG(distance >= -0x80 && distance < 0x80, + "Jump target too far away, needs force5Bytes = true"); branch.ptr[-1] = (u8)(s8)distance; - } - else if (branch.type == 1) - { + } else if (branch.type == 1) { s64 distance = (s64)(code - branch.ptr); - ASSERT_MSG(distance >= -0x80000000LL && distance < 0x80000000LL, "Jump target too far away, needs indirect register"); + ASSERT_MSG(distance >= -0x80000000LL && distance < 0x80000000LL, + "Jump target too far away, needs indirect register"); ((s32*)branch.ptr)[-1] = (s32)distance; } } -void XEmitter::SetJumpTarget(const FixupBranch& branch, const u8* target) -{ - if (branch.type == 0) - { +void XEmitter::SetJumpTarget(const FixupBranch& branch, const u8* target) { + if (branch.type == 0) { s64 distance = (s64)(target - branch.ptr); - ASSERT_MSG(distance >= -0x80 && distance < 0x80, "Jump target too far away, needs force5Bytes = true"); + ASSERT_MSG(distance >= -0x80 && distance < 0x80, + "Jump target too far away, needs force5Bytes = true"); branch.ptr[-1] = (u8)(s8)distance; - } - else if (branch.type == 1) - { + } else if (branch.type == 1) { s64 distance = (s64)(target - branch.ptr); - ASSERT_MSG(distance >= -0x80000000LL && distance < 0x80000000LL, "Jump target too far away, needs indirect register"); + ASSERT_MSG(distance >= -0x80000000LL && distance < 0x80000000LL, + "Jump target too far away, needs indirect register"); ((s32*)branch.ptr)[-1] = (s32)distance; } } -//Single byte opcodes -//There is no PUSHAD/POPAD in 64-bit mode. -void XEmitter::INT3() {Write8(0xCC);} -void XEmitter::RET() {Write8(0xC3);} -void XEmitter::RET_FAST() {Write8(0xF3); Write8(0xC3);} //two-byte return (rep ret) - recommended by AMD optimization manual for the case of jumping to a ret +// Single byte opcodes +// There is no PUSHAD/POPAD in 64-bit mode. +void XEmitter::INT3() { + Write8(0xCC); +} +void XEmitter::RET() { + Write8(0xC3); +} +void XEmitter::RET_FAST() { + Write8(0xF3); + Write8(0xC3); +} // two-byte return (rep ret) - recommended by AMD optimization manual for the case of jumping to a + // ret // The first sign of decadence: optimized NOPs. -void XEmitter::NOP(size_t size) -{ +void XEmitter::NOP(size_t size) { DEBUG_ASSERT((int)size > 0); - while (true) - { - switch (size) - { + while (true) { + switch (size) { case 0: return; case 1: Write8(0x90); return; case 2: - Write8(0x66); Write8(0x90); + Write8(0x66); + Write8(0x90); return; case 3: - Write8(0x0F); Write8(0x1F); Write8(0x00); + Write8(0x0F); + Write8(0x1F); + Write8(0x00); return; case 4: - Write8(0x0F); Write8(0x1F); Write8(0x40); Write8(0x00); + Write8(0x0F); + Write8(0x1F); + Write8(0x40); + Write8(0x00); return; case 5: - Write8(0x0F); Write8(0x1F); Write8(0x44); Write8(0x00); + Write8(0x0F); + Write8(0x1F); + Write8(0x44); + Write8(0x00); Write8(0x00); return; case 6: - Write8(0x66); Write8(0x0F); Write8(0x1F); Write8(0x44); - Write8(0x00); Write8(0x00); + Write8(0x66); + Write8(0x0F); + Write8(0x1F); + Write8(0x44); + Write8(0x00); + Write8(0x00); return; case 7: - Write8(0x0F); Write8(0x1F); Write8(0x80); Write8(0x00); - Write8(0x00); Write8(0x00); Write8(0x00); + Write8(0x0F); + Write8(0x1F); + Write8(0x80); + Write8(0x00); + Write8(0x00); + Write8(0x00); + Write8(0x00); return; case 8: - Write8(0x0F); Write8(0x1F); Write8(0x84); Write8(0x00); - Write8(0x00); Write8(0x00); Write8(0x00); Write8(0x00); + Write8(0x0F); + Write8(0x1F); + Write8(0x84); + Write8(0x00); + Write8(0x00); + Write8(0x00); + Write8(0x00); + Write8(0x00); return; case 9: - Write8(0x66); Write8(0x0F); Write8(0x1F); Write8(0x84); - Write8(0x00); Write8(0x00); Write8(0x00); Write8(0x00); + Write8(0x66); + Write8(0x0F); + Write8(0x1F); + Write8(0x84); + Write8(0x00); + Write8(0x00); + Write8(0x00); + Write8(0x00); Write8(0x00); return; case 10: - Write8(0x66); Write8(0x66); Write8(0x0F); Write8(0x1F); - Write8(0x84); Write8(0x00); Write8(0x00); Write8(0x00); - Write8(0x00); Write8(0x00); + Write8(0x66); + Write8(0x66); + Write8(0x0F); + Write8(0x1F); + Write8(0x84); + Write8(0x00); + Write8(0x00); + Write8(0x00); + Write8(0x00); + Write8(0x00); return; default: // Even though x86 instructions are allowed to be up to 15 bytes long, // AMD advises against using NOPs longer than 11 bytes because they // carry a performance penalty on CPUs older than AMD family 16h. - Write8(0x66); Write8(0x66); Write8(0x66); Write8(0x0F); - Write8(0x1F); Write8(0x84); Write8(0x00); Write8(0x00); - Write8(0x00); Write8(0x00); Write8(0x00); + Write8(0x66); + Write8(0x66); + Write8(0x66); + Write8(0x0F); + Write8(0x1F); + Write8(0x84); + Write8(0x00); + Write8(0x00); + Write8(0x00); + Write8(0x00); + Write8(0x00); size -= 11; continue; } } } -void XEmitter::PAUSE() {Write8(0xF3); NOP();} //use in tight spinloops for energy saving on some cpu -void XEmitter::CLC() {CheckFlags(); Write8(0xF8);} //clear carry -void XEmitter::CMC() {CheckFlags(); Write8(0xF5);} //flip carry -void XEmitter::STC() {CheckFlags(); Write8(0xF9);} //set carry +void XEmitter::PAUSE() { + Write8(0xF3); + NOP(); +} // use in tight spinloops for energy saving on some cpu +void XEmitter::CLC() { + CheckFlags(); + Write8(0xF8); +} // clear carry +void XEmitter::CMC() { + CheckFlags(); + Write8(0xF5); +} // flip carry +void XEmitter::STC() { + CheckFlags(); + Write8(0xF9); +} // set carry -//TODO: xchg ah, al ??? -void XEmitter::XCHG_AHAL() -{ +// TODO: xchg ah, al ??? +void XEmitter::XCHG_AHAL() { Write8(0x86); Write8(0xe0); // alt. 86 c4 } -//These two can not be executed on early Intel 64-bit CPU:s, only on AMD! -void XEmitter::LAHF() {Write8(0x9F);} -void XEmitter::SAHF() {CheckFlags(); Write8(0x9E);} +// These two can not be executed on early Intel 64-bit CPU:s, only on AMD! +void XEmitter::LAHF() { + Write8(0x9F); +} +void XEmitter::SAHF() { + CheckFlags(); + Write8(0x9E); +} -void XEmitter::PUSHF() {Write8(0x9C);} -void XEmitter::POPF() {CheckFlags(); Write8(0x9D);} +void XEmitter::PUSHF() { + Write8(0x9C); +} +void XEmitter::POPF() { + CheckFlags(); + Write8(0x9D); +} -void XEmitter::LFENCE() {Write8(0x0F); Write8(0xAE); Write8(0xE8);} -void XEmitter::MFENCE() {Write8(0x0F); Write8(0xAE); Write8(0xF0);} -void XEmitter::SFENCE() {Write8(0x0F); Write8(0xAE); Write8(0xF8);} +void XEmitter::LFENCE() { + Write8(0x0F); + Write8(0xAE); + Write8(0xE8); +} +void XEmitter::MFENCE() { + Write8(0x0F); + Write8(0xAE); + Write8(0xF0); +} +void XEmitter::SFENCE() { + Write8(0x0F); + Write8(0xAE); + Write8(0xF8); +} -void XEmitter::WriteSimple1Byte(int bits, u8 byte, X64Reg reg) -{ +void XEmitter::WriteSimple1Byte(int bits, u8 byte, X64Reg reg) { if (bits == 16) Write8(0x66); Rex(bits == 64, 0, 0, (int)reg >> 3); Write8(byte + ((int)reg & 7)); } -void XEmitter::WriteSimple2Byte(int bits, u8 byte1, u8 byte2, X64Reg reg) -{ +void XEmitter::WriteSimple2Byte(int bits, u8 byte1, u8 byte2, X64Reg reg) { if (bits == 16) Write8(0x66); - Rex(bits==64, 0, 0, (int)reg >> 3); + Rex(bits == 64, 0, 0, (int)reg >> 3); Write8(byte1); Write8(byte2 + ((int)reg & 7)); } -void XEmitter::CWD(int bits) -{ +void XEmitter::CWD(int bits) { if (bits == 16) Write8(0x66); Rex(bits == 64, 0, 0, 0); Write8(0x99); } -void XEmitter::CBW(int bits) -{ +void XEmitter::CBW(int bits) { if (bits == 8) Write8(0x66); Rex(bits == 32, 0, 0, 0); Write8(0x98); } -//Simple opcodes +// Simple opcodes +// push/pop do not need wide to be 64-bit +void XEmitter::PUSH(X64Reg reg) { + WriteSimple1Byte(32, 0x50, reg); +} +void XEmitter::POP(X64Reg reg) { + WriteSimple1Byte(32, 0x58, reg); +} -//push/pop do not need wide to be 64-bit -void XEmitter::PUSH(X64Reg reg) {WriteSimple1Byte(32, 0x50, reg);} -void XEmitter::POP(X64Reg reg) {WriteSimple1Byte(32, 0x58, reg);} - -void XEmitter::PUSH(int bits, const OpArg& reg) -{ +void XEmitter::PUSH(int bits, const OpArg& reg) { if (reg.IsSimpleReg()) PUSH(reg.GetSimpleReg()); - else if (reg.IsImm()) - { - switch (reg.GetImmBits()) - { + else if (reg.IsImm()) { + switch (reg.GetImmBits()) { case 8: Write8(0x6A); Write8((u8)(s8)reg.offset); @@ -715,9 +742,7 @@ void XEmitter::PUSH(int bits, const OpArg& reg) ASSERT_MSG(0, "PUSH - Bad imm bits"); break; } - } - else - { + } else { if (bits == 16) Write8(0x66); reg.WriteRex(this, bits, bits); @@ -726,44 +751,33 @@ void XEmitter::PUSH(int bits, const OpArg& reg) } } -void XEmitter::POP(int /*bits*/, const OpArg& reg) -{ +void XEmitter::POP(int /*bits*/, const OpArg& reg) { if (reg.IsSimpleReg()) POP(reg.GetSimpleReg()); else ASSERT_MSG(0, "POP - Unsupported encoding"); } -void XEmitter::BSWAP(int bits, X64Reg reg) -{ - if (bits >= 32) - { +void XEmitter::BSWAP(int bits, X64Reg reg) { + if (bits >= 32) { WriteSimple2Byte(bits, 0x0F, 0xC8, reg); - } - else if (bits == 16) - { + } else if (bits == 16) { ROL(16, R(reg), Imm8(8)); - } - else if (bits == 8) - { + } else if (bits == 8) { // Do nothing - can't bswap a single byte... - } - else - { + } else { ASSERT_MSG(0, "BSWAP - Wrong number of bits"); } } // Undefined opcode - reserved // If we ever need a way to always cause a non-breakpoint hard exception... -void XEmitter::UD2() -{ +void XEmitter::UD2() { Write8(0x0F); Write8(0x0B); } -void XEmitter::PREFETCH(PrefetchLevel level, OpArg arg) -{ +void XEmitter::PREFETCH(PrefetchLevel level, OpArg arg) { ASSERT_MSG(!arg.IsImm(), "PREFETCH - Imm argument"); arg.operandReg = (u8)level; arg.WriteRex(this, 0, 0); @@ -772,8 +786,7 @@ void XEmitter::PREFETCH(PrefetchLevel level, OpArg arg) arg.WriteRest(this); } -void XEmitter::SETcc(CCFlags flag, OpArg dest) -{ +void XEmitter::SETcc(CCFlags flag, OpArg dest) { ASSERT_MSG(!dest.IsImm(), "SETcc - Imm argument"); dest.operandReg = 0; dest.WriteRex(this, 0, 8); @@ -782,8 +795,7 @@ void XEmitter::SETcc(CCFlags flag, OpArg dest) dest.WriteRest(this); } -void XEmitter::CMOVcc(int bits, X64Reg dest, OpArg src, CCFlags flag) -{ +void XEmitter::CMOVcc(int bits, X64Reg dest, OpArg src, CCFlags flag) { ASSERT_MSG(!src.IsImm(), "CMOVcc - Imm argument"); ASSERT_MSG(bits != 8, "CMOVcc - 8 bits unsupported"); if (bits == 16) @@ -795,34 +807,41 @@ void XEmitter::CMOVcc(int bits, X64Reg dest, OpArg src, CCFlags flag) src.WriteRest(this); } -void XEmitter::WriteMulDivType(int bits, OpArg src, int ext) -{ +void XEmitter::WriteMulDivType(int bits, OpArg src, int ext) { ASSERT_MSG(!src.IsImm(), "WriteMulDivType - Imm argument"); CheckFlags(); src.operandReg = ext; if (bits == 16) Write8(0x66); src.WriteRex(this, bits, bits, 0); - if (bits == 8) - { + if (bits == 8) { Write8(0xF6); - } - else - { + } else { Write8(0xF7); } src.WriteRest(this); } -void XEmitter::MUL(int bits, const OpArg& src) {WriteMulDivType(bits, src, 4);} -void XEmitter::DIV(int bits, const OpArg& src) {WriteMulDivType(bits, src, 6);} -void XEmitter::IMUL(int bits, const OpArg& src) {WriteMulDivType(bits, src, 5);} -void XEmitter::IDIV(int bits, const OpArg& src) {WriteMulDivType(bits, src, 7);} -void XEmitter::NEG(int bits, const OpArg& src) {WriteMulDivType(bits, src, 3);} -void XEmitter::NOT(int bits, const OpArg& src) {WriteMulDivType(bits, src, 2);} +void XEmitter::MUL(int bits, const OpArg& src) { + WriteMulDivType(bits, src, 4); +} +void XEmitter::DIV(int bits, const OpArg& src) { + WriteMulDivType(bits, src, 6); +} +void XEmitter::IMUL(int bits, const OpArg& src) { + WriteMulDivType(bits, src, 5); +} +void XEmitter::IDIV(int bits, const OpArg& src) { + WriteMulDivType(bits, src, 7); +} +void XEmitter::NEG(int bits, const OpArg& src) { + WriteMulDivType(bits, src, 3); +} +void XEmitter::NOT(int bits, const OpArg& src) { + WriteMulDivType(bits, src, 2); +} -void XEmitter::WriteBitSearchType(int bits, X64Reg dest, OpArg src, u8 byte2, bool rep) -{ +void XEmitter::WriteBitSearchType(int bits, X64Reg dest, OpArg src, u8 byte2, bool rep) { ASSERT_MSG(!src.IsImm(), "WriteBitSearchType - Imm argument"); CheckFlags(); src.operandReg = (u8)dest; @@ -836,36 +855,35 @@ void XEmitter::WriteBitSearchType(int bits, X64Reg dest, OpArg src, u8 byte2, bo src.WriteRest(this); } -void XEmitter::MOVNTI(int bits, const OpArg& dest, X64Reg src) -{ +void XEmitter::MOVNTI(int bits, const OpArg& dest, X64Reg src) { if (bits <= 16) ASSERT_MSG(0, "MOVNTI - bits<=16"); WriteBitSearchType(bits, src, dest, 0xC3); } -void XEmitter::BSF(int bits, X64Reg dest, const OpArg& src) {WriteBitSearchType(bits,dest,src,0xBC);} // Bottom bit to top bit -void XEmitter::BSR(int bits, X64Reg dest, const OpArg& src) {WriteBitSearchType(bits,dest,src,0xBD);} // Top bit to bottom bit +void XEmitter::BSF(int bits, X64Reg dest, const OpArg& src) { + WriteBitSearchType(bits, dest, src, 0xBC); +} // Bottom bit to top bit +void XEmitter::BSR(int bits, X64Reg dest, const OpArg& src) { + WriteBitSearchType(bits, dest, src, 0xBD); +} // Top bit to bottom bit -void XEmitter::TZCNT(int bits, X64Reg dest, const OpArg& src) -{ +void XEmitter::TZCNT(int bits, X64Reg dest, const OpArg& src) { CheckFlags(); if (!Common::GetCPUCaps().bmi1) ASSERT_MSG(0, "Trying to use BMI1 on a system that doesn't support it. Bad programmer."); WriteBitSearchType(bits, dest, src, 0xBC, true); } -void XEmitter::LZCNT(int bits, X64Reg dest, const OpArg& src) -{ +void XEmitter::LZCNT(int bits, X64Reg dest, const OpArg& src) { CheckFlags(); if (!Common::GetCPUCaps().lzcnt) ASSERT_MSG(0, "Trying to use LZCNT on a system that doesn't support it. Bad programmer."); WriteBitSearchType(bits, dest, src, 0xBD, true); } -void XEmitter::MOVSX(int dbits, int sbits, X64Reg dest, OpArg src) -{ +void XEmitter::MOVSX(int dbits, int sbits, X64Reg dest, OpArg src) { ASSERT_MSG(!src.IsImm(), "MOVSX - Imm argument"); - if (dbits == sbits) - { + if (dbits == sbits) { MOV(dbits, R(dest), src); return; } @@ -873,66 +891,49 @@ void XEmitter::MOVSX(int dbits, int sbits, X64Reg dest, OpArg src) if (dbits == 16) Write8(0x66); src.WriteRex(this, dbits, sbits); - if (sbits == 8) - { + if (sbits == 8) { Write8(0x0F); Write8(0xBE); - } - else if (sbits == 16) - { + } else if (sbits == 16) { Write8(0x0F); Write8(0xBF); - } - else if (sbits == 32 && dbits == 64) - { + } else if (sbits == 32 && dbits == 64) { Write8(0x63); - } - else - { + } else { Crash(); } src.WriteRest(this); } -void XEmitter::MOVZX(int dbits, int sbits, X64Reg dest, OpArg src) -{ +void XEmitter::MOVZX(int dbits, int sbits, X64Reg dest, OpArg src) { ASSERT_MSG(!src.IsImm(), "MOVZX - Imm argument"); - if (dbits == sbits) - { + if (dbits == sbits) { MOV(dbits, R(dest), src); return; } src.operandReg = (u8)dest; if (dbits == 16) Write8(0x66); - //the 32bit result is automatically zero extended to 64bit + // the 32bit result is automatically zero extended to 64bit src.WriteRex(this, dbits == 64 ? 32 : dbits, sbits); - if (sbits == 8) - { + if (sbits == 8) { Write8(0x0F); Write8(0xB6); - } - else if (sbits == 16) - { + } else if (sbits == 16) { Write8(0x0F); Write8(0xB7); - } - else if (sbits == 32 && dbits == 64) - { + } else if (sbits == 32 && dbits == 64) { Write8(0x8B); - } - else - { + } else { ASSERT_MSG(0, "MOVZX - Invalid size"); } src.WriteRest(this); } -void XEmitter::MOVBE(int bits, const OpArg& dest, const OpArg& src) -{ - ASSERT_MSG(Common::GetCPUCaps().movbe, "Generating MOVBE on a system that does not support it."); - if (bits == 8) - { +void XEmitter::MOVBE(int bits, const OpArg& dest, const OpArg& src) { + ASSERT_MSG(Common::GetCPUCaps().movbe, + "Generating MOVBE on a system that does not support it."); + if (bits == 8) { MOV(bits, dest, src); return; } @@ -940,71 +941,60 @@ void XEmitter::MOVBE(int bits, const OpArg& dest, const OpArg& src) if (bits == 16) Write8(0x66); - if (dest.IsSimpleReg()) - { + if (dest.IsSimpleReg()) { ASSERT_MSG(!src.IsSimpleReg() && !src.IsImm(), "MOVBE: Loading from !mem"); src.WriteRex(this, bits, bits, dest.GetSimpleReg()); - Write8(0x0F); Write8(0x38); Write8(0xF0); + Write8(0x0F); + Write8(0x38); + Write8(0xF0); src.WriteRest(this, 0, dest.GetSimpleReg()); - } - else if (src.IsSimpleReg()) - { + } else if (src.IsSimpleReg()) { ASSERT_MSG(!dest.IsSimpleReg() && !dest.IsImm(), "MOVBE: Storing to !mem"); dest.WriteRex(this, bits, bits, src.GetSimpleReg()); - Write8(0x0F); Write8(0x38); Write8(0xF1); + Write8(0x0F); + Write8(0x38); + Write8(0xF1); dest.WriteRest(this, 0, src.GetSimpleReg()); - } - else - { + } else { ASSERT_MSG(0, "MOVBE: Not loading or storing to mem"); } } - -void XEmitter::LEA(int bits, X64Reg dest, OpArg src) -{ +void XEmitter::LEA(int bits, X64Reg dest, OpArg src) { ASSERT_MSG(!src.IsImm(), "LEA - Imm argument"); src.operandReg = (u8)dest; if (bits == 16) - Write8(0x66); //TODO: performance warning + Write8(0x66); // TODO: performance warning src.WriteRex(this, bits, bits); Write8(0x8D); src.WriteRest(this, 0, INVALID_REG, bits == 64); } -//shift can be either imm8 or cl -void XEmitter::WriteShift(int bits, OpArg dest, const OpArg& shift, int ext) -{ +// shift can be either imm8 or cl +void XEmitter::WriteShift(int bits, OpArg dest, const OpArg& shift, int ext) { CheckFlags(); bool writeImm = false; - if (dest.IsImm()) - { + if (dest.IsImm()) { ASSERT_MSG(0, "WriteShift - can't shift imms"); } - if ((shift.IsSimpleReg() && shift.GetSimpleReg() != ECX) || (shift.IsImm() && shift.GetImmBits() != 8)) - { + if ((shift.IsSimpleReg() && shift.GetSimpleReg() != ECX) || + (shift.IsImm() && shift.GetImmBits() != 8)) { ASSERT_MSG(0, "WriteShift - illegal argument"); } dest.operandReg = ext; if (bits == 16) Write8(0x66); dest.WriteRex(this, bits, bits, 0); - if (shift.GetImmBits() == 8) - { - //ok an imm + if (shift.GetImmBits() == 8) { + // ok an imm u8 imm = (u8)shift.offset; - if (imm == 1) - { + if (imm == 1) { Write8(bits == 8 ? 0xD0 : 0xD1); - } - else - { + } else { writeImm = true; Write8(bits == 8 ? 0xC0 : 0xC1); } - } - else - { + } else { Write8(bits == 8 ? 0xD2 : 0xD3); } dest.WriteRest(this, writeImm ? 1 : 0); @@ -1014,116 +1004,125 @@ void XEmitter::WriteShift(int bits, OpArg dest, const OpArg& shift, int ext) // large rotates and shift are slower on intel than amd // intel likes to rotate by 1, and the op is smaller too -void XEmitter::ROL(int bits, const OpArg& dest, const OpArg& shift) {WriteShift(bits, dest, shift, 0);} -void XEmitter::ROR(int bits, const OpArg& dest, const OpArg& shift) {WriteShift(bits, dest, shift, 1);} -void XEmitter::RCL(int bits, const OpArg& dest, const OpArg& shift) {WriteShift(bits, dest, shift, 2);} -void XEmitter::RCR(int bits, const OpArg& dest, const OpArg& shift) {WriteShift(bits, dest, shift, 3);} -void XEmitter::SHL(int bits, const OpArg& dest, const OpArg& shift) {WriteShift(bits, dest, shift, 4);} -void XEmitter::SHR(int bits, const OpArg& dest, const OpArg& shift) {WriteShift(bits, dest, shift, 5);} -void XEmitter::SAR(int bits, const OpArg& dest, const OpArg& shift) {WriteShift(bits, dest, shift, 7);} +void XEmitter::ROL(int bits, const OpArg& dest, const OpArg& shift) { + WriteShift(bits, dest, shift, 0); +} +void XEmitter::ROR(int bits, const OpArg& dest, const OpArg& shift) { + WriteShift(bits, dest, shift, 1); +} +void XEmitter::RCL(int bits, const OpArg& dest, const OpArg& shift) { + WriteShift(bits, dest, shift, 2); +} +void XEmitter::RCR(int bits, const OpArg& dest, const OpArg& shift) { + WriteShift(bits, dest, shift, 3); +} +void XEmitter::SHL(int bits, const OpArg& dest, const OpArg& shift) { + WriteShift(bits, dest, shift, 4); +} +void XEmitter::SHR(int bits, const OpArg& dest, const OpArg& shift) { + WriteShift(bits, dest, shift, 5); +} +void XEmitter::SAR(int bits, const OpArg& dest, const OpArg& shift) { + WriteShift(bits, dest, shift, 7); +} // index can be either imm8 or register, don't use memory destination because it's slow -void XEmitter::WriteBitTest(int bits, const OpArg& dest, const OpArg& index, int ext) -{ +void XEmitter::WriteBitTest(int bits, const OpArg& dest, const OpArg& index, int ext) { CheckFlags(); - if (dest.IsImm()) - { + if (dest.IsImm()) { ASSERT_MSG(0, "WriteBitTest - can't test imms"); } - if ((index.IsImm() && index.GetImmBits() != 8)) - { + if ((index.IsImm() && index.GetImmBits() != 8)) { ASSERT_MSG(0, "WriteBitTest - illegal argument"); } if (bits == 16) Write8(0x66); - if (index.IsImm()) - { + if (index.IsImm()) { dest.WriteRex(this, bits, bits); - Write8(0x0F); Write8(0xBA); + Write8(0x0F); + Write8(0xBA); dest.WriteRest(this, 1, (X64Reg)ext); Write8((u8)index.offset); - } - else - { + } else { X64Reg operand = index.GetSimpleReg(); dest.WriteRex(this, bits, bits, operand); - Write8(0x0F); Write8(0x83 + 8*ext); + Write8(0x0F); + Write8(0x83 + 8 * ext); dest.WriteRest(this, 1, operand); } } -void XEmitter::BT(int bits, const OpArg& dest, const OpArg& index) {WriteBitTest(bits, dest, index, 4);} -void XEmitter::BTS(int bits, const OpArg& dest, const OpArg& index) {WriteBitTest(bits, dest, index, 5);} -void XEmitter::BTR(int bits, const OpArg& dest, const OpArg& index) {WriteBitTest(bits, dest, index, 6);} -void XEmitter::BTC(int bits, const OpArg& dest, const OpArg& index) {WriteBitTest(bits, dest, index, 7);} +void XEmitter::BT(int bits, const OpArg& dest, const OpArg& index) { + WriteBitTest(bits, dest, index, 4); +} +void XEmitter::BTS(int bits, const OpArg& dest, const OpArg& index) { + WriteBitTest(bits, dest, index, 5); +} +void XEmitter::BTR(int bits, const OpArg& dest, const OpArg& index) { + WriteBitTest(bits, dest, index, 6); +} +void XEmitter::BTC(int bits, const OpArg& dest, const OpArg& index) { + WriteBitTest(bits, dest, index, 7); +} -//shift can be either imm8 or cl -void XEmitter::SHRD(int bits, const OpArg& dest, const OpArg& src, const OpArg& shift) -{ +// shift can be either imm8 or cl +void XEmitter::SHRD(int bits, const OpArg& dest, const OpArg& src, const OpArg& shift) { CheckFlags(); - if (dest.IsImm()) - { + if (dest.IsImm()) { ASSERT_MSG(0, "SHRD - can't use imms as destination"); } - if (!src.IsSimpleReg()) - { + if (!src.IsSimpleReg()) { ASSERT_MSG(0, "SHRD - must use simple register as source"); } - if ((shift.IsSimpleReg() && shift.GetSimpleReg() != ECX) || (shift.IsImm() && shift.GetImmBits() != 8)) - { + if ((shift.IsSimpleReg() && shift.GetSimpleReg() != ECX) || + (shift.IsImm() && shift.GetImmBits() != 8)) { ASSERT_MSG(0, "SHRD - illegal shift"); } if (bits == 16) Write8(0x66); X64Reg operand = src.GetSimpleReg(); dest.WriteRex(this, bits, bits, operand); - if (shift.GetImmBits() == 8) - { - Write8(0x0F); Write8(0xAC); + if (shift.GetImmBits() == 8) { + Write8(0x0F); + Write8(0xAC); dest.WriteRest(this, 1, operand); Write8((u8)shift.offset); - } - else - { - Write8(0x0F); Write8(0xAD); + } else { + Write8(0x0F); + Write8(0xAD); dest.WriteRest(this, 0, operand); } } -void XEmitter::SHLD(int bits, const OpArg& dest, const OpArg& src, const OpArg& shift) -{ +void XEmitter::SHLD(int bits, const OpArg& dest, const OpArg& src, const OpArg& shift) { CheckFlags(); - if (dest.IsImm()) - { + if (dest.IsImm()) { ASSERT_MSG(0, "SHLD - can't use imms as destination"); } - if (!src.IsSimpleReg()) - { + if (!src.IsSimpleReg()) { ASSERT_MSG(0, "SHLD - must use simple register as source"); } - if ((shift.IsSimpleReg() && shift.GetSimpleReg() != ECX) || (shift.IsImm() && shift.GetImmBits() != 8)) - { + if ((shift.IsSimpleReg() && shift.GetSimpleReg() != ECX) || + (shift.IsImm() && shift.GetImmBits() != 8)) { ASSERT_MSG(0, "SHLD - illegal shift"); } if (bits == 16) Write8(0x66); X64Reg operand = src.GetSimpleReg(); dest.WriteRex(this, bits, bits, operand); - if (shift.GetImmBits() == 8) - { - Write8(0x0F); Write8(0xA4); + if (shift.GetImmBits() == 8) { + Write8(0x0F); + Write8(0xA4); dest.WriteRest(this, 1, operand); Write8((u8)shift.offset); - } - else - { - Write8(0x0F); Write8(0xA5); + } else { + Write8(0x0F); + Write8(0xA5); dest.WriteRest(this, 0, operand); } } -void OpArg::WriteSingleByteOp(XEmitter *emit, u8 op, X64Reg _operandReg, int bits) -{ +void OpArg::WriteSingleByteOp(XEmitter* emit, u8 op, X64Reg _operandReg, int bits) { if (bits == 16) emit->Write8(0x66); @@ -1133,12 +1132,11 @@ void OpArg::WriteSingleByteOp(XEmitter *emit, u8 op, X64Reg _operandReg, int bit WriteRest(emit); } -//operand can either be immediate or register -void OpArg::WriteNormalOp(XEmitter *emit, bool toRM, NormalOp op, const OpArg& operand, int bits) const -{ +// operand can either be immediate or register +void OpArg::WriteNormalOp(XEmitter* emit, bool toRM, NormalOp op, const OpArg& operand, + int bits) const { X64Reg _operandReg; - if (IsImm()) - { + if (IsImm()) { ASSERT_MSG(0, "WriteNormalOp - Imm argument, wrong order"); } @@ -1147,27 +1145,22 @@ void OpArg::WriteNormalOp(XEmitter *emit, bool toRM, NormalOp op, const OpArg& o int immToWrite = 0; - if (operand.IsImm()) - { + if (operand.IsImm()) { WriteRex(emit, bits, bits); - if (!toRM) - { + if (!toRM) { ASSERT_MSG(0, "WriteNormalOp - Writing to Imm (!toRM)"); } - if (operand.scale == SCALE_IMM8 && bits == 8) - { + if (operand.scale == SCALE_IMM8 && bits == 8) { // op al, imm8 - if (!scale && offsetOrBaseReg == AL && normalops[op].eaximm8 != 0xCC) - { + if (!scale && offsetOrBaseReg == AL && normalops[op].eaximm8 != 0xCC) { emit->Write8(normalops[op].eaximm8); emit->Write8((u8)operand.offset); return; } // mov reg, imm8 - if (!scale && op == nrmMOV) - { + if (!scale && op == nrmMOV) { emit->Write8(0xB0 + (offsetOrBaseReg & 7)); emit->Write8((u8)operand.offset); return; @@ -1175,26 +1168,20 @@ void OpArg::WriteNormalOp(XEmitter *emit, bool toRM, NormalOp op, const OpArg& o // op r/m8, imm8 emit->Write8(normalops[op].imm8); immToWrite = 8; - } - else if ((operand.scale == SCALE_IMM16 && bits == 16) || - (operand.scale == SCALE_IMM32 && bits == 32) || - (operand.scale == SCALE_IMM32 && bits == 64)) - { + } else if ((operand.scale == SCALE_IMM16 && bits == 16) || + (operand.scale == SCALE_IMM32 && bits == 32) || + (operand.scale == SCALE_IMM32 && bits == 64)) { // Try to save immediate size if we can, but first check to see // if the instruction supports simm8. // op r/m, imm8 if (normalops[op].simm8 != 0xCC && ((operand.scale == SCALE_IMM16 && (s16)operand.offset == (s8)operand.offset) || - (operand.scale == SCALE_IMM32 && (s32)operand.offset == (s8)operand.offset))) - { + (operand.scale == SCALE_IMM32 && (s32)operand.offset == (s8)operand.offset))) { emit->Write8(normalops[op].simm8); immToWrite = 8; - } - else - { + } else { // mov reg, imm - if (!scale && op == nrmMOV && bits != 64) - { + if (!scale && op == nrmMOV && bits != 64) { emit->Write8(0xB8 + (offsetOrBaseReg & 7)); if (bits == 16) emit->Write16((u16)operand.offset); @@ -1203,8 +1190,7 @@ void OpArg::WriteNormalOp(XEmitter *emit, bool toRM, NormalOp op, const OpArg& o return; } // op eax, imm - if (!scale && offsetOrBaseReg == EAX && normalops[op].eaximm32 != 0xCC) - { + if (!scale && offsetOrBaseReg == EAX && normalops[op].eaximm32 != 0xCC) { emit->Write8(normalops[op].eaximm32); if (bits == 16) emit->Write16((u16)operand.offset); @@ -1216,54 +1202,41 @@ void OpArg::WriteNormalOp(XEmitter *emit, bool toRM, NormalOp op, const OpArg& o emit->Write8(normalops[op].imm32); immToWrite = bits == 16 ? 16 : 32; } - } - else if ((operand.scale == SCALE_IMM8 && bits == 16) || - (operand.scale == SCALE_IMM8 && bits == 32) || - (operand.scale == SCALE_IMM8 && bits == 64)) - { + } else if ((operand.scale == SCALE_IMM8 && bits == 16) || + (operand.scale == SCALE_IMM8 && bits == 32) || + (operand.scale == SCALE_IMM8 && bits == 64)) { // op r/m, imm8 emit->Write8(normalops[op].simm8); immToWrite = 8; - } - else if (operand.scale == SCALE_IMM64 && bits == 64) - { - if (scale) - { + } else if (operand.scale == SCALE_IMM64 && bits == 64) { + if (scale) { ASSERT_MSG(0, "WriteNormalOp - MOV with 64-bit imm requres register destination"); } // mov reg64, imm64 - else if (op == nrmMOV) - { + else if (op == nrmMOV) { emit->Write8(0xB8 + (offsetOrBaseReg & 7)); emit->Write64((u64)operand.offset); return; } ASSERT_MSG(0, "WriteNormalOp - Only MOV can take 64-bit imm"); - } - else - { + } else { ASSERT_MSG(0, "WriteNormalOp - Unhandled case"); } - _operandReg = (X64Reg)normalops[op].ext; //pass extension in REG of ModRM - } - else - { + _operandReg = (X64Reg)normalops[op].ext; // pass extension in REG of ModRM + } else { _operandReg = (X64Reg)operand.offsetOrBaseReg; WriteRex(emit, bits, bits, _operandReg); // op r/m, reg - if (toRM) - { + if (toRM) { emit->Write8(bits == 8 ? normalops[op].toRm8 : normalops[op].toRm32); } // op reg, r/m - else - { + else { emit->Write8(bits == 8 ? normalops[op].fromRm8 : normalops[op].fromRm32); } } WriteRest(emit, immToWrite >> 3, _operandReg); - switch (immToWrite) - { + switch (immToWrite) { case 0: break; case 8: @@ -1280,66 +1253,84 @@ void OpArg::WriteNormalOp(XEmitter *emit, bool toRM, NormalOp op, const OpArg& o } } -void XEmitter::WriteNormalOp(XEmitter *emit, int bits, NormalOp op, const OpArg& a1, const OpArg& a2) -{ - if (a1.IsImm()) - { - //Booh! Can't write to an imm +void XEmitter::WriteNormalOp(XEmitter* emit, int bits, NormalOp op, const OpArg& a1, + const OpArg& a2) { + if (a1.IsImm()) { + // Booh! Can't write to an imm ASSERT_MSG(0, "WriteNormalOp - a1 cannot be imm"); return; } - if (a2.IsImm()) - { + if (a2.IsImm()) { a1.WriteNormalOp(emit, true, op, a2, bits); - } - else - { - if (a1.IsSimpleReg()) - { + } else { + if (a1.IsSimpleReg()) { a2.WriteNormalOp(emit, false, op, a1, bits); - } - else - { - ASSERT_MSG(a2.IsSimpleReg() || a2.IsImm(), "WriteNormalOp - a1 and a2 cannot both be memory"); + } else { + ASSERT_MSG(a2.IsSimpleReg() || a2.IsImm(), + "WriteNormalOp - a1 and a2 cannot both be memory"); a1.WriteNormalOp(emit, true, op, a2, bits); } } } -void XEmitter::ADD (int bits, const OpArg& a1, const OpArg& a2) {CheckFlags(); WriteNormalOp(this, bits, nrmADD, a1, a2);} -void XEmitter::ADC (int bits, const OpArg& a1, const OpArg& a2) {CheckFlags(); WriteNormalOp(this, bits, nrmADC, a1, a2);} -void XEmitter::SUB (int bits, const OpArg& a1, const OpArg& a2) {CheckFlags(); WriteNormalOp(this, bits, nrmSUB, a1, a2);} -void XEmitter::SBB (int bits, const OpArg& a1, const OpArg& a2) {CheckFlags(); WriteNormalOp(this, bits, nrmSBB, a1, a2);} -void XEmitter::AND (int bits, const OpArg& a1, const OpArg& a2) {CheckFlags(); WriteNormalOp(this, bits, nrmAND, a1, a2);} -void XEmitter::OR (int bits, const OpArg& a1, const OpArg& a2) {CheckFlags(); WriteNormalOp(this, bits, nrmOR , a1, a2);} -void XEmitter::XOR (int bits, const OpArg& a1, const OpArg& a2) {CheckFlags(); WriteNormalOp(this, bits, nrmXOR, a1, a2);} -void XEmitter::MOV (int bits, const OpArg& a1, const OpArg& a2) -{ +void XEmitter::ADD(int bits, const OpArg& a1, const OpArg& a2) { + CheckFlags(); + WriteNormalOp(this, bits, nrmADD, a1, a2); +} +void XEmitter::ADC(int bits, const OpArg& a1, const OpArg& a2) { + CheckFlags(); + WriteNormalOp(this, bits, nrmADC, a1, a2); +} +void XEmitter::SUB(int bits, const OpArg& a1, const OpArg& a2) { + CheckFlags(); + WriteNormalOp(this, bits, nrmSUB, a1, a2); +} +void XEmitter::SBB(int bits, const OpArg& a1, const OpArg& a2) { + CheckFlags(); + WriteNormalOp(this, bits, nrmSBB, a1, a2); +} +void XEmitter::AND(int bits, const OpArg& a1, const OpArg& a2) { + CheckFlags(); + WriteNormalOp(this, bits, nrmAND, a1, a2); +} +void XEmitter::OR(int bits, const OpArg& a1, const OpArg& a2) { + CheckFlags(); + WriteNormalOp(this, bits, nrmOR, a1, a2); +} +void XEmitter::XOR(int bits, const OpArg& a1, const OpArg& a2) { + CheckFlags(); + WriteNormalOp(this, bits, nrmXOR, a1, a2); +} +void XEmitter::MOV(int bits, const OpArg& a1, const OpArg& a2) { if (a1.IsSimpleReg() && a2.IsSimpleReg() && a1.GetSimpleReg() == a2.GetSimpleReg()) LOG_ERROR(Common, "Redundant MOV @ %p - bug in JIT?", code); WriteNormalOp(this, bits, nrmMOV, a1, a2); } -void XEmitter::TEST(int bits, const OpArg& a1, const OpArg& a2) {CheckFlags(); WriteNormalOp(this, bits, nrmTEST, a1, a2);} -void XEmitter::CMP (int bits, const OpArg& a1, const OpArg& a2) {CheckFlags(); WriteNormalOp(this, bits, nrmCMP, a1, a2);} -void XEmitter::XCHG(int bits, const OpArg& a1, const OpArg& a2) {WriteNormalOp(this, bits, nrmXCHG, a1, a2);} +void XEmitter::TEST(int bits, const OpArg& a1, const OpArg& a2) { + CheckFlags(); + WriteNormalOp(this, bits, nrmTEST, a1, a2); +} +void XEmitter::CMP(int bits, const OpArg& a1, const OpArg& a2) { + CheckFlags(); + WriteNormalOp(this, bits, nrmCMP, a1, a2); +} +void XEmitter::XCHG(int bits, const OpArg& a1, const OpArg& a2) { + WriteNormalOp(this, bits, nrmXCHG, a1, a2); +} -void XEmitter::IMUL(int bits, X64Reg regOp, const OpArg& a1, const OpArg& a2) -{ +void XEmitter::IMUL(int bits, X64Reg regOp, const OpArg& a1, const OpArg& a2) { CheckFlags(); - if (bits == 8) - { + if (bits == 8) { ASSERT_MSG(0, "IMUL - illegal bit size!"); return; } - if (a1.IsImm()) - { + if (a1.IsImm()) { ASSERT_MSG(0, "IMUL - second arg cannot be imm!"); return; } - if (!a2.IsImm()) - { + if (!a2.IsImm()) { ASSERT_MSG(0, "IMUL - third arg must be imm!"); return; } @@ -1348,46 +1339,34 @@ void XEmitter::IMUL(int bits, X64Reg regOp, const OpArg& a1, const OpArg& a2) Write8(0x66); a1.WriteRex(this, bits, bits, regOp); - if (a2.GetImmBits() == 8 || - (a2.GetImmBits() == 16 && (s8)a2.offset == (s16)a2.offset) || - (a2.GetImmBits() == 32 && (s8)a2.offset == (s32)a2.offset)) - { + if (a2.GetImmBits() == 8 || (a2.GetImmBits() == 16 && (s8)a2.offset == (s16)a2.offset) || + (a2.GetImmBits() == 32 && (s8)a2.offset == (s32)a2.offset)) { Write8(0x6B); a1.WriteRest(this, 1, regOp); Write8((u8)a2.offset); - } - else - { + } else { Write8(0x69); - if (a2.GetImmBits() == 16 && bits == 16) - { + if (a2.GetImmBits() == 16 && bits == 16) { a1.WriteRest(this, 2, regOp); Write16((u16)a2.offset); - } - else if (a2.GetImmBits() == 32 && (bits == 32 || bits == 64)) - { + } else if (a2.GetImmBits() == 32 && (bits == 32 || bits == 64)) { a1.WriteRest(this, 4, regOp); Write32((u32)a2.offset); - } - else - { + } else { ASSERT_MSG(0, "IMUL - unhandled case!"); } } } -void XEmitter::IMUL(int bits, X64Reg regOp, const OpArg& a) -{ +void XEmitter::IMUL(int bits, X64Reg regOp, const OpArg& a) { CheckFlags(); - if (bits == 8) - { + if (bits == 8) { ASSERT_MSG(0, "IMUL - illegal bit size!"); return; } - if (a.IsImm()) - { - IMUL(bits, regOp, R(regOp), a) ; + if (a.IsImm()) { + IMUL(bits, regOp, R(regOp), a); return; } @@ -1399,9 +1378,7 @@ void XEmitter::IMUL(int bits, X64Reg regOp, const OpArg& a) a.WriteRest(this, 0, regOp); } - -void XEmitter::WriteSSEOp(u8 opPrefix, u16 op, X64Reg regOp, OpArg arg, int extrabytes) -{ +void XEmitter::WriteSSEOp(u8 opPrefix, u16 op, X64Reg regOp, OpArg arg, int extrabytes) { if (opPrefix) Write8(opPrefix); arg.operandReg = regOp; @@ -1413,13 +1390,11 @@ void XEmitter::WriteSSEOp(u8 opPrefix, u16 op, X64Reg regOp, OpArg arg, int extr arg.WriteRest(this, extrabytes); } -void XEmitter::WriteAVXOp(u8 opPrefix, u16 op, X64Reg regOp, const OpArg& arg, int extrabytes) -{ +void XEmitter::WriteAVXOp(u8 opPrefix, u16 op, X64Reg regOp, const OpArg& arg, int extrabytes) { WriteAVXOp(opPrefix, op, regOp, INVALID_REG, arg, extrabytes); } -static int GetVEXmmmmm(u16 op) -{ +static int GetVEXmmmmm(u16 op) { // Currently, only 0x38 and 0x3A are used as secondary escape byte. if ((op >> 8) == 0x3A) return 3; @@ -1429,8 +1404,7 @@ static int GetVEXmmmmm(u16 op) return 1; } -static int GetVEXpp(u8 opPrefix) -{ +static int GetVEXpp(u8 opPrefix) { if (opPrefix == 0x66) return 1; if (opPrefix == 0xF3) @@ -1441,21 +1415,22 @@ static int GetVEXpp(u8 opPrefix) return 0; } -void XEmitter::WriteAVXOp(u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, const OpArg& arg, int extrabytes) -{ +void XEmitter::WriteAVXOp(u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, const OpArg& arg, + int extrabytes) { if (!Common::GetCPUCaps().avx) ASSERT_MSG(0, "Trying to use AVX on a system that doesn't support it. Bad programmer."); int mmmmm = GetVEXmmmmm(op); int pp = GetVEXpp(opPrefix); - // FIXME: we currently don't support 256-bit instructions, and "size" is not the vector size here + // FIXME: we currently don't support 256-bit instructions, and "size" is not the vector size + // here arg.WriteVex(this, regOp1, regOp2, 0, pp, mmmmm); Write8(op & 0xFF); arg.WriteRest(this, extrabytes, regOp1); } // Like the above, but more general; covers GPR-based VEX operations, like BMI1/2 -void XEmitter::WriteVEXOp(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, const OpArg& arg, int extrabytes) -{ +void XEmitter::WriteVEXOp(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, + const OpArg& arg, int extrabytes) { if (size != 32 && size != 64) ASSERT_MSG(0, "VEX GPR instructions only support 32-bit and 64-bit modes!"); int mmmmm = GetVEXmmmmm(op); @@ -1465,49 +1440,50 @@ void XEmitter::WriteVEXOp(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg r arg.WriteRest(this, extrabytes, regOp1); } -void XEmitter::WriteBMI1Op(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, const OpArg& arg, int extrabytes) -{ +void XEmitter::WriteBMI1Op(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, + const OpArg& arg, int extrabytes) { CheckFlags(); if (!Common::GetCPUCaps().bmi1) ASSERT_MSG(0, "Trying to use BMI1 on a system that doesn't support it. Bad programmer."); WriteVEXOp(size, opPrefix, op, regOp1, regOp2, arg, extrabytes); } -void XEmitter::WriteBMI2Op(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, const OpArg& arg, int extrabytes) -{ +void XEmitter::WriteBMI2Op(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, + const OpArg& arg, int extrabytes) { CheckFlags(); if (!Common::GetCPUCaps().bmi2) ASSERT_MSG(0, "Trying to use BMI2 on a system that doesn't support it. Bad programmer."); WriteVEXOp(size, opPrefix, op, regOp1, regOp2, arg, extrabytes); } -void XEmitter::MOVD_xmm(X64Reg dest, const OpArg &arg) {WriteSSEOp(0x66, 0x6E, dest, arg, 0);} -void XEmitter::MOVD_xmm(const OpArg &arg, X64Reg src) {WriteSSEOp(0x66, 0x7E, src, arg, 0);} +void XEmitter::MOVD_xmm(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0x6E, dest, arg, 0); +} +void XEmitter::MOVD_xmm(const OpArg& arg, X64Reg src) { + WriteSSEOp(0x66, 0x7E, src, arg, 0); +} -void XEmitter::MOVQ_xmm(X64Reg dest, OpArg arg) -{ +void XEmitter::MOVQ_xmm(X64Reg dest, OpArg arg) { #ifdef ARCHITECTURE_x86_64 - // Alternate encoding - // This does not display correctly in MSVC's debugger, it thinks it's a MOVD - arg.operandReg = dest; - Write8(0x66); - arg.WriteRex(this, 64, 0); - Write8(0x0f); - Write8(0x6E); - arg.WriteRest(this, 0); + // Alternate encoding + // This does not display correctly in MSVC's debugger, it thinks it's a MOVD + arg.operandReg = dest; + Write8(0x66); + arg.WriteRex(this, 64, 0); + Write8(0x0f); + Write8(0x6E); + arg.WriteRest(this, 0); #else - arg.operandReg = dest; - Write8(0xF3); - Write8(0x0f); - Write8(0x7E); - arg.WriteRest(this, 0); + arg.operandReg = dest; + Write8(0xF3); + Write8(0x0f); + Write8(0x7E); + arg.WriteRest(this, 0); #endif } -void XEmitter::MOVQ_xmm(OpArg arg, X64Reg src) -{ - if (src > 7 || arg.IsSimpleReg()) - { +void XEmitter::MOVQ_xmm(OpArg arg, X64Reg src) { + if (src > 7 || arg.IsSimpleReg()) { // Alternate encoding // This does not display correctly in MSVC's debugger, it thinks it's a MOVD arg.operandReg = src; @@ -1516,9 +1492,7 @@ void XEmitter::MOVQ_xmm(OpArg arg, X64Reg src) Write8(0x0f); Write8(0x7E); arg.WriteRest(this, 0); - } - else - { + } else { arg.operandReg = src; arg.WriteRex(this, 0, 0); Write8(0x66); @@ -1528,8 +1502,7 @@ void XEmitter::MOVQ_xmm(OpArg arg, X64Reg src) } } -void XEmitter::WriteMXCSR(OpArg arg, int ext) -{ +void XEmitter::WriteMXCSR(OpArg arg, int ext) { if (arg.IsImm() || arg.IsSimpleReg()) ASSERT_MSG(0, "MXCSR - invalid operand"); @@ -1540,143 +1513,357 @@ void XEmitter::WriteMXCSR(OpArg arg, int ext) arg.WriteRest(this); } -void XEmitter::STMXCSR(const OpArg& memloc) {WriteMXCSR(memloc, 3);} -void XEmitter::LDMXCSR(const OpArg& memloc) {WriteMXCSR(memloc, 2);} - -void XEmitter::MOVNTDQ(const OpArg& arg, X64Reg regOp) {WriteSSEOp(0x66, sseMOVNTDQ, regOp, arg);} -void XEmitter::MOVNTPS(const OpArg& arg, X64Reg regOp) {WriteSSEOp(0x00, sseMOVNTP, regOp, arg);} -void XEmitter::MOVNTPD(const OpArg& arg, X64Reg regOp) {WriteSSEOp(0x66, sseMOVNTP, regOp, arg);} - -void XEmitter::ADDSS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF3, sseADD, regOp, arg);} -void XEmitter::ADDSD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF2, sseADD, regOp, arg);} -void XEmitter::SUBSS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF3, sseSUB, regOp, arg);} -void XEmitter::SUBSD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF2, sseSUB, regOp, arg);} -void XEmitter::CMPSS(X64Reg regOp, const OpArg& arg, u8 compare) {WriteSSEOp(0xF3, sseCMP, regOp, arg, 1); Write8(compare);} -void XEmitter::CMPSD(X64Reg regOp, const OpArg& arg, u8 compare) {WriteSSEOp(0xF2, sseCMP, regOp, arg, 1); Write8(compare);} -void XEmitter::MULSS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF3, sseMUL, regOp, arg);} -void XEmitter::MULSD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF2, sseMUL, regOp, arg);} -void XEmitter::DIVSS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF3, sseDIV, regOp, arg);} -void XEmitter::DIVSD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF2, sseDIV, regOp, arg);} -void XEmitter::MINSS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF3, sseMIN, regOp, arg);} -void XEmitter::MINSD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF2, sseMIN, regOp, arg);} -void XEmitter::MAXSS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF3, sseMAX, regOp, arg);} -void XEmitter::MAXSD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF2, sseMAX, regOp, arg);} -void XEmitter::SQRTSS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF3, sseSQRT, regOp, arg);} -void XEmitter::SQRTSD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF2, sseSQRT, regOp, arg);} -void XEmitter::RCPSS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF3, sseRCP, regOp, arg);} -void XEmitter::RSQRTSS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF3, sseRSQRT, regOp, arg);} - -void XEmitter::ADDPS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x00, sseADD, regOp, arg);} -void XEmitter::ADDPD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x66, sseADD, regOp, arg);} -void XEmitter::SUBPS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x00, sseSUB, regOp, arg);} -void XEmitter::SUBPD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x66, sseSUB, regOp, arg);} -void XEmitter::CMPPS(X64Reg regOp, const OpArg& arg, u8 compare) {WriteSSEOp(0x00, sseCMP, regOp, arg, 1); Write8(compare);} -void XEmitter::CMPPD(X64Reg regOp, const OpArg& arg, u8 compare) {WriteSSEOp(0x66, sseCMP, regOp, arg, 1); Write8(compare);} -void XEmitter::ANDPS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x00, sseAND, regOp, arg);} -void XEmitter::ANDPD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x66, sseAND, regOp, arg);} -void XEmitter::ANDNPS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x00, sseANDN, regOp, arg);} -void XEmitter::ANDNPD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x66, sseANDN, regOp, arg);} -void XEmitter::ORPS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x00, sseOR, regOp, arg);} -void XEmitter::ORPD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x66, sseOR, regOp, arg);} -void XEmitter::XORPS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x00, sseXOR, regOp, arg);} -void XEmitter::XORPD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x66, sseXOR, regOp, arg);} -void XEmitter::MULPS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x00, sseMUL, regOp, arg);} -void XEmitter::MULPD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x66, sseMUL, regOp, arg);} -void XEmitter::DIVPS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x00, sseDIV, regOp, arg);} -void XEmitter::DIVPD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x66, sseDIV, regOp, arg);} -void XEmitter::MINPS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x00, sseMIN, regOp, arg);} -void XEmitter::MINPD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x66, sseMIN, regOp, arg);} -void XEmitter::MAXPS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x00, sseMAX, regOp, arg);} -void XEmitter::MAXPD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x66, sseMAX, regOp, arg);} -void XEmitter::SQRTPS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x00, sseSQRT, regOp, arg);} -void XEmitter::SQRTPD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x66, sseSQRT, regOp, arg);} -void XEmitter::RCPPS(X64Reg regOp, const OpArg& arg) { WriteSSEOp(0x00, sseRCP, regOp, arg); } -void XEmitter::RSQRTPS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x00, sseRSQRT, regOp, arg);} -void XEmitter::SHUFPS(X64Reg regOp, const OpArg& arg, u8 shuffle) {WriteSSEOp(0x00, sseSHUF, regOp, arg,1); Write8(shuffle);} -void XEmitter::SHUFPD(X64Reg regOp, const OpArg& arg, u8 shuffle) {WriteSSEOp(0x66, sseSHUF, regOp, arg,1); Write8(shuffle);} - -void XEmitter::HADDPS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF2, sseHADD, regOp, arg);} - -void XEmitter::COMISS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x00, sseCOMIS, regOp, arg);} //weird that these should be packed -void XEmitter::COMISD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x66, sseCOMIS, regOp, arg);} //ordered -void XEmitter::UCOMISS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x00, sseUCOMIS, regOp, arg);} //unordered -void XEmitter::UCOMISD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x66, sseUCOMIS, regOp, arg);} - -void XEmitter::MOVAPS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x00, sseMOVAPfromRM, regOp, arg);} -void XEmitter::MOVAPD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x66, sseMOVAPfromRM, regOp, arg);} -void XEmitter::MOVAPS(const OpArg& arg, X64Reg regOp) {WriteSSEOp(0x00, sseMOVAPtoRM, regOp, arg);} -void XEmitter::MOVAPD(const OpArg& arg, X64Reg regOp) {WriteSSEOp(0x66, sseMOVAPtoRM, regOp, arg);} - -void XEmitter::MOVUPS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x00, sseMOVUPfromRM, regOp, arg);} -void XEmitter::MOVUPD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x66, sseMOVUPfromRM, regOp, arg);} -void XEmitter::MOVUPS(const OpArg& arg, X64Reg regOp) {WriteSSEOp(0x00, sseMOVUPtoRM, regOp, arg);} -void XEmitter::MOVUPD(const OpArg& arg, X64Reg regOp) {WriteSSEOp(0x66, sseMOVUPtoRM, regOp, arg);} - -void XEmitter::MOVDQA(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x66, sseMOVDQfromRM, regOp, arg);} -void XEmitter::MOVDQA(const OpArg& arg, X64Reg regOp) {WriteSSEOp(0x66, sseMOVDQtoRM, regOp, arg);} -void XEmitter::MOVDQU(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF3, sseMOVDQfromRM, regOp, arg);} -void XEmitter::MOVDQU(const OpArg& arg, X64Reg regOp) {WriteSSEOp(0xF3, sseMOVDQtoRM, regOp, arg);} - -void XEmitter::MOVSS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF3, sseMOVUPfromRM, regOp, arg);} -void XEmitter::MOVSD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF2, sseMOVUPfromRM, regOp, arg);} -void XEmitter::MOVSS(const OpArg& arg, X64Reg regOp) {WriteSSEOp(0xF3, sseMOVUPtoRM, regOp, arg);} -void XEmitter::MOVSD(const OpArg& arg, X64Reg regOp) {WriteSSEOp(0xF2, sseMOVUPtoRM, regOp, arg);} - -void XEmitter::MOVLPS(X64Reg regOp, const OpArg& arg) { WriteSSEOp(0x00, sseMOVLPfromRM, regOp, arg); } -void XEmitter::MOVLPD(X64Reg regOp, const OpArg& arg) { WriteSSEOp(0x66, sseMOVLPfromRM, regOp, arg); } -void XEmitter::MOVLPS(const OpArg& arg, X64Reg regOp) { WriteSSEOp(0x00, sseMOVLPtoRM, regOp, arg); } -void XEmitter::MOVLPD(const OpArg& arg, X64Reg regOp) { WriteSSEOp(0x66, sseMOVLPtoRM, regOp, arg); } - -void XEmitter::MOVHPS(X64Reg regOp, const OpArg& arg) { WriteSSEOp(0x00, sseMOVHPfromRM, regOp, arg); } -void XEmitter::MOVHPD(X64Reg regOp, const OpArg& arg) { WriteSSEOp(0x66, sseMOVHPfromRM, regOp, arg); } -void XEmitter::MOVHPS(const OpArg& arg, X64Reg regOp) { WriteSSEOp(0x00, sseMOVHPtoRM, regOp, arg); } -void XEmitter::MOVHPD(const OpArg& arg, X64Reg regOp) { WriteSSEOp(0x66, sseMOVHPtoRM, regOp, arg); } - -void XEmitter::MOVHLPS(X64Reg regOp1, X64Reg regOp2) {WriteSSEOp(0x00, sseMOVHLPS, regOp1, R(regOp2));} -void XEmitter::MOVLHPS(X64Reg regOp1, X64Reg regOp2) {WriteSSEOp(0x00, sseMOVLHPS, regOp1, R(regOp2));} - -void XEmitter::CVTPS2PD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x00, 0x5A, regOp, arg);} -void XEmitter::CVTPD2PS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x66, 0x5A, regOp, arg);} - -void XEmitter::CVTSD2SS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF2, 0x5A, regOp, arg);} -void XEmitter::CVTSS2SD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF3, 0x5A, regOp, arg);} -void XEmitter::CVTSD2SI(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF2, 0x2D, regOp, arg);} -void XEmitter::CVTSS2SI(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF3, 0x2D, regOp, arg);} -void XEmitter::CVTSI2SD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF2, 0x2A, regOp, arg);} -void XEmitter::CVTSI2SS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF3, 0x2A, regOp, arg);} - -void XEmitter::CVTDQ2PD(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF3, 0xE6, regOp, arg);} -void XEmitter::CVTDQ2PS(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x00, 0x5B, regOp, arg);} -void XEmitter::CVTPD2DQ(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF2, 0xE6, regOp, arg);} -void XEmitter::CVTPS2DQ(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x66, 0x5B, regOp, arg);} - -void XEmitter::CVTTSD2SI(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF2, 0x2C, regOp, arg);} -void XEmitter::CVTTSS2SI(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF3, 0x2C, regOp, arg);} -void XEmitter::CVTTPS2DQ(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0xF3, 0x5B, regOp, arg);} -void XEmitter::CVTTPD2DQ(X64Reg regOp, const OpArg& arg) {WriteSSEOp(0x66, 0xE6, regOp, arg);} - -void XEmitter::MASKMOVDQU(X64Reg dest, X64Reg src) {WriteSSEOp(0x66, sseMASKMOVDQU, dest, R(src));} - -void XEmitter::MOVMSKPS(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x00, 0x50, dest, arg);} -void XEmitter::MOVMSKPD(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0x50, dest, arg);} - -void XEmitter::LDDQU(X64Reg dest, const OpArg& arg) {WriteSSEOp(0xF2, sseLDDQU, dest, arg);} // For integer data only +void XEmitter::STMXCSR(const OpArg& memloc) { + WriteMXCSR(memloc, 3); +} +void XEmitter::LDMXCSR(const OpArg& memloc) { + WriteMXCSR(memloc, 2); +} + +void XEmitter::MOVNTDQ(const OpArg& arg, X64Reg regOp) { + WriteSSEOp(0x66, sseMOVNTDQ, regOp, arg); +} +void XEmitter::MOVNTPS(const OpArg& arg, X64Reg regOp) { + WriteSSEOp(0x00, sseMOVNTP, regOp, arg); +} +void XEmitter::MOVNTPD(const OpArg& arg, X64Reg regOp) { + WriteSSEOp(0x66, sseMOVNTP, regOp, arg); +} + +void XEmitter::ADDSS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF3, sseADD, regOp, arg); +} +void XEmitter::ADDSD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF2, sseADD, regOp, arg); +} +void XEmitter::SUBSS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF3, sseSUB, regOp, arg); +} +void XEmitter::SUBSD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF2, sseSUB, regOp, arg); +} +void XEmitter::CMPSS(X64Reg regOp, const OpArg& arg, u8 compare) { + WriteSSEOp(0xF3, sseCMP, regOp, arg, 1); + Write8(compare); +} +void XEmitter::CMPSD(X64Reg regOp, const OpArg& arg, u8 compare) { + WriteSSEOp(0xF2, sseCMP, regOp, arg, 1); + Write8(compare); +} +void XEmitter::MULSS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF3, sseMUL, regOp, arg); +} +void XEmitter::MULSD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF2, sseMUL, regOp, arg); +} +void XEmitter::DIVSS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF3, sseDIV, regOp, arg); +} +void XEmitter::DIVSD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF2, sseDIV, regOp, arg); +} +void XEmitter::MINSS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF3, sseMIN, regOp, arg); +} +void XEmitter::MINSD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF2, sseMIN, regOp, arg); +} +void XEmitter::MAXSS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF3, sseMAX, regOp, arg); +} +void XEmitter::MAXSD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF2, sseMAX, regOp, arg); +} +void XEmitter::SQRTSS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF3, sseSQRT, regOp, arg); +} +void XEmitter::SQRTSD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF2, sseSQRT, regOp, arg); +} +void XEmitter::RCPSS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF3, sseRCP, regOp, arg); +} +void XEmitter::RSQRTSS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF3, sseRSQRT, regOp, arg); +} + +void XEmitter::ADDPS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, sseADD, regOp, arg); +} +void XEmitter::ADDPD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, sseADD, regOp, arg); +} +void XEmitter::SUBPS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, sseSUB, regOp, arg); +} +void XEmitter::SUBPD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, sseSUB, regOp, arg); +} +void XEmitter::CMPPS(X64Reg regOp, const OpArg& arg, u8 compare) { + WriteSSEOp(0x00, sseCMP, regOp, arg, 1); + Write8(compare); +} +void XEmitter::CMPPD(X64Reg regOp, const OpArg& arg, u8 compare) { + WriteSSEOp(0x66, sseCMP, regOp, arg, 1); + Write8(compare); +} +void XEmitter::ANDPS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, sseAND, regOp, arg); +} +void XEmitter::ANDPD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, sseAND, regOp, arg); +} +void XEmitter::ANDNPS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, sseANDN, regOp, arg); +} +void XEmitter::ANDNPD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, sseANDN, regOp, arg); +} +void XEmitter::ORPS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, sseOR, regOp, arg); +} +void XEmitter::ORPD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, sseOR, regOp, arg); +} +void XEmitter::XORPS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, sseXOR, regOp, arg); +} +void XEmitter::XORPD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, sseXOR, regOp, arg); +} +void XEmitter::MULPS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, sseMUL, regOp, arg); +} +void XEmitter::MULPD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, sseMUL, regOp, arg); +} +void XEmitter::DIVPS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, sseDIV, regOp, arg); +} +void XEmitter::DIVPD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, sseDIV, regOp, arg); +} +void XEmitter::MINPS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, sseMIN, regOp, arg); +} +void XEmitter::MINPD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, sseMIN, regOp, arg); +} +void XEmitter::MAXPS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, sseMAX, regOp, arg); +} +void XEmitter::MAXPD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, sseMAX, regOp, arg); +} +void XEmitter::SQRTPS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, sseSQRT, regOp, arg); +} +void XEmitter::SQRTPD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, sseSQRT, regOp, arg); +} +void XEmitter::RCPPS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, sseRCP, regOp, arg); +} +void XEmitter::RSQRTPS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, sseRSQRT, regOp, arg); +} +void XEmitter::SHUFPS(X64Reg regOp, const OpArg& arg, u8 shuffle) { + WriteSSEOp(0x00, sseSHUF, regOp, arg, 1); + Write8(shuffle); +} +void XEmitter::SHUFPD(X64Reg regOp, const OpArg& arg, u8 shuffle) { + WriteSSEOp(0x66, sseSHUF, regOp, arg, 1); + Write8(shuffle); +} + +void XEmitter::HADDPS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF2, sseHADD, regOp, arg); +} + +void XEmitter::COMISS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, sseCOMIS, regOp, arg); +} // weird that these should be packed +void XEmitter::COMISD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, sseCOMIS, regOp, arg); +} // ordered +void XEmitter::UCOMISS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, sseUCOMIS, regOp, arg); +} // unordered +void XEmitter::UCOMISD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, sseUCOMIS, regOp, arg); +} + +void XEmitter::MOVAPS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, sseMOVAPfromRM, regOp, arg); +} +void XEmitter::MOVAPD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, sseMOVAPfromRM, regOp, arg); +} +void XEmitter::MOVAPS(const OpArg& arg, X64Reg regOp) { + WriteSSEOp(0x00, sseMOVAPtoRM, regOp, arg); +} +void XEmitter::MOVAPD(const OpArg& arg, X64Reg regOp) { + WriteSSEOp(0x66, sseMOVAPtoRM, regOp, arg); +} + +void XEmitter::MOVUPS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, sseMOVUPfromRM, regOp, arg); +} +void XEmitter::MOVUPD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, sseMOVUPfromRM, regOp, arg); +} +void XEmitter::MOVUPS(const OpArg& arg, X64Reg regOp) { + WriteSSEOp(0x00, sseMOVUPtoRM, regOp, arg); +} +void XEmitter::MOVUPD(const OpArg& arg, X64Reg regOp) { + WriteSSEOp(0x66, sseMOVUPtoRM, regOp, arg); +} + +void XEmitter::MOVDQA(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, sseMOVDQfromRM, regOp, arg); +} +void XEmitter::MOVDQA(const OpArg& arg, X64Reg regOp) { + WriteSSEOp(0x66, sseMOVDQtoRM, regOp, arg); +} +void XEmitter::MOVDQU(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF3, sseMOVDQfromRM, regOp, arg); +} +void XEmitter::MOVDQU(const OpArg& arg, X64Reg regOp) { + WriteSSEOp(0xF3, sseMOVDQtoRM, regOp, arg); +} + +void XEmitter::MOVSS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF3, sseMOVUPfromRM, regOp, arg); +} +void XEmitter::MOVSD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF2, sseMOVUPfromRM, regOp, arg); +} +void XEmitter::MOVSS(const OpArg& arg, X64Reg regOp) { + WriteSSEOp(0xF3, sseMOVUPtoRM, regOp, arg); +} +void XEmitter::MOVSD(const OpArg& arg, X64Reg regOp) { + WriteSSEOp(0xF2, sseMOVUPtoRM, regOp, arg); +} + +void XEmitter::MOVLPS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, sseMOVLPfromRM, regOp, arg); +} +void XEmitter::MOVLPD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, sseMOVLPfromRM, regOp, arg); +} +void XEmitter::MOVLPS(const OpArg& arg, X64Reg regOp) { + WriteSSEOp(0x00, sseMOVLPtoRM, regOp, arg); +} +void XEmitter::MOVLPD(const OpArg& arg, X64Reg regOp) { + WriteSSEOp(0x66, sseMOVLPtoRM, regOp, arg); +} + +void XEmitter::MOVHPS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, sseMOVHPfromRM, regOp, arg); +} +void XEmitter::MOVHPD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, sseMOVHPfromRM, regOp, arg); +} +void XEmitter::MOVHPS(const OpArg& arg, X64Reg regOp) { + WriteSSEOp(0x00, sseMOVHPtoRM, regOp, arg); +} +void XEmitter::MOVHPD(const OpArg& arg, X64Reg regOp) { + WriteSSEOp(0x66, sseMOVHPtoRM, regOp, arg); +} + +void XEmitter::MOVHLPS(X64Reg regOp1, X64Reg regOp2) { + WriteSSEOp(0x00, sseMOVHLPS, regOp1, R(regOp2)); +} +void XEmitter::MOVLHPS(X64Reg regOp1, X64Reg regOp2) { + WriteSSEOp(0x00, sseMOVLHPS, regOp1, R(regOp2)); +} + +void XEmitter::CVTPS2PD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, 0x5A, regOp, arg); +} +void XEmitter::CVTPD2PS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, 0x5A, regOp, arg); +} + +void XEmitter::CVTSD2SS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF2, 0x5A, regOp, arg); +} +void XEmitter::CVTSS2SD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF3, 0x5A, regOp, arg); +} +void XEmitter::CVTSD2SI(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF2, 0x2D, regOp, arg); +} +void XEmitter::CVTSS2SI(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF3, 0x2D, regOp, arg); +} +void XEmitter::CVTSI2SD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF2, 0x2A, regOp, arg); +} +void XEmitter::CVTSI2SS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF3, 0x2A, regOp, arg); +} + +void XEmitter::CVTDQ2PD(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF3, 0xE6, regOp, arg); +} +void XEmitter::CVTDQ2PS(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x00, 0x5B, regOp, arg); +} +void XEmitter::CVTPD2DQ(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF2, 0xE6, regOp, arg); +} +void XEmitter::CVTPS2DQ(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, 0x5B, regOp, arg); +} + +void XEmitter::CVTTSD2SI(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF2, 0x2C, regOp, arg); +} +void XEmitter::CVTTSS2SI(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF3, 0x2C, regOp, arg); +} +void XEmitter::CVTTPS2DQ(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0xF3, 0x5B, regOp, arg); +} +void XEmitter::CVTTPD2DQ(X64Reg regOp, const OpArg& arg) { + WriteSSEOp(0x66, 0xE6, regOp, arg); +} + +void XEmitter::MASKMOVDQU(X64Reg dest, X64Reg src) { + WriteSSEOp(0x66, sseMASKMOVDQU, dest, R(src)); +} + +void XEmitter::MOVMSKPS(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x00, 0x50, dest, arg); +} +void XEmitter::MOVMSKPD(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0x50, dest, arg); +} + +void XEmitter::LDDQU(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0xF2, sseLDDQU, dest, arg); +} // For integer data only // THESE TWO ARE UNTESTED. -void XEmitter::UNPCKLPS(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x00, 0x14, dest, arg);} -void XEmitter::UNPCKHPS(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x00, 0x15, dest, arg);} +void XEmitter::UNPCKLPS(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x00, 0x14, dest, arg); +} +void XEmitter::UNPCKHPS(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x00, 0x15, dest, arg); +} -void XEmitter::UNPCKLPD(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0x14, dest, arg);} -void XEmitter::UNPCKHPD(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0x15, dest, arg);} +void XEmitter::UNPCKLPD(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0x14, dest, arg); +} +void XEmitter::UNPCKHPD(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0x15, dest, arg); +} -void XEmitter::MOVDDUP(X64Reg regOp, const OpArg& arg) -{ - if (Common::GetCPUCaps().sse3) - { - WriteSSEOp(0xF2, 0x12, regOp, arg); //SSE3 movddup - } - else - { +void XEmitter::MOVDDUP(X64Reg regOp, const OpArg& arg) { + if (Common::GetCPUCaps().sse3) { + WriteSSEOp(0xF2, 0x12, regOp, arg); // SSE3 movddup + } else { // Simulate this instruction with SSE2 instructions if (!arg.IsSimpleReg(regOp)) MOVSD(regOp, arg); @@ -1684,38 +1871,48 @@ void XEmitter::MOVDDUP(X64Reg regOp, const OpArg& arg) } } -//There are a few more left +// There are a few more left // Also some integer instructions are missing -void XEmitter::PACKSSDW(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0x6B, dest, arg);} -void XEmitter::PACKSSWB(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0x63, dest, arg);} -void XEmitter::PACKUSWB(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0x67, dest, arg);} +void XEmitter::PACKSSDW(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0x6B, dest, arg); +} +void XEmitter::PACKSSWB(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0x63, dest, arg); +} +void XEmitter::PACKUSWB(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0x67, dest, arg); +} -void XEmitter::PUNPCKLBW(X64Reg dest, const OpArg &arg) {WriteSSEOp(0x66, 0x60, dest, arg);} -void XEmitter::PUNPCKLWD(X64Reg dest, const OpArg &arg) {WriteSSEOp(0x66, 0x61, dest, arg);} -void XEmitter::PUNPCKLDQ(X64Reg dest, const OpArg &arg) {WriteSSEOp(0x66, 0x62, dest, arg);} -void XEmitter::PUNPCKLQDQ(X64Reg dest, const OpArg &arg) {WriteSSEOp(0x66, 0x6C, dest, arg);} +void XEmitter::PUNPCKLBW(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0x60, dest, arg); +} +void XEmitter::PUNPCKLWD(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0x61, dest, arg); +} +void XEmitter::PUNPCKLDQ(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0x62, dest, arg); +} +void XEmitter::PUNPCKLQDQ(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0x6C, dest, arg); +} -void XEmitter::PSRLW(X64Reg reg, int shift) -{ +void XEmitter::PSRLW(X64Reg reg, int shift) { WriteSSEOp(0x66, 0x71, (X64Reg)2, R(reg)); Write8(shift); } -void XEmitter::PSRLD(X64Reg reg, int shift) -{ +void XEmitter::PSRLD(X64Reg reg, int shift) { WriteSSEOp(0x66, 0x72, (X64Reg)2, R(reg)); Write8(shift); } -void XEmitter::PSRLQ(X64Reg reg, int shift) -{ +void XEmitter::PSRLQ(X64Reg reg, int shift) { WriteSSEOp(0x66, 0x73, (X64Reg)2, R(reg)); Write8(shift); } -void XEmitter::PSRLQ(X64Reg reg, const OpArg& arg) -{ +void XEmitter::PSRLQ(X64Reg reg, const OpArg& arg) { WriteSSEOp(0x66, 0xd3, reg, arg); } @@ -1724,20 +1921,17 @@ void XEmitter::PSRLDQ(X64Reg reg, int shift) { Write8(shift); } -void XEmitter::PSLLW(X64Reg reg, int shift) -{ +void XEmitter::PSLLW(X64Reg reg, int shift) { WriteSSEOp(0x66, 0x71, (X64Reg)6, R(reg)); Write8(shift); } -void XEmitter::PSLLD(X64Reg reg, int shift) -{ +void XEmitter::PSLLD(X64Reg reg, int shift) { WriteSSEOp(0x66, 0x72, (X64Reg)6, R(reg)); Write8(shift); } -void XEmitter::PSLLQ(X64Reg reg, int shift) -{ +void XEmitter::PSLLQ(X64Reg reg, int shift) { WriteSSEOp(0x66, 0x73, (X64Reg)6, R(reg)); Write8(shift); } @@ -1747,267 +1941,643 @@ void XEmitter::PSLLDQ(X64Reg reg, int shift) { Write8(shift); } -void XEmitter::PSRAW(X64Reg reg, int shift) -{ +void XEmitter::PSRAW(X64Reg reg, int shift) { WriteSSEOp(0x66, 0x71, (X64Reg)4, R(reg)); Write8(shift); } -void XEmitter::PSRAD(X64Reg reg, int shift) -{ +void XEmitter::PSRAD(X64Reg reg, int shift) { WriteSSEOp(0x66, 0x72, (X64Reg)4, R(reg)); Write8(shift); } -void XEmitter::WriteSSSE3Op(u8 opPrefix, u16 op, X64Reg regOp, const OpArg& arg, int extrabytes) -{ +void XEmitter::WriteSSSE3Op(u8 opPrefix, u16 op, X64Reg regOp, const OpArg& arg, int extrabytes) { if (!Common::GetCPUCaps().ssse3) ASSERT_MSG(0, "Trying to use SSSE3 on a system that doesn't support it. Bad programmer."); WriteSSEOp(opPrefix, op, regOp, arg, extrabytes); } -void XEmitter::WriteSSE41Op(u8 opPrefix, u16 op, X64Reg regOp, const OpArg& arg, int extrabytes) -{ +void XEmitter::WriteSSE41Op(u8 opPrefix, u16 op, X64Reg regOp, const OpArg& arg, int extrabytes) { if (!Common::GetCPUCaps().sse4_1) ASSERT_MSG(0, "Trying to use SSE4.1 on a system that doesn't support it. Bad programmer."); WriteSSEOp(opPrefix, op, regOp, arg, extrabytes); } -void XEmitter::PSHUFB(X64Reg dest, const OpArg& arg) {WriteSSSE3Op(0x66, 0x3800, dest, arg);} -void XEmitter::PTEST(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x3817, dest, arg);} -void XEmitter::PACKUSDW(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x382b, dest, arg);} -void XEmitter::DPPS(X64Reg dest, const OpArg& arg, u8 mask) {WriteSSE41Op(0x66, 0x3A40, dest, arg, 1); Write8(mask);} - -void XEmitter::PMINSB(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x3838, dest, arg);} -void XEmitter::PMINSD(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x3839, dest, arg);} -void XEmitter::PMINUW(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x383a, dest, arg);} -void XEmitter::PMINUD(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x383b, dest, arg);} -void XEmitter::PMAXSB(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x383c, dest, arg);} -void XEmitter::PMAXSD(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x383d, dest, arg);} -void XEmitter::PMAXUW(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x383e, dest, arg);} -void XEmitter::PMAXUD(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x383f, dest, arg);} - -void XEmitter::PMOVSXBW(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x3820, dest, arg);} -void XEmitter::PMOVSXBD(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x3821, dest, arg);} -void XEmitter::PMOVSXBQ(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x3822, dest, arg);} -void XEmitter::PMOVSXWD(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x3823, dest, arg);} -void XEmitter::PMOVSXWQ(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x3824, dest, arg);} -void XEmitter::PMOVSXDQ(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x3825, dest, arg);} -void XEmitter::PMOVZXBW(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x3830, dest, arg);} -void XEmitter::PMOVZXBD(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x3831, dest, arg);} -void XEmitter::PMOVZXBQ(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x3832, dest, arg);} -void XEmitter::PMOVZXWD(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x3833, dest, arg);} -void XEmitter::PMOVZXWQ(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x3834, dest, arg);} -void XEmitter::PMOVZXDQ(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x3835, dest, arg);} - -void XEmitter::PBLENDVB(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x3810, dest, arg);} -void XEmitter::BLENDVPS(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x3814, dest, arg);} -void XEmitter::BLENDVPD(X64Reg dest, const OpArg& arg) {WriteSSE41Op(0x66, 0x3815, dest, arg);} -void XEmitter::BLENDPS(X64Reg dest, const OpArg& arg, u8 blend) { WriteSSE41Op(0x66, 0x3A0C, dest, arg, 1); Write8(blend); } -void XEmitter::BLENDPD(X64Reg dest, const OpArg& arg, u8 blend) { WriteSSE41Op(0x66, 0x3A0D, dest, arg, 1); Write8(blend); } - -void XEmitter::ROUNDSS(X64Reg dest, const OpArg& arg, u8 mode) {WriteSSE41Op(0x66, 0x3A0A, dest, arg, 1); Write8(mode);} -void XEmitter::ROUNDSD(X64Reg dest, const OpArg& arg, u8 mode) {WriteSSE41Op(0x66, 0x3A0B, dest, arg, 1); Write8(mode);} -void XEmitter::ROUNDPS(X64Reg dest, const OpArg& arg, u8 mode) {WriteSSE41Op(0x66, 0x3A08, dest, arg, 1); Write8(mode);} -void XEmitter::ROUNDPD(X64Reg dest, const OpArg& arg, u8 mode) {WriteSSE41Op(0x66, 0x3A09, dest, arg, 1); Write8(mode);} - -void XEmitter::PAND(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xDB, dest, arg);} -void XEmitter::PANDN(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xDF, dest, arg);} -void XEmitter::PXOR(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xEF, dest, arg);} -void XEmitter::POR(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xEB, dest, arg);} - -void XEmitter::PADDB(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xFC, dest, arg);} -void XEmitter::PADDW(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xFD, dest, arg);} -void XEmitter::PADDD(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xFE, dest, arg);} -void XEmitter::PADDQ(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xD4, dest, arg);} - -void XEmitter::PADDSB(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xEC, dest, arg);} -void XEmitter::PADDSW(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xED, dest, arg);} -void XEmitter::PADDUSB(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xDC, dest, arg);} -void XEmitter::PADDUSW(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xDD, dest, arg);} - -void XEmitter::PSUBB(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xF8, dest, arg);} -void XEmitter::PSUBW(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xF9, dest, arg);} -void XEmitter::PSUBD(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xFA, dest, arg);} -void XEmitter::PSUBQ(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xFB, dest, arg);} - -void XEmitter::PSUBSB(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xE8, dest, arg);} -void XEmitter::PSUBSW(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xE9, dest, arg);} -void XEmitter::PSUBUSB(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xD8, dest, arg);} -void XEmitter::PSUBUSW(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xD9, dest, arg);} - -void XEmitter::PAVGB(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xE0, dest, arg);} -void XEmitter::PAVGW(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xE3, dest, arg);} - -void XEmitter::PCMPEQB(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0x74, dest, arg);} -void XEmitter::PCMPEQW(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0x75, dest, arg);} -void XEmitter::PCMPEQD(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0x76, dest, arg);} - -void XEmitter::PCMPGTB(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0x64, dest, arg);} -void XEmitter::PCMPGTW(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0x65, dest, arg);} -void XEmitter::PCMPGTD(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0x66, dest, arg);} - -void XEmitter::PEXTRW(X64Reg dest, const OpArg& arg, u8 subreg) {WriteSSEOp(0x66, 0xC5, dest, arg, 1); Write8(subreg);} -void XEmitter::PINSRW(X64Reg dest, const OpArg& arg, u8 subreg) {WriteSSEOp(0x66, 0xC4, dest, arg, 1); Write8(subreg);} - -void XEmitter::PMADDWD(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xF5, dest, arg); } -void XEmitter::PSADBW(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xF6, dest, arg);} - -void XEmitter::PMAXSW(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xEE, dest, arg); } -void XEmitter::PMAXUB(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xDE, dest, arg); } -void XEmitter::PMINSW(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xEA, dest, arg); } -void XEmitter::PMINUB(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xDA, dest, arg); } - -void XEmitter::PMOVMSKB(X64Reg dest, const OpArg& arg) {WriteSSEOp(0x66, 0xD7, dest, arg); } -void XEmitter::PSHUFD(X64Reg regOp, const OpArg& arg, u8 shuffle) {WriteSSEOp(0x66, 0x70, regOp, arg, 1); Write8(shuffle);} -void XEmitter::PSHUFLW(X64Reg regOp, const OpArg& arg, u8 shuffle) {WriteSSEOp(0xF2, 0x70, regOp, arg, 1); Write8(shuffle);} -void XEmitter::PSHUFHW(X64Reg regOp, const OpArg& arg, u8 shuffle) {WriteSSEOp(0xF3, 0x70, regOp, arg, 1); Write8(shuffle);} +void XEmitter::PSHUFB(X64Reg dest, const OpArg& arg) { + WriteSSSE3Op(0x66, 0x3800, dest, arg); +} +void XEmitter::PTEST(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x3817, dest, arg); +} +void XEmitter::PACKUSDW(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x382b, dest, arg); +} +void XEmitter::DPPS(X64Reg dest, const OpArg& arg, u8 mask) { + WriteSSE41Op(0x66, 0x3A40, dest, arg, 1); + Write8(mask); +} + +void XEmitter::PMINSB(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x3838, dest, arg); +} +void XEmitter::PMINSD(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x3839, dest, arg); +} +void XEmitter::PMINUW(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x383a, dest, arg); +} +void XEmitter::PMINUD(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x383b, dest, arg); +} +void XEmitter::PMAXSB(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x383c, dest, arg); +} +void XEmitter::PMAXSD(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x383d, dest, arg); +} +void XEmitter::PMAXUW(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x383e, dest, arg); +} +void XEmitter::PMAXUD(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x383f, dest, arg); +} + +void XEmitter::PMOVSXBW(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x3820, dest, arg); +} +void XEmitter::PMOVSXBD(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x3821, dest, arg); +} +void XEmitter::PMOVSXBQ(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x3822, dest, arg); +} +void XEmitter::PMOVSXWD(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x3823, dest, arg); +} +void XEmitter::PMOVSXWQ(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x3824, dest, arg); +} +void XEmitter::PMOVSXDQ(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x3825, dest, arg); +} +void XEmitter::PMOVZXBW(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x3830, dest, arg); +} +void XEmitter::PMOVZXBD(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x3831, dest, arg); +} +void XEmitter::PMOVZXBQ(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x3832, dest, arg); +} +void XEmitter::PMOVZXWD(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x3833, dest, arg); +} +void XEmitter::PMOVZXWQ(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x3834, dest, arg); +} +void XEmitter::PMOVZXDQ(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x3835, dest, arg); +} + +void XEmitter::PBLENDVB(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x3810, dest, arg); +} +void XEmitter::BLENDVPS(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x3814, dest, arg); +} +void XEmitter::BLENDVPD(X64Reg dest, const OpArg& arg) { + WriteSSE41Op(0x66, 0x3815, dest, arg); +} +void XEmitter::BLENDPS(X64Reg dest, const OpArg& arg, u8 blend) { + WriteSSE41Op(0x66, 0x3A0C, dest, arg, 1); + Write8(blend); +} +void XEmitter::BLENDPD(X64Reg dest, const OpArg& arg, u8 blend) { + WriteSSE41Op(0x66, 0x3A0D, dest, arg, 1); + Write8(blend); +} + +void XEmitter::ROUNDSS(X64Reg dest, const OpArg& arg, u8 mode) { + WriteSSE41Op(0x66, 0x3A0A, dest, arg, 1); + Write8(mode); +} +void XEmitter::ROUNDSD(X64Reg dest, const OpArg& arg, u8 mode) { + WriteSSE41Op(0x66, 0x3A0B, dest, arg, 1); + Write8(mode); +} +void XEmitter::ROUNDPS(X64Reg dest, const OpArg& arg, u8 mode) { + WriteSSE41Op(0x66, 0x3A08, dest, arg, 1); + Write8(mode); +} +void XEmitter::ROUNDPD(X64Reg dest, const OpArg& arg, u8 mode) { + WriteSSE41Op(0x66, 0x3A09, dest, arg, 1); + Write8(mode); +} + +void XEmitter::PAND(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xDB, dest, arg); +} +void XEmitter::PANDN(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xDF, dest, arg); +} +void XEmitter::PXOR(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xEF, dest, arg); +} +void XEmitter::POR(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xEB, dest, arg); +} + +void XEmitter::PADDB(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xFC, dest, arg); +} +void XEmitter::PADDW(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xFD, dest, arg); +} +void XEmitter::PADDD(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xFE, dest, arg); +} +void XEmitter::PADDQ(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xD4, dest, arg); +} + +void XEmitter::PADDSB(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xEC, dest, arg); +} +void XEmitter::PADDSW(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xED, dest, arg); +} +void XEmitter::PADDUSB(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xDC, dest, arg); +} +void XEmitter::PADDUSW(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xDD, dest, arg); +} + +void XEmitter::PSUBB(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xF8, dest, arg); +} +void XEmitter::PSUBW(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xF9, dest, arg); +} +void XEmitter::PSUBD(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xFA, dest, arg); +} +void XEmitter::PSUBQ(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xFB, dest, arg); +} + +void XEmitter::PSUBSB(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xE8, dest, arg); +} +void XEmitter::PSUBSW(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xE9, dest, arg); +} +void XEmitter::PSUBUSB(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xD8, dest, arg); +} +void XEmitter::PSUBUSW(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xD9, dest, arg); +} + +void XEmitter::PAVGB(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xE0, dest, arg); +} +void XEmitter::PAVGW(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xE3, dest, arg); +} + +void XEmitter::PCMPEQB(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0x74, dest, arg); +} +void XEmitter::PCMPEQW(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0x75, dest, arg); +} +void XEmitter::PCMPEQD(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0x76, dest, arg); +} + +void XEmitter::PCMPGTB(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0x64, dest, arg); +} +void XEmitter::PCMPGTW(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0x65, dest, arg); +} +void XEmitter::PCMPGTD(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0x66, dest, arg); +} + +void XEmitter::PEXTRW(X64Reg dest, const OpArg& arg, u8 subreg) { + WriteSSEOp(0x66, 0xC5, dest, arg, 1); + Write8(subreg); +} +void XEmitter::PINSRW(X64Reg dest, const OpArg& arg, u8 subreg) { + WriteSSEOp(0x66, 0xC4, dest, arg, 1); + Write8(subreg); +} + +void XEmitter::PMADDWD(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xF5, dest, arg); +} +void XEmitter::PSADBW(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xF6, dest, arg); +} + +void XEmitter::PMAXSW(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xEE, dest, arg); +} +void XEmitter::PMAXUB(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xDE, dest, arg); +} +void XEmitter::PMINSW(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xEA, dest, arg); +} +void XEmitter::PMINUB(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xDA, dest, arg); +} + +void XEmitter::PMOVMSKB(X64Reg dest, const OpArg& arg) { + WriteSSEOp(0x66, 0xD7, dest, arg); +} +void XEmitter::PSHUFD(X64Reg regOp, const OpArg& arg, u8 shuffle) { + WriteSSEOp(0x66, 0x70, regOp, arg, 1); + Write8(shuffle); +} +void XEmitter::PSHUFLW(X64Reg regOp, const OpArg& arg, u8 shuffle) { + WriteSSEOp(0xF2, 0x70, regOp, arg, 1); + Write8(shuffle); +} +void XEmitter::PSHUFHW(X64Reg regOp, const OpArg& arg, u8 shuffle) { + WriteSSEOp(0xF3, 0x70, regOp, arg, 1); + Write8(shuffle); +} // VEX -void XEmitter::VADDSD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) {WriteAVXOp(0xF2, sseADD, regOp1, regOp2, arg);} -void XEmitter::VSUBSD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) {WriteAVXOp(0xF2, sseSUB, regOp1, regOp2, arg);} -void XEmitter::VMULSD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) {WriteAVXOp(0xF2, sseMUL, regOp1, regOp2, arg);} -void XEmitter::VDIVSD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) {WriteAVXOp(0xF2, sseDIV, regOp1, regOp2, arg);} -void XEmitter::VADDPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) {WriteAVXOp(0x66, sseADD, regOp1, regOp2, arg);} -void XEmitter::VSUBPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) {WriteAVXOp(0x66, sseSUB, regOp1, regOp2, arg);} -void XEmitter::VMULPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) {WriteAVXOp(0x66, sseMUL, regOp1, regOp2, arg);} -void XEmitter::VDIVPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) {WriteAVXOp(0x66, sseDIV, regOp1, regOp2, arg);} -void XEmitter::VSQRTSD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) {WriteAVXOp(0xF2, sseSQRT, regOp1, regOp2, arg);} -void XEmitter::VSHUFPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg, u8 shuffle) {WriteAVXOp(0x66, sseSHUF, regOp1, regOp2, arg, 1); Write8(shuffle);} -void XEmitter::VUNPCKLPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg){WriteAVXOp(0x66, 0x14, regOp1, regOp2, arg);} -void XEmitter::VUNPCKHPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg){WriteAVXOp(0x66, 0x15, regOp1, regOp2, arg);} - -void XEmitter::VANDPS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x00, sseAND, regOp1, regOp2, arg); } -void XEmitter::VANDPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, sseAND, regOp1, regOp2, arg); } -void XEmitter::VANDNPS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x00, sseANDN, regOp1, regOp2, arg); } -void XEmitter::VANDNPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, sseANDN, regOp1, regOp2, arg); } -void XEmitter::VORPS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x00, sseOR, regOp1, regOp2, arg); } -void XEmitter::VORPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, sseOR, regOp1, regOp2, arg); } -void XEmitter::VXORPS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x00, sseXOR, regOp1, regOp2, arg); } -void XEmitter::VXORPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, sseXOR, regOp1, regOp2, arg); } - -void XEmitter::VPAND(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0xDB, regOp1, regOp2, arg); } -void XEmitter::VPANDN(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0xDF, regOp1, regOp2, arg); } -void XEmitter::VPOR(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0xEB, regOp1, regOp2, arg); } -void XEmitter::VPXOR(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0xEF, regOp1, regOp2, arg); } - -void XEmitter::VFMADD132PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x3898, regOp1, regOp2, arg); } -void XEmitter::VFMADD213PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38A8, regOp1, regOp2, arg); } -void XEmitter::VFMADD231PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38B8, regOp1, regOp2, arg); } -void XEmitter::VFMADD132PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x3898, regOp1, regOp2, arg, 1); } -void XEmitter::VFMADD213PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38A8, regOp1, regOp2, arg, 1); } -void XEmitter::VFMADD231PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38B8, regOp1, regOp2, arg, 1); } -void XEmitter::VFMADD132SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x3899, regOp1, regOp2, arg); } -void XEmitter::VFMADD213SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38A9, regOp1, regOp2, arg); } -void XEmitter::VFMADD231SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38B9, regOp1, regOp2, arg); } -void XEmitter::VFMADD132SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x3899, regOp1, regOp2, arg, 1); } -void XEmitter::VFMADD213SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38A9, regOp1, regOp2, arg, 1); } -void XEmitter::VFMADD231SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38B9, regOp1, regOp2, arg, 1); } -void XEmitter::VFMSUB132PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x389A, regOp1, regOp2, arg); } -void XEmitter::VFMSUB213PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38AA, regOp1, regOp2, arg); } -void XEmitter::VFMSUB231PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38BA, regOp1, regOp2, arg); } -void XEmitter::VFMSUB132PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x389A, regOp1, regOp2, arg, 1); } -void XEmitter::VFMSUB213PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38AA, regOp1, regOp2, arg, 1); } -void XEmitter::VFMSUB231PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38BA, regOp1, regOp2, arg, 1); } -void XEmitter::VFMSUB132SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x389B, regOp1, regOp2, arg); } -void XEmitter::VFMSUB213SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38AB, regOp1, regOp2, arg); } -void XEmitter::VFMSUB231SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38BB, regOp1, regOp2, arg); } -void XEmitter::VFMSUB132SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x389B, regOp1, regOp2, arg, 1); } -void XEmitter::VFMSUB213SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38AB, regOp1, regOp2, arg, 1); } -void XEmitter::VFMSUB231SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38BB, regOp1, regOp2, arg, 1); } -void XEmitter::VFNMADD132PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x389C, regOp1, regOp2, arg); } -void XEmitter::VFNMADD213PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38AC, regOp1, regOp2, arg); } -void XEmitter::VFNMADD231PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38BC, regOp1, regOp2, arg); } -void XEmitter::VFNMADD132PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x389C, regOp1, regOp2, arg, 1); } -void XEmitter::VFNMADD213PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38AC, regOp1, regOp2, arg, 1); } -void XEmitter::VFNMADD231PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38BC, regOp1, regOp2, arg, 1); } -void XEmitter::VFNMADD132SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x389D, regOp1, regOp2, arg); } -void XEmitter::VFNMADD213SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38AD, regOp1, regOp2, arg); } -void XEmitter::VFNMADD231SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38BD, regOp1, regOp2, arg); } -void XEmitter::VFNMADD132SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x389D, regOp1, regOp2, arg, 1); } -void XEmitter::VFNMADD213SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38AD, regOp1, regOp2, arg, 1); } -void XEmitter::VFNMADD231SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38BD, regOp1, regOp2, arg, 1); } -void XEmitter::VFNMSUB132PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x389E, regOp1, regOp2, arg); } -void XEmitter::VFNMSUB213PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38AE, regOp1, regOp2, arg); } -void XEmitter::VFNMSUB231PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38BE, regOp1, regOp2, arg); } -void XEmitter::VFNMSUB132PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x389E, regOp1, regOp2, arg, 1); } -void XEmitter::VFNMSUB213PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38AE, regOp1, regOp2, arg, 1); } -void XEmitter::VFNMSUB231PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38BE, regOp1, regOp2, arg, 1); } -void XEmitter::VFNMSUB132SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x389F, regOp1, regOp2, arg); } -void XEmitter::VFNMSUB213SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38AF, regOp1, regOp2, arg); } -void XEmitter::VFNMSUB231SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38BF, regOp1, regOp2, arg); } -void XEmitter::VFNMSUB132SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x389F, regOp1, regOp2, arg, 1); } -void XEmitter::VFNMSUB213SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38AF, regOp1, regOp2, arg, 1); } -void XEmitter::VFNMSUB231SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38BF, regOp1, regOp2, arg, 1); } -void XEmitter::VFMADDSUB132PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x3896, regOp1, regOp2, arg); } -void XEmitter::VFMADDSUB213PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38A6, regOp1, regOp2, arg); } -void XEmitter::VFMADDSUB231PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38B6, regOp1, regOp2, arg); } -void XEmitter::VFMADDSUB132PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x3896, regOp1, regOp2, arg, 1); } -void XEmitter::VFMADDSUB213PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38A6, regOp1, regOp2, arg, 1); } -void XEmitter::VFMADDSUB231PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38B6, regOp1, regOp2, arg, 1); } -void XEmitter::VFMSUBADD132PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x3897, regOp1, regOp2, arg); } -void XEmitter::VFMSUBADD213PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38A7, regOp1, regOp2, arg); } -void XEmitter::VFMSUBADD231PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38B7, regOp1, regOp2, arg); } -void XEmitter::VFMSUBADD132PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x3897, regOp1, regOp2, arg, 1); } -void XEmitter::VFMSUBADD213PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38A7, regOp1, regOp2, arg, 1); } -void XEmitter::VFMSUBADD231PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { WriteAVXOp(0x66, 0x38B7, regOp1, regOp2, arg, 1); } - -void XEmitter::SARX(int bits, X64Reg regOp1, const OpArg& arg, X64Reg regOp2) {WriteBMI2Op(bits, 0xF3, 0x38F7, regOp1, regOp2, arg);} -void XEmitter::SHLX(int bits, X64Reg regOp1, const OpArg& arg, X64Reg regOp2) {WriteBMI2Op(bits, 0x66, 0x38F7, regOp1, regOp2, arg);} -void XEmitter::SHRX(int bits, X64Reg regOp1, const OpArg& arg, X64Reg regOp2) {WriteBMI2Op(bits, 0xF2, 0x38F7, regOp1, regOp2, arg);} -void XEmitter::RORX(int bits, X64Reg regOp, const OpArg& arg, u8 rotate) {WriteBMI2Op(bits, 0xF2, 0x3AF0, regOp, INVALID_REG, arg, 1); Write8(rotate);} -void XEmitter::PEXT(int bits, X64Reg regOp1, X64Reg regOp2, const OpArg& arg) {WriteBMI2Op(bits, 0xF3, 0x38F5, regOp1, regOp2, arg);} -void XEmitter::PDEP(int bits, X64Reg regOp1, X64Reg regOp2, const OpArg& arg) {WriteBMI2Op(bits, 0xF2, 0x38F5, regOp1, regOp2, arg);} -void XEmitter::MULX(int bits, X64Reg regOp1, X64Reg regOp2, const OpArg& arg) {WriteBMI2Op(bits, 0xF2, 0x38F6, regOp2, regOp1, arg);} -void XEmitter::BZHI(int bits, X64Reg regOp1, const OpArg& arg, X64Reg regOp2) {WriteBMI2Op(bits, 0x00, 0x38F5, regOp1, regOp2, arg);} -void XEmitter::BLSR(int bits, X64Reg regOp, const OpArg& arg) {WriteBMI1Op(bits, 0x00, 0x38F3, (X64Reg)0x1, regOp, arg);} -void XEmitter::BLSMSK(int bits, X64Reg regOp, const OpArg& arg) {WriteBMI1Op(bits, 0x00, 0x38F3, (X64Reg)0x2, regOp, arg);} -void XEmitter::BLSI(int bits, X64Reg regOp, const OpArg& arg) {WriteBMI1Op(bits, 0x00, 0x38F3, (X64Reg)0x3, regOp, arg);} -void XEmitter::BEXTR(int bits, X64Reg regOp1, const OpArg& arg, X64Reg regOp2){WriteBMI1Op(bits, 0x00, 0x38F7, regOp1, regOp2, arg);} -void XEmitter::ANDN(int bits, X64Reg regOp1, X64Reg regOp2, const OpArg& arg) {WriteBMI1Op(bits, 0x00, 0x38F2, regOp1, regOp2, arg);} +void XEmitter::VADDSD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0xF2, sseADD, regOp1, regOp2, arg); +} +void XEmitter::VSUBSD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0xF2, sseSUB, regOp1, regOp2, arg); +} +void XEmitter::VMULSD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0xF2, sseMUL, regOp1, regOp2, arg); +} +void XEmitter::VDIVSD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0xF2, sseDIV, regOp1, regOp2, arg); +} +void XEmitter::VADDPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, sseADD, regOp1, regOp2, arg); +} +void XEmitter::VSUBPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, sseSUB, regOp1, regOp2, arg); +} +void XEmitter::VMULPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, sseMUL, regOp1, regOp2, arg); +} +void XEmitter::VDIVPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, sseDIV, regOp1, regOp2, arg); +} +void XEmitter::VSQRTSD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0xF2, sseSQRT, regOp1, regOp2, arg); +} +void XEmitter::VSHUFPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg, u8 shuffle) { + WriteAVXOp(0x66, sseSHUF, regOp1, regOp2, arg, 1); + Write8(shuffle); +} +void XEmitter::VUNPCKLPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x14, regOp1, regOp2, arg); +} +void XEmitter::VUNPCKHPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x15, regOp1, regOp2, arg); +} + +void XEmitter::VANDPS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x00, sseAND, regOp1, regOp2, arg); +} +void XEmitter::VANDPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, sseAND, regOp1, regOp2, arg); +} +void XEmitter::VANDNPS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x00, sseANDN, regOp1, regOp2, arg); +} +void XEmitter::VANDNPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, sseANDN, regOp1, regOp2, arg); +} +void XEmitter::VORPS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x00, sseOR, regOp1, regOp2, arg); +} +void XEmitter::VORPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, sseOR, regOp1, regOp2, arg); +} +void XEmitter::VXORPS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x00, sseXOR, regOp1, regOp2, arg); +} +void XEmitter::VXORPD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, sseXOR, regOp1, regOp2, arg); +} + +void XEmitter::VPAND(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0xDB, regOp1, regOp2, arg); +} +void XEmitter::VPANDN(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0xDF, regOp1, regOp2, arg); +} +void XEmitter::VPOR(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0xEB, regOp1, regOp2, arg); +} +void XEmitter::VPXOR(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0xEF, regOp1, regOp2, arg); +} + +void XEmitter::VFMADD132PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x3898, regOp1, regOp2, arg); +} +void XEmitter::VFMADD213PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38A8, regOp1, regOp2, arg); +} +void XEmitter::VFMADD231PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38B8, regOp1, regOp2, arg); +} +void XEmitter::VFMADD132PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x3898, regOp1, regOp2, arg, 1); +} +void XEmitter::VFMADD213PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38A8, regOp1, regOp2, arg, 1); +} +void XEmitter::VFMADD231PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38B8, regOp1, regOp2, arg, 1); +} +void XEmitter::VFMADD132SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x3899, regOp1, regOp2, arg); +} +void XEmitter::VFMADD213SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38A9, regOp1, regOp2, arg); +} +void XEmitter::VFMADD231SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38B9, regOp1, regOp2, arg); +} +void XEmitter::VFMADD132SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x3899, regOp1, regOp2, arg, 1); +} +void XEmitter::VFMADD213SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38A9, regOp1, regOp2, arg, 1); +} +void XEmitter::VFMADD231SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38B9, regOp1, regOp2, arg, 1); +} +void XEmitter::VFMSUB132PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x389A, regOp1, regOp2, arg); +} +void XEmitter::VFMSUB213PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38AA, regOp1, regOp2, arg); +} +void XEmitter::VFMSUB231PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38BA, regOp1, regOp2, arg); +} +void XEmitter::VFMSUB132PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x389A, regOp1, regOp2, arg, 1); +} +void XEmitter::VFMSUB213PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38AA, regOp1, regOp2, arg, 1); +} +void XEmitter::VFMSUB231PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38BA, regOp1, regOp2, arg, 1); +} +void XEmitter::VFMSUB132SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x389B, regOp1, regOp2, arg); +} +void XEmitter::VFMSUB213SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38AB, regOp1, regOp2, arg); +} +void XEmitter::VFMSUB231SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38BB, regOp1, regOp2, arg); +} +void XEmitter::VFMSUB132SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x389B, regOp1, regOp2, arg, 1); +} +void XEmitter::VFMSUB213SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38AB, regOp1, regOp2, arg, 1); +} +void XEmitter::VFMSUB231SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38BB, regOp1, regOp2, arg, 1); +} +void XEmitter::VFNMADD132PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x389C, regOp1, regOp2, arg); +} +void XEmitter::VFNMADD213PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38AC, regOp1, regOp2, arg); +} +void XEmitter::VFNMADD231PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38BC, regOp1, regOp2, arg); +} +void XEmitter::VFNMADD132PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x389C, regOp1, regOp2, arg, 1); +} +void XEmitter::VFNMADD213PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38AC, regOp1, regOp2, arg, 1); +} +void XEmitter::VFNMADD231PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38BC, regOp1, regOp2, arg, 1); +} +void XEmitter::VFNMADD132SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x389D, regOp1, regOp2, arg); +} +void XEmitter::VFNMADD213SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38AD, regOp1, regOp2, arg); +} +void XEmitter::VFNMADD231SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38BD, regOp1, regOp2, arg); +} +void XEmitter::VFNMADD132SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x389D, regOp1, regOp2, arg, 1); +} +void XEmitter::VFNMADD213SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38AD, regOp1, regOp2, arg, 1); +} +void XEmitter::VFNMADD231SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38BD, regOp1, regOp2, arg, 1); +} +void XEmitter::VFNMSUB132PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x389E, regOp1, regOp2, arg); +} +void XEmitter::VFNMSUB213PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38AE, regOp1, regOp2, arg); +} +void XEmitter::VFNMSUB231PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38BE, regOp1, regOp2, arg); +} +void XEmitter::VFNMSUB132PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x389E, regOp1, regOp2, arg, 1); +} +void XEmitter::VFNMSUB213PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38AE, regOp1, regOp2, arg, 1); +} +void XEmitter::VFNMSUB231PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38BE, regOp1, regOp2, arg, 1); +} +void XEmitter::VFNMSUB132SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x389F, regOp1, regOp2, arg); +} +void XEmitter::VFNMSUB213SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38AF, regOp1, regOp2, arg); +} +void XEmitter::VFNMSUB231SS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38BF, regOp1, regOp2, arg); +} +void XEmitter::VFNMSUB132SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x389F, regOp1, regOp2, arg, 1); +} +void XEmitter::VFNMSUB213SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38AF, regOp1, regOp2, arg, 1); +} +void XEmitter::VFNMSUB231SD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38BF, regOp1, regOp2, arg, 1); +} +void XEmitter::VFMADDSUB132PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x3896, regOp1, regOp2, arg); +} +void XEmitter::VFMADDSUB213PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38A6, regOp1, regOp2, arg); +} +void XEmitter::VFMADDSUB231PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38B6, regOp1, regOp2, arg); +} +void XEmitter::VFMADDSUB132PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x3896, regOp1, regOp2, arg, 1); +} +void XEmitter::VFMADDSUB213PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38A6, regOp1, regOp2, arg, 1); +} +void XEmitter::VFMADDSUB231PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38B6, regOp1, regOp2, arg, 1); +} +void XEmitter::VFMSUBADD132PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x3897, regOp1, regOp2, arg); +} +void XEmitter::VFMSUBADD213PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38A7, regOp1, regOp2, arg); +} +void XEmitter::VFMSUBADD231PS(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38B7, regOp1, regOp2, arg); +} +void XEmitter::VFMSUBADD132PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x3897, regOp1, regOp2, arg, 1); +} +void XEmitter::VFMSUBADD213PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38A7, regOp1, regOp2, arg, 1); +} +void XEmitter::VFMSUBADD231PD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteAVXOp(0x66, 0x38B7, regOp1, regOp2, arg, 1); +} + +void XEmitter::SARX(int bits, X64Reg regOp1, const OpArg& arg, X64Reg regOp2) { + WriteBMI2Op(bits, 0xF3, 0x38F7, regOp1, regOp2, arg); +} +void XEmitter::SHLX(int bits, X64Reg regOp1, const OpArg& arg, X64Reg regOp2) { + WriteBMI2Op(bits, 0x66, 0x38F7, regOp1, regOp2, arg); +} +void XEmitter::SHRX(int bits, X64Reg regOp1, const OpArg& arg, X64Reg regOp2) { + WriteBMI2Op(bits, 0xF2, 0x38F7, regOp1, regOp2, arg); +} +void XEmitter::RORX(int bits, X64Reg regOp, const OpArg& arg, u8 rotate) { + WriteBMI2Op(bits, 0xF2, 0x3AF0, regOp, INVALID_REG, arg, 1); + Write8(rotate); +} +void XEmitter::PEXT(int bits, X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteBMI2Op(bits, 0xF3, 0x38F5, regOp1, regOp2, arg); +} +void XEmitter::PDEP(int bits, X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteBMI2Op(bits, 0xF2, 0x38F5, regOp1, regOp2, arg); +} +void XEmitter::MULX(int bits, X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteBMI2Op(bits, 0xF2, 0x38F6, regOp2, regOp1, arg); +} +void XEmitter::BZHI(int bits, X64Reg regOp1, const OpArg& arg, X64Reg regOp2) { + WriteBMI2Op(bits, 0x00, 0x38F5, regOp1, regOp2, arg); +} +void XEmitter::BLSR(int bits, X64Reg regOp, const OpArg& arg) { + WriteBMI1Op(bits, 0x00, 0x38F3, (X64Reg)0x1, regOp, arg); +} +void XEmitter::BLSMSK(int bits, X64Reg regOp, const OpArg& arg) { + WriteBMI1Op(bits, 0x00, 0x38F3, (X64Reg)0x2, regOp, arg); +} +void XEmitter::BLSI(int bits, X64Reg regOp, const OpArg& arg) { + WriteBMI1Op(bits, 0x00, 0x38F3, (X64Reg)0x3, regOp, arg); +} +void XEmitter::BEXTR(int bits, X64Reg regOp1, const OpArg& arg, X64Reg regOp2) { + WriteBMI1Op(bits, 0x00, 0x38F7, regOp1, regOp2, arg); +} +void XEmitter::ANDN(int bits, X64Reg regOp1, X64Reg regOp2, const OpArg& arg) { + WriteBMI1Op(bits, 0x00, 0x38F2, regOp1, regOp2, arg); +} // Prefixes -void XEmitter::LOCK() { Write8(0xF0); } -void XEmitter::REP() { Write8(0xF3); } -void XEmitter::REPNE() { Write8(0xF2); } -void XEmitter::FSOverride() { Write8(0x64); } -void XEmitter::GSOverride() { Write8(0x65); } +void XEmitter::LOCK() { + Write8(0xF0); +} +void XEmitter::REP() { + Write8(0xF3); +} +void XEmitter::REPNE() { + Write8(0xF2); +} +void XEmitter::FSOverride() { + Write8(0x64); +} +void XEmitter::GSOverride() { + Write8(0x65); +} -void XEmitter::FWAIT() -{ +void XEmitter::FWAIT() { Write8(0x9B); } // TODO: make this more generic -void XEmitter::WriteFloatLoadStore(int bits, FloatOp op, FloatOp op_80b, const OpArg& arg) -{ +void XEmitter::WriteFloatLoadStore(int bits, FloatOp op, FloatOp op_80b, const OpArg& arg) { int mf = 0; - ASSERT_MSG(!(bits == 80 && op_80b == floatINVALID), "WriteFloatLoadStore: 80 bits not supported for this instruction"); - switch (bits) - { - case 32: mf = 0; break; - case 64: mf = 4; break; - case 80: mf = 2; break; - default: ASSERT_MSG(0, "WriteFloatLoadStore: invalid bits (should be 32/64/80)"); + ASSERT_MSG(!(bits == 80 && op_80b == floatINVALID), + "WriteFloatLoadStore: 80 bits not supported for this instruction"); + switch (bits) { + case 32: + mf = 0; + break; + case 64: + mf = 4; + break; + case 80: + mf = 2; + break; + default: + ASSERT_MSG(0, "WriteFloatLoadStore: invalid bits (should be 32/64/80)"); } Write8(0xd9 | mf); // x87 instructions use the reg field of the ModR/M byte as opcode: if (bits == 80) op = op_80b; - arg.WriteRest(this, 0, (X64Reg) op); + arg.WriteRest(this, 0, (X64Reg)op); } -void XEmitter::FLD(int bits, const OpArg& src) {WriteFloatLoadStore(bits, floatLD, floatLD80, src);} -void XEmitter::FST(int bits, const OpArg& dest) {WriteFloatLoadStore(bits, floatST, floatINVALID, dest);} -void XEmitter::FSTP(int bits, const OpArg& dest) {WriteFloatLoadStore(bits, floatSTP, floatSTP80, dest);} -void XEmitter::FNSTSW_AX() { Write8(0xDF); Write8(0xE0); } +void XEmitter::FLD(int bits, const OpArg& src) { + WriteFloatLoadStore(bits, floatLD, floatLD80, src); +} +void XEmitter::FST(int bits, const OpArg& dest) { + WriteFloatLoadStore(bits, floatST, floatINVALID, dest); +} +void XEmitter::FSTP(int bits, const OpArg& dest) { + WriteFloatLoadStore(bits, floatSTP, floatSTP80, dest); +} +void XEmitter::FNSTSW_AX() { + Write8(0xDF); + Write8(0xE0); +} -void XEmitter::RDTSC() { Write8(0x0F); Write8(0x31); } +void XEmitter::RDTSC() { + Write8(0x0F); + Write8(0x31); +} void XCodeBlock::PoisonMemory() { // x86/64: 0xCC = breakpoint memset(region, 0xCC, region_size); } - } diff --git a/src/common/x64/emitter.h b/src/common/x64/emitter.h index 60a77dfe1..7d7cdde16 100644 --- a/src/common/x64/emitter.h +++ b/src/common/x64/emitter.h @@ -18,11 +18,10 @@ #pragma once #include <cstddef> - #include "common/assert.h" #include "common/bit_set.h" -#include "common/common_types.h" #include "common/code_block.h" +#include "common/common_types.h" #if defined(ARCHITECTURE_x86_64) && !defined(_ARCH_64) #define _ARCH_64 @@ -34,75 +33,145 @@ #define PTRBITS 32 #endif -namespace Gen -{ - -enum X64Reg -{ - EAX = 0, EBX = 3, ECX = 1, EDX = 2, - ESI = 6, EDI = 7, EBP = 5, ESP = 4, - - RAX = 0, RBX = 3, RCX = 1, RDX = 2, - RSI = 6, RDI = 7, RBP = 5, RSP = 4, - R8 = 8, R9 = 9, R10 = 10,R11 = 11, - R12 = 12,R13 = 13,R14 = 14,R15 = 15, - - AL = 0, BL = 3, CL = 1, DL = 2, - SIL = 6, DIL = 7, BPL = 5, SPL = 4, - AH = 0x104, BH = 0x107, CH = 0x105, DH = 0x106, - - AX = 0, BX = 3, CX = 1, DX = 2, - SI = 6, DI = 7, BP = 5, SP = 4, - - XMM0=0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, - XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, - - YMM0=0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7, - YMM8, YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15, +namespace Gen { + +enum X64Reg { + EAX = 0, + EBX = 3, + ECX = 1, + EDX = 2, + ESI = 6, + EDI = 7, + EBP = 5, + ESP = 4, + + RAX = 0, + RBX = 3, + RCX = 1, + RDX = 2, + RSI = 6, + RDI = 7, + RBP = 5, + RSP = 4, + R8 = 8, + R9 = 9, + R10 = 10, + R11 = 11, + R12 = 12, + R13 = 13, + R14 = 14, + R15 = 15, + + AL = 0, + BL = 3, + CL = 1, + DL = 2, + SIL = 6, + DIL = 7, + BPL = 5, + SPL = 4, + AH = 0x104, + BH = 0x107, + CH = 0x105, + DH = 0x106, + + AX = 0, + BX = 3, + CX = 1, + DX = 2, + SI = 6, + DI = 7, + BP = 5, + SP = 4, + + XMM0 = 0, + XMM1, + XMM2, + XMM3, + XMM4, + XMM5, + XMM6, + XMM7, + XMM8, + XMM9, + XMM10, + XMM11, + XMM12, + XMM13, + XMM14, + XMM15, + + YMM0 = 0, + YMM1, + YMM2, + YMM3, + YMM4, + YMM5, + YMM6, + YMM7, + YMM8, + YMM9, + YMM10, + YMM11, + YMM12, + YMM13, + YMM14, + YMM15, INVALID_REG = 0xFFFFFFFF }; -enum CCFlags -{ - CC_O = 0, - CC_NO = 1, - CC_B = 2, CC_C = 2, CC_NAE = 2, - CC_NB = 3, CC_NC = 3, CC_AE = 3, - CC_Z = 4, CC_E = 4, - CC_NZ = 5, CC_NE = 5, - CC_BE = 6, CC_NA = 6, - CC_NBE = 7, CC_A = 7, - CC_S = 8, - CC_NS = 9, - CC_P = 0xA, CC_PE = 0xA, - CC_NP = 0xB, CC_PO = 0xB, - CC_L = 0xC, CC_NGE = 0xC, - CC_NL = 0xD, CC_GE = 0xD, - CC_LE = 0xE, CC_NG = 0xE, - CC_NLE = 0xF, CC_G = 0xF +enum CCFlags { + CC_O = 0, + CC_NO = 1, + CC_B = 2, + CC_C = 2, + CC_NAE = 2, + CC_NB = 3, + CC_NC = 3, + CC_AE = 3, + CC_Z = 4, + CC_E = 4, + CC_NZ = 5, + CC_NE = 5, + CC_BE = 6, + CC_NA = 6, + CC_NBE = 7, + CC_A = 7, + CC_S = 8, + CC_NS = 9, + CC_P = 0xA, + CC_PE = 0xA, + CC_NP = 0xB, + CC_PO = 0xB, + CC_L = 0xC, + CC_NGE = 0xC, + CC_NL = 0xD, + CC_GE = 0xD, + CC_LE = 0xE, + CC_NG = 0xE, + CC_NLE = 0xF, + CC_G = 0xF }; -enum -{ +enum { NUMGPRs = 16, NUMXMMs = 16, }; -enum -{ +enum { SCALE_NONE = 0, SCALE_1 = 1, SCALE_2 = 2, SCALE_4 = 4, SCALE_8 = 8, SCALE_ATREG = 16, - //SCALE_NOBASE_1 is not supported and can be replaced with SCALE_ATREG + // SCALE_NOBASE_1 is not supported and can be replaced with SCALE_ATREG SCALE_NOBASE_2 = 34, SCALE_NOBASE_4 = 36, SCALE_NOBASE_8 = 40, SCALE_RIP = 0xFF, - SCALE_IMM8 = 0xF0, + SCALE_IMM8 = 0xF0, SCALE_IMM16 = 0xF1, SCALE_IMM32 = 0xF2, SCALE_IMM64 = 0xF3, @@ -114,7 +183,7 @@ enum NormalOp { nrmSUB, nrmSBB, nrmAND, - nrmOR , + nrmOR, nrmXOR, nrmMOV, nrmTEST, @@ -157,68 +226,73 @@ enum FloatRound { class XEmitter; // RIP addressing does not benefit from micro op fusion on Core arch -struct OpArg -{ +struct OpArg { friend class XEmitter; - constexpr OpArg() = default; // dummy op arg, used for storage + constexpr OpArg() = default; // dummy op arg, used for storage constexpr OpArg(u64 offset_, int scale_, X64Reg rmReg = RAX, X64Reg scaledReg = RAX) - : scale(static_cast<u8>(scale_)) - , offsetOrBaseReg(static_cast<u16>(rmReg)) - , indexReg(static_cast<u16>(scaledReg)) - , offset(offset_) - { - } + : scale(static_cast<u8>(scale_)), offsetOrBaseReg(static_cast<u16>(rmReg)), + indexReg(static_cast<u16>(scaledReg)), offset(offset_) {} - constexpr bool operator==(const OpArg &b) const - { - return operandReg == b.operandReg && - scale == b.scale && - offsetOrBaseReg == b.offsetOrBaseReg && - indexReg == b.indexReg && - offset == b.offset; + constexpr bool operator==(const OpArg& b) const { + return operandReg == b.operandReg && scale == b.scale && + offsetOrBaseReg == b.offsetOrBaseReg && indexReg == b.indexReg && offset == b.offset; } - void WriteRex(XEmitter *emit, int opBits, int bits, int customOp = -1) const; - void WriteVex(XEmitter* emit, X64Reg regOp1, X64Reg regOp2, int L, int pp, int mmmmm, int W = 0) const; - void WriteRest(XEmitter *emit, int extraBytes=0, X64Reg operandReg=INVALID_REG, bool warn_64bit_offset = true) const; - void WriteSingleByteOp(XEmitter *emit, u8 op, X64Reg operandReg, int bits); - void WriteNormalOp(XEmitter *emit, bool toRM, NormalOp op, const OpArg &operand, int bits) const; - - constexpr bool IsImm() const { return scale == SCALE_IMM8 || scale == SCALE_IMM16 || scale == SCALE_IMM32 || scale == SCALE_IMM64; } - constexpr bool IsSimpleReg() const { return scale == SCALE_NONE; } - constexpr bool IsSimpleReg(X64Reg reg) const - { + void WriteRex(XEmitter* emit, int opBits, int bits, int customOp = -1) const; + void WriteVex(XEmitter* emit, X64Reg regOp1, X64Reg regOp2, int L, int pp, int mmmmm, + int W = 0) const; + void WriteRest(XEmitter* emit, int extraBytes = 0, X64Reg operandReg = INVALID_REG, + bool warn_64bit_offset = true) const; + void WriteSingleByteOp(XEmitter* emit, u8 op, X64Reg operandReg, int bits); + void WriteNormalOp(XEmitter* emit, bool toRM, NormalOp op, const OpArg& operand, + int bits) const; + + constexpr bool IsImm() const { + return scale == SCALE_IMM8 || scale == SCALE_IMM16 || scale == SCALE_IMM32 || + scale == SCALE_IMM64; + } + constexpr bool IsSimpleReg() const { + return scale == SCALE_NONE; + } + constexpr bool IsSimpleReg(X64Reg reg) const { return IsSimpleReg() && GetSimpleReg() == reg; } - int GetImmBits() const - { - switch (scale) - { - case SCALE_IMM8: return 8; - case SCALE_IMM16: return 16; - case SCALE_IMM32: return 32; - case SCALE_IMM64: return 64; - default: return -1; + int GetImmBits() const { + switch (scale) { + case SCALE_IMM8: + return 8; + case SCALE_IMM16: + return 16; + case SCALE_IMM32: + return 32; + case SCALE_IMM64: + return 64; + default: + return -1; } } void SetImmBits(int bits) { - switch (bits) - { - case 8: scale = SCALE_IMM8; break; - case 16: scale = SCALE_IMM16; break; - case 32: scale = SCALE_IMM32; break; - case 64: scale = SCALE_IMM64; break; + switch (bits) { + case 8: + scale = SCALE_IMM8; + break; + case 16: + scale = SCALE_IMM16; + break; + case 32: + scale = SCALE_IMM32; + break; + case 64: + scale = SCALE_IMM64; + break; } } - constexpr X64Reg GetSimpleReg() const - { - return scale == SCALE_NONE - ? static_cast<X64Reg>(offsetOrBaseReg) - : INVALID_REG; + constexpr X64Reg GetSimpleReg() const { + return scale == SCALE_NONE ? static_cast<X64Reg>(offsetOrBaseReg) : INVALID_REG; } constexpr u32 GetImmValue() const { @@ -234,41 +308,50 @@ private: u8 scale = 0; u16 offsetOrBaseReg = 0; u16 indexReg = 0; - u64 offset = 0; // use RIP-relative as much as possible - 64-bit immediates are not available. + u64 offset = 0; // use RIP-relative as much as possible - 64-bit immediates are not available. u16 operandReg = 0; }; template <typename T> -inline OpArg M(const T *ptr) { return OpArg(reinterpret_cast<u64>(ptr), static_cast<int>(SCALE_RIP)); } -constexpr OpArg R(X64Reg value) { return OpArg(0, SCALE_NONE, value); } -constexpr OpArg MatR(X64Reg value) { return OpArg(0, SCALE_ATREG, value); } +inline OpArg M(const T* ptr) { + return OpArg(reinterpret_cast<u64>(ptr), static_cast<int>(SCALE_RIP)); +} +constexpr OpArg R(X64Reg value) { + return OpArg(0, SCALE_NONE, value); +} +constexpr OpArg MatR(X64Reg value) { + return OpArg(0, SCALE_ATREG, value); +} -constexpr OpArg MDisp(X64Reg value, int offset) -{ +constexpr OpArg MDisp(X64Reg value, int offset) { return OpArg(static_cast<u32>(offset), SCALE_ATREG, value); } -constexpr OpArg MComplex(X64Reg base, X64Reg scaled, int scale, int offset) -{ +constexpr OpArg MComplex(X64Reg base, X64Reg scaled, int scale, int offset) { return OpArg(offset, scale, base, scaled); } -constexpr OpArg MScaled(X64Reg scaled, int scale, int offset) -{ - return scale == SCALE_1 - ? OpArg(offset, SCALE_ATREG, scaled) - : OpArg(offset, scale | 0x20, RAX, scaled); +constexpr OpArg MScaled(X64Reg scaled, int scale, int offset) { + return scale == SCALE_1 ? OpArg(offset, SCALE_ATREG, scaled) + : OpArg(offset, scale | 0x20, RAX, scaled); } -constexpr OpArg MRegSum(X64Reg base, X64Reg offset) -{ +constexpr OpArg MRegSum(X64Reg base, X64Reg offset) { return MComplex(base, offset, 1, 0); } -constexpr OpArg Imm8 (u8 imm) { return OpArg(imm, SCALE_IMM8); } -constexpr OpArg Imm16(u16 imm) { return OpArg(imm, SCALE_IMM16); } //rarely used -constexpr OpArg Imm32(u32 imm) { return OpArg(imm, SCALE_IMM32); } -constexpr OpArg Imm64(u64 imm) { return OpArg(imm, SCALE_IMM64); } +constexpr OpArg Imm8(u8 imm) { + return OpArg(imm, SCALE_IMM8); +} +constexpr OpArg Imm16(u16 imm) { + return OpArg(imm, SCALE_IMM16); +} // rarely used +constexpr OpArg Imm32(u32 imm) { + return OpArg(imm, SCALE_IMM32); +} +constexpr OpArg Imm64(u64 imm) { + return OpArg(imm, SCALE_IMM64); +} constexpr OpArg UImmAuto(u32 imm) { return OpArg(imm, imm >= 128 ? SCALE_IMM32 : SCALE_IMM8); } @@ -277,8 +360,7 @@ constexpr OpArg SImmAuto(s32 imm) { } template <typename T> -OpArg ImmPtr(const T* imm) -{ +OpArg ImmPtr(const T* imm) { #ifdef _ARCH_64 return Imm64(reinterpret_cast<u64>(imm)); #else @@ -286,36 +368,31 @@ OpArg ImmPtr(const T* imm) #endif } -inline u32 PtrOffset(const void* ptr, const void* base) -{ +inline u32 PtrOffset(const void* ptr, const void* base) { #ifdef _ARCH_64 - s64 distance = (s64)ptr-(s64)base; - if (distance >= 0x80000000LL || - distance < -0x80000000LL) - { + s64 distance = (s64)ptr - (s64)base; + if (distance >= 0x80000000LL || distance < -0x80000000LL) { ASSERT_MSG(0, "pointer offset out of range"); return 0; } return (u32)distance; #else - return (u32)ptr-(u32)base; + return (u32)ptr - (u32)base; #endif } -//usage: int a[]; ARRAY_OFFSET(a,10) -#define ARRAY_OFFSET(array,index) ((u32)((u64)&(array)[index]-(u64)&(array)[0])) -//usage: struct {int e;} s; STRUCT_OFFSET(s,e) -#define STRUCT_OFFSET(str,elem) ((u32)((u64)&(str).elem-(u64)&(str))) +// usage: int a[]; ARRAY_OFFSET(a,10) +#define ARRAY_OFFSET(array, index) ((u32)((u64) & (array)[index] - (u64) & (array)[0])) +// usage: struct {int e;} s; STRUCT_OFFSET(s,e) +#define STRUCT_OFFSET(str, elem) ((u32)((u64) & (str).elem - (u64) & (str))) -struct FixupBranch -{ - u8 *ptr; - int type; //0 = 8bit 1 = 32bit +struct FixupBranch { + u8* ptr; + int type; // 0 = 8bit 1 = 32bit }; -enum SSECompare -{ +enum SSECompare { EQ = 0, LT, LE, @@ -326,11 +403,10 @@ enum SSECompare ORD, }; -class XEmitter -{ - friend struct OpArg; // for Write8 etc +class XEmitter { + friend struct OpArg; // for Write8 etc private: - u8 *code; + u8* code; bool flags_locked; void CheckFlags(); @@ -347,14 +423,19 @@ private: void WriteSSSE3Op(u8 opPrefix, u16 op, X64Reg regOp, const OpArg& arg, int extrabytes = 0); void WriteSSE41Op(u8 opPrefix, u16 op, X64Reg regOp, const OpArg& arg, int extrabytes = 0); void WriteAVXOp(u8 opPrefix, u16 op, X64Reg regOp, const OpArg& arg, int extrabytes = 0); - void WriteAVXOp(u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, const OpArg& arg, int extrabytes = 0); - void WriteVEXOp(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, const OpArg& arg, int extrabytes = 0); - void WriteBMI1Op(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, const OpArg& arg, int extrabytes = 0); - void WriteBMI2Op(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, const OpArg& arg, int extrabytes = 0); + void WriteAVXOp(u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, const OpArg& arg, + int extrabytes = 0); + void WriteVEXOp(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, const OpArg& arg, + int extrabytes = 0); + void WriteBMI1Op(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, const OpArg& arg, + int extrabytes = 0); + void WriteBMI2Op(int size, u8 opPrefix, u16 op, X64Reg regOp1, X64Reg regOp2, const OpArg& arg, + int extrabytes = 0); void WriteFloatLoadStore(int bits, FloatOp op, FloatOp op_80b, const OpArg& arg); - void WriteNormalOp(XEmitter *emit, int bits, NormalOp op, const OpArg& a1, const OpArg& a2); + void WriteNormalOp(XEmitter* emit, int bits, NormalOp op, const OpArg& a1, const OpArg& a2); - void ABI_CalculateFrameSize(BitSet32 mask, size_t rsp_alignment, size_t needed_frame_size, size_t* shadowp, size_t* subtractionp, size_t* xmm_offsetp); + void ABI_CalculateFrameSize(BitSet32 mask, size_t rsp_alignment, size_t needed_frame_size, + size_t* shadowp, size_t* subtractionp, size_t* xmm_offsetp); protected: void Write8(u8 value); @@ -363,26 +444,37 @@ protected: void Write64(u64 value); public: - XEmitter() { code = nullptr; flags_locked = false; } - XEmitter(u8 *code_ptr) { code = code_ptr; flags_locked = false; } + XEmitter() { + code = nullptr; + flags_locked = false; + } + XEmitter(u8* code_ptr) { + code = code_ptr; + flags_locked = false; + } virtual ~XEmitter() {} void WriteModRM(int mod, int rm, int reg); void WriteSIB(int scale, int index, int base); - void SetCodePtr(u8 *ptr); + void SetCodePtr(u8* ptr); void ReserveCodeSpace(int bytes); - const u8 *AlignCode4(); - const u8 *AlignCode16(); - const u8 *AlignCodePage(); - const u8 *GetCodePtr() const; - u8 *GetWritableCodePtr(); - - void LockFlags() { flags_locked = true; } - void UnlockFlags() { flags_locked = false; } + const u8* AlignCode4(); + const u8* AlignCode16(); + const u8* AlignCodePage(); + const u8* GetCodePtr() const; + u8* GetWritableCodePtr(); + + void LockFlags() { + flags_locked = true; + } + void UnlockFlags() { + flags_locked = false; + } // Looking for one of these? It's BANNED!! Some instructions are slow on modern CPU - // INC, DEC, LOOP, LOOPNE, LOOPE, ENTER, LEAVE, XCHG, XLAT, REP MOVSB/MOVSD, REP SCASD + other string instr., + // INC, DEC, LOOP, LOOPNE, LOOPE, ENTER, LEAVE, XCHG, XLAT, REP MOVSB/MOVSD, REP SCASD + other + // string instr., // INC and DEC are slow on Intel Core, but not on AMD. They create a // false flag dependency because they only update a subset of the flags. // XCHG is SLOW and should be avoided. @@ -401,11 +493,11 @@ public: void CLC(); void CMC(); - // These two can not be executed in 64-bit mode on early Intel 64-bit CPU:s, only on Core2 and AMD! + // These two can not be executed in 64-bit mode on early Intel 64-bit CPU:s, only on Core2 and + // AMD! void LAHF(); // 3 cycle vector path void SAHF(); // direct path fast - // Stack control void PUSH(X64Reg reg); void POP(X64Reg reg); @@ -422,7 +514,7 @@ public: void JMP(const u8* addr, bool force5Bytes = false); void JMPptr(const OpArg& arg); - void JMPself(); //infinite loop! + void JMPself(); // infinite loop! #ifdef CALL #undef CALL #endif @@ -450,12 +542,11 @@ public: void BSR(int bits, X64Reg dest, const OpArg& src); // Top bit to bottom bit // Cache control - enum PrefetchLevel - { - PF_NTA, //Non-temporal (data used once and only once) - PF_T0, //All cache levels - PF_T1, //Levels 2+ (aliased to T0 on AMD) - PF_T2, //Levels 3+ (aliased to T0 on AMD) + enum PrefetchLevel { + PF_NTA, // Non-temporal (data used once and only once) + PF_T0, // All cache levels + PF_T1, // Levels 2+ (aliased to T0 on AMD) + PF_T2, // Levels 3+ (aliased to T0 on AMD) }; void PREFETCH(PrefetchLevel level, OpArg arg); void MOVNTI(int bits, const OpArg& dest, X64Reg src); @@ -464,8 +555,8 @@ public: void MOVNTPD(const OpArg& arg, X64Reg regOp); // Multiplication / division - void MUL(int bits, const OpArg& src); //UNSIGNED - void IMUL(int bits, const OpArg& src); //SIGNED + void MUL(int bits, const OpArg& src); // UNSIGNED + void IMUL(int bits, const OpArg& src); // SIGNED void IMUL(int bits, X64Reg regOp, const OpArg& src); void IMUL(int bits, X64Reg regOp, const OpArg& src, const OpArg& imm); void DIV(int bits, const OpArg& src); @@ -492,11 +583,19 @@ public: // Extend EAX into EDX in various ways void CWD(int bits = 16); - void CDQ() {CWD(32);} - void CQO() {CWD(64);} + void CDQ() { + CWD(32); + } + void CQO() { + CWD(64); + } void CBW(int bits = 8); - void CWDE() {CBW(16);} - void CDQE() {CBW(32);} + void CWDE() { + CBW(16); + } + void CDQE() { + CBW(32); + } // Load effective address void LEA(int bits, X64Reg dest, OpArg src); @@ -511,7 +610,7 @@ public: void CMP(int bits, const OpArg& a1, const OpArg& a2); // Bit operations - void NOT (int bits, const OpArg& src); + void NOT(int bits, const OpArg& src); void OR(int bits, const OpArg& a1, const OpArg& a2); void XOR(int bits, const OpArg& a1, const OpArg& a2); void MOV(int bits, const OpArg& a1, const OpArg& a2); @@ -525,7 +624,8 @@ public: void BSWAP(int bits, X64Reg reg); // Sign/zero extension - void MOVSX(int dbits, int sbits, X64Reg dest, OpArg src); //automatically uses MOVSXD if necessary + void MOVSX(int dbits, int sbits, X64Reg dest, + OpArg src); // automatically uses MOVSXD if necessary void MOVZX(int dbits, int sbits, X64Reg dest, OpArg src); // Available only on Atom or >= Haswell so far. Test with GetCPUCaps().movbe. @@ -593,13 +693,27 @@ public: void CMPSS(X64Reg regOp, const OpArg& arg, u8 compare); void CMPSD(X64Reg regOp, const OpArg& arg, u8 compare); - void CMPEQSS(X64Reg regOp, const OpArg& arg) { CMPSS(regOp, arg, CMP_EQ); } - void CMPLTSS(X64Reg regOp, const OpArg& arg) { CMPSS(regOp, arg, CMP_LT); } - void CMPLESS(X64Reg regOp, const OpArg& arg) { CMPSS(regOp, arg, CMP_LE); } - void CMPUNORDSS(X64Reg regOp, const OpArg& arg) { CMPSS(regOp, arg, CMP_UNORD); } - void CMPNEQSS(X64Reg regOp, const OpArg& arg) { CMPSS(regOp, arg, CMP_NEQ); } - void CMPNLTSS(X64Reg regOp, const OpArg& arg) { CMPSS(regOp, arg, CMP_NLT); } - void CMPORDSS(X64Reg regOp, const OpArg& arg) { CMPSS(regOp, arg, CMP_ORD); } + void CMPEQSS(X64Reg regOp, const OpArg& arg) { + CMPSS(regOp, arg, CMP_EQ); + } + void CMPLTSS(X64Reg regOp, const OpArg& arg) { + CMPSS(regOp, arg, CMP_LT); + } + void CMPLESS(X64Reg regOp, const OpArg& arg) { + CMPSS(regOp, arg, CMP_LE); + } + void CMPUNORDSS(X64Reg regOp, const OpArg& arg) { + CMPSS(regOp, arg, CMP_UNORD); + } + void CMPNEQSS(X64Reg regOp, const OpArg& arg) { + CMPSS(regOp, arg, CMP_NEQ); + } + void CMPNLTSS(X64Reg regOp, const OpArg& arg) { + CMPSS(regOp, arg, CMP_NLT); + } + void CMPORDSS(X64Reg regOp, const OpArg& arg) { + CMPSS(regOp, arg, CMP_ORD); + } // SSE/SSE2: Floating point packed arithmetic (x4 for float, x2 for double) void ADDPS(X64Reg regOp, const OpArg& arg); @@ -638,10 +752,12 @@ public: // SSE/SSE2: Useful alternative to shuffle in some cases. void MOVDDUP(X64Reg regOp, const OpArg& arg); - // SSE3: Horizontal operations in SIMD registers. Very slow! shufps-based code beats it handily on Ivy. + // SSE3: Horizontal operations in SIMD registers. Very slow! shufps-based code beats it handily + // on Ivy. void HADDPS(X64Reg dest, const OpArg& src); - // SSE4: Further horizontal operations - dot products. These are weirdly flexible, the arg contains both a read mask and a write "mask". + // SSE4: Further horizontal operations - dot products. These are weirdly flexible, the arg + // contains both a read mask and a write "mask". void DPPS(X64Reg dest, const OpArg& src, u8 arg); void UNPCKLPS(X64Reg dest, const OpArg& src); @@ -694,11 +810,13 @@ public: void MOVD_xmm(const OpArg& arg, X64Reg src); void MOVQ_xmm(OpArg arg, X64Reg src); - // SSE/SSE2: Generates a mask from the high bits of the components of the packed register in question. + // SSE/SSE2: Generates a mask from the high bits of the components of the packed register in + // question. void MOVMSKPS(X64Reg dest, const OpArg& arg); void MOVMSKPD(X64Reg dest, const OpArg& arg); - // SSE2: Selective byte store, mask in src register. EDI/RDI specifies store address. This is a weird one. + // SSE2: Selective byte store, mask in src register. EDI/RDI specifies store address. This is a + // weird one. void MASKMOVDQU(X64Reg dest, X64Reg src); void LDDQU(X64Reg dest, const OpArg& src); @@ -729,10 +847,10 @@ public: void PACKUSDW(X64Reg dest, const OpArg& arg); void PACKUSWB(X64Reg dest, const OpArg& arg); - void PUNPCKLBW(X64Reg dest, const OpArg &arg); - void PUNPCKLWD(X64Reg dest, const OpArg &arg); - void PUNPCKLDQ(X64Reg dest, const OpArg &arg); - void PUNPCKLQDQ(X64Reg dest, const OpArg &arg); + void PUNPCKLBW(X64Reg dest, const OpArg& arg); + void PUNPCKLWD(X64Reg dest, const OpArg& arg); + void PUNPCKLDQ(X64Reg dest, const OpArg& arg); + void PUNPCKLQDQ(X64Reg dest, const OpArg& arg); void PTEST(X64Reg dest, const OpArg& arg); void PAND(X64Reg dest, const OpArg& arg); @@ -839,25 +957,57 @@ public: void ROUNDPS(X64Reg dest, const OpArg& arg, u8 mode); void ROUNDPD(X64Reg dest, const OpArg& arg, u8 mode); - void ROUNDNEARSS(X64Reg dest, const OpArg& arg) { ROUNDSS(dest, arg, FROUND_NEAREST); } - void ROUNDFLOORSS(X64Reg dest, const OpArg& arg) { ROUNDSS(dest, arg, FROUND_FLOOR); } - void ROUNDCEILSS(X64Reg dest, const OpArg& arg) { ROUNDSS(dest, arg, FROUND_CEIL); } - void ROUNDZEROSS(X64Reg dest, const OpArg& arg) { ROUNDSS(dest, arg, FROUND_ZERO); } + void ROUNDNEARSS(X64Reg dest, const OpArg& arg) { + ROUNDSS(dest, arg, FROUND_NEAREST); + } + void ROUNDFLOORSS(X64Reg dest, const OpArg& arg) { + ROUNDSS(dest, arg, FROUND_FLOOR); + } + void ROUNDCEILSS(X64Reg dest, const OpArg& arg) { + ROUNDSS(dest, arg, FROUND_CEIL); + } + void ROUNDZEROSS(X64Reg dest, const OpArg& arg) { + ROUNDSS(dest, arg, FROUND_ZERO); + } - void ROUNDNEARSD(X64Reg dest, const OpArg& arg) { ROUNDSD(dest, arg, FROUND_NEAREST); } - void ROUNDFLOORSD(X64Reg dest, const OpArg& arg) { ROUNDSD(dest, arg, FROUND_FLOOR); } - void ROUNDCEILSD(X64Reg dest, const OpArg& arg) { ROUNDSD(dest, arg, FROUND_CEIL); } - void ROUNDZEROSD(X64Reg dest, const OpArg& arg) { ROUNDSD(dest, arg, FROUND_ZERO); } + void ROUNDNEARSD(X64Reg dest, const OpArg& arg) { + ROUNDSD(dest, arg, FROUND_NEAREST); + } + void ROUNDFLOORSD(X64Reg dest, const OpArg& arg) { + ROUNDSD(dest, arg, FROUND_FLOOR); + } + void ROUNDCEILSD(X64Reg dest, const OpArg& arg) { + ROUNDSD(dest, arg, FROUND_CEIL); + } + void ROUNDZEROSD(X64Reg dest, const OpArg& arg) { + ROUNDSD(dest, arg, FROUND_ZERO); + } - void ROUNDNEARPS(X64Reg dest, const OpArg& arg) { ROUNDPS(dest, arg, FROUND_NEAREST); } - void ROUNDFLOORPS(X64Reg dest, const OpArg& arg) { ROUNDPS(dest, arg, FROUND_FLOOR); } - void ROUNDCEILPS(X64Reg dest, const OpArg& arg) { ROUNDPS(dest, arg, FROUND_CEIL); } - void ROUNDZEROPS(X64Reg dest, const OpArg& arg) { ROUNDPS(dest, arg, FROUND_ZERO); } + void ROUNDNEARPS(X64Reg dest, const OpArg& arg) { + ROUNDPS(dest, arg, FROUND_NEAREST); + } + void ROUNDFLOORPS(X64Reg dest, const OpArg& arg) { + ROUNDPS(dest, arg, FROUND_FLOOR); + } + void ROUNDCEILPS(X64Reg dest, const OpArg& arg) { + ROUNDPS(dest, arg, FROUND_CEIL); + } + void ROUNDZEROPS(X64Reg dest, const OpArg& arg) { + ROUNDPS(dest, arg, FROUND_ZERO); + } - void ROUNDNEARPD(X64Reg dest, const OpArg& arg) { ROUNDPD(dest, arg, FROUND_NEAREST); } - void ROUNDFLOORPD(X64Reg dest, const OpArg& arg) { ROUNDPD(dest, arg, FROUND_FLOOR); } - void ROUNDCEILPD(X64Reg dest, const OpArg& arg) { ROUNDPD(dest, arg, FROUND_CEIL); } - void ROUNDZEROPD(X64Reg dest, const OpArg& arg) { ROUNDPD(dest, arg, FROUND_ZERO); } + void ROUNDNEARPD(X64Reg dest, const OpArg& arg) { + ROUNDPD(dest, arg, FROUND_NEAREST); + } + void ROUNDFLOORPD(X64Reg dest, const OpArg& arg) { + ROUNDPD(dest, arg, FROUND_FLOOR); + } + void ROUNDCEILPD(X64Reg dest, const OpArg& arg) { + ROUNDPD(dest, arg, FROUND_CEIL); + } + void ROUNDZEROPD(X64Reg dest, const OpArg& arg) { + ROUNDPD(dest, arg, FROUND_ZERO); + } // AVX void VADDSD(X64Reg regOp1, X64Reg regOp2, const OpArg& arg); @@ -981,7 +1131,6 @@ public: void ABI_CallFunctionC16(const void* func, u16 param1); void ABI_CallFunctionCC16(const void* func, u32 param1, u16 param2); - // These only support u32 parameters, but that's enough for a lot of uses. // These will destroy the 1 or 2 first "parameter regs". void ABI_CallFunctionC(const void* func, u32 param1); @@ -1012,29 +1161,38 @@ public: * * @param mask Registers to push on the stack (high 16 bits are XMMs, low 16 bits are GPRs) * @param rsp_alignment Current alignment of the stack pointer, must be 0 or 8 - * @param needed_frame_size Additional space needed, e.g., for function arguments passed on the stack + * @param needed_frame_size Additional space needed, e.g., for function arguments passed on the + * stack * @return Size of the shadow space, i.e., offset of the frame */ - size_t ABI_PushRegistersAndAdjustStack(BitSet32 mask, size_t rsp_alignment, size_t needed_frame_size = 0); + size_t ABI_PushRegistersAndAdjustStack(BitSet32 mask, size_t rsp_alignment, + size_t needed_frame_size = 0); /** - * Restores specified registers and adjusts the stack to its original alignment, i.e., the alignment before + * Restores specified registers and adjusts the stack to its original alignment, i.e., the + * alignment before * the matching PushRegistersAndAdjustStack. * - * @param mask Registers to restores from the stack (high 16 bits are XMMs, low 16 bits are GPRs) - * @param rsp_alignment Original alignment before the matching PushRegistersAndAdjustStack, must be 0 or 8 + * @param mask Registers to restores from the stack (high 16 bits are XMMs, low 16 bits are + * GPRs) + * @param rsp_alignment Original alignment before the matching PushRegistersAndAdjustStack, must + * be 0 or 8 * @param needed_frame_size Additional space that was needed * @warning Stack must be currently 16-byte aligned */ - void ABI_PopRegistersAndAdjustStack(BitSet32 mask, size_t rsp_alignment, size_t needed_frame_size = 0); - - #ifdef _M_IX86 - static int ABI_GetNumXMMRegs() { return 8; } - #else - static int ABI_GetNumXMMRegs() { return 16; } - #endif -}; // class XEmitter + void ABI_PopRegistersAndAdjustStack(BitSet32 mask, size_t rsp_alignment, + size_t needed_frame_size = 0); +#ifdef _M_IX86 + static int ABI_GetNumXMMRegs() { + return 8; + } +#else + static int ABI_GetNumXMMRegs() { + return 16; + } +#endif +}; // class XEmitter // Everything that needs to generate X86 code should inherit from this. // You get memory management for free, plus, you can use all the MOV etc functions without @@ -1045,4 +1203,4 @@ public: void PoisonMemory() override; }; -} // namespace +} // namespace diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 480c90e66..e466b21b2 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -9,14 +9,13 @@ #include "core/arm/skyeye_common/vfp/asm_vfp.h" namespace Core { - struct ThreadContext; +struct ThreadContext; } /// Generic ARM11 CPU interface class ARM_Interface : NonCopyable { public: - virtual ~ARM_Interface() { - } + virtual ~ARM_Interface() {} /** * Runs the CPU for the given number of instructions @@ -141,10 +140,10 @@ public: return num_instructions; } - s64 down_count = 0; ///< A decreasing counter of remaining cycles before the next event, decreased by the cpu run loop + s64 down_count = 0; ///< A decreasing counter of remaining cycles before the next event, + /// decreased by the cpu run loop protected: - /** * Executes the given number of instructions * @param num_instructions Number of instructions to executes @@ -152,6 +151,5 @@ protected: virtual void ExecuteInstructions(int num_instructions) = 0; private: - u64 num_instructions = 0; ///< Number of instructions executed }; diff --git a/src/core/arm/disassembler/arm_disasm.cpp b/src/core/arm/disassembler/arm_disasm.cpp index 5ad1f1c29..05d6ed1fb 100644 --- a/src/core/arm/disassembler/arm_disasm.cpp +++ b/src/core/arm/disassembler/arm_disasm.cpp @@ -2,408 +2,230 @@ #include <string> #include <unordered_set> - #include "common/common_types.h" #include "common/string_util.h" - #include "core/arm/disassembler/arm_disasm.h" #include "core/arm/skyeye_common/armsupp.h" -static const char *cond_names[] = { - "eq", - "ne", - "cs", - "cc", - "mi", - "pl", - "vs", - "vc", - "hi", - "ls", - "ge", - "lt", - "gt", - "le", - "", - "RESERVED" -}; - -static const char *opcode_names[] = { - "invalid", - "undefined", - "adc", - "add", - "and", - "b", - "bl", - "bic", - "bkpt", - "blx", - "bx", - "cdp", - "clrex", - "clz", - "cmn", - "cmp", - "eor", - "ldc", - "ldm", - "ldr", - "ldrb", - "ldrbt", - "ldrex", - "ldrexb", - "ldrexd", - "ldrexh", - "ldrh", - "ldrsb", - "ldrsh", - "ldrt", - "mcr", - "mla", - "mov", - "mrc", - "mrs", - "msr", - "mul", - "mvn", - "nop", - "orr", - "pkh", - "pld", - "qadd16", - "qadd8", - "qasx", - "qsax", - "qsub16", - "qsub8", - "rev", - "rev16", - "revsh", - "rsb", - "rsc", - "sadd16", - "sadd8", - "sasx", - "sbc", - "sel", - "sev", - "shadd16", - "shadd8", - "shasx", - "shsax", - "shsub16", - "shsub8", - "smlad", - "smlal", - "smlald", - "smlsd", - "smlsld", - "smmla", - "smmls", - "smmul", - "smuad", - "smull", - "smusd", - "ssat", - "ssat16", - "ssax", - "ssub16", - "ssub8", - "stc", - "stm", - "str", - "strb", - "strbt", - "strex", - "strexb", - "strexd", - "strexh", - "strh", - "strt", - "sub", - "swi", - "swp", - "swpb", - "sxtab", - "sxtab16", - "sxtah", - "sxtb", - "sxtb16", - "sxth", - "teq", - "tst", - "uadd16", - "uadd8", - "uasx", - "uhadd16", - "uhadd8", - "uhasx", - "uhsax", - "uhsub16", - "uhsub8", - "umlal", - "umull", - "uqadd16", - "uqadd8", - "uqasx", - "uqsax", - "uqsub16", - "uqsub8", - "usad8", - "usada8", - "usat", - "usat16", - "usax", - "usub16", - "usub8", - "uxtab", - "uxtab16", - "uxtah", - "uxtb", - "uxtb16", - "uxth", - "wfe", - "wfi", +static const char* cond_names[] = {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", + "hi", "ls", "ge", "lt", "gt", "le", "", "RESERVED"}; + +static const char* opcode_names[] = { + "invalid", "undefined", "adc", "add", "and", "b", "bl", "bic", + "bkpt", "blx", "bx", "cdp", "clrex", "clz", "cmn", "cmp", + "eor", "ldc", "ldm", "ldr", "ldrb", "ldrbt", "ldrex", "ldrexb", + "ldrexd", "ldrexh", "ldrh", "ldrsb", "ldrsh", "ldrt", "mcr", "mla", + "mov", "mrc", "mrs", "msr", "mul", "mvn", "nop", "orr", + "pkh", "pld", "qadd16", "qadd8", "qasx", "qsax", "qsub16", "qsub8", + "rev", "rev16", "revsh", "rsb", "rsc", "sadd16", "sadd8", "sasx", + "sbc", "sel", "sev", "shadd16", "shadd8", "shasx", "shsax", "shsub16", + "shsub8", "smlad", "smlal", "smlald", "smlsd", "smlsld", "smmla", "smmls", + "smmul", "smuad", "smull", "smusd", "ssat", "ssat16", "ssax", "ssub16", + "ssub8", "stc", "stm", "str", "strb", "strbt", "strex", "strexb", + "strexd", "strexh", "strh", "strt", "sub", "swi", "swp", "swpb", + "sxtab", "sxtab16", "sxtah", "sxtb", "sxtb16", "sxth", "teq", "tst", + "uadd16", "uadd8", "uasx", "uhadd16", "uhadd8", "uhasx", "uhsax", "uhsub16", + "uhsub8", "umlal", "umull", "uqadd16", "uqadd8", "uqasx", "uqsax", "uqsub16", + "uqsub8", "usad8", "usada8", "usat", "usat16", "usax", "usub16", "usub8", + "uxtab", "uxtab16", "uxtah", "uxtb", "uxtb16", "uxth", "wfe", "wfi", "yield", - "undefined", - "adc", - "add", - "and", - "asr", - "b", - "bic", - "bkpt", - "bl", - "blx", - "bx", - "cmn", - "cmp", - "eor", - "ldmia", - "ldr", - "ldrb", - "ldrh", - "ldrsb", - "ldrsh", - "lsl", - "lsr", - "mov", - "mul", - "mvn", - "neg", - "orr", - "pop", - "push", - "ror", - "sbc", - "stmia", - "str", - "strb", - "strh", - "sub", - "swi", - "tst", - - nullptr -}; + "undefined", "adc", "add", "and", "asr", "b", "bic", "bkpt", + "bl", "blx", "bx", "cmn", "cmp", "eor", "ldmia", "ldr", + "ldrb", "ldrh", "ldrsb", "ldrsh", "lsl", "lsr", "mov", "mul", + "mvn", "neg", "orr", "pop", "push", "ror", "sbc", "stmia", + "str", "strb", "strh", "sub", "swi", "tst", + + nullptr}; // Indexed by the shift type (bits 6-5) -static const char *shift_names[] = { - "LSL", - "LSR", - "ASR", - "ROR" -}; +static const char* shift_names[] = {"LSL", "LSR", "ASR", "ROR"}; static const char* cond_to_str(u32 cond) { return cond_names[cond]; } -std::string ARM_Disasm::Disassemble(u32 addr, u32 insn) -{ +std::string ARM_Disasm::Disassemble(u32 addr, u32 insn) { Opcode opcode = Decode(insn); switch (opcode) { - case OP_INVALID: - return "Invalid"; - case OP_UNDEFINED: - return "Undefined"; - case OP_ADC: - case OP_ADD: - case OP_AND: - case OP_BIC: - case OP_CMN: - case OP_CMP: - case OP_EOR: - case OP_MOV: - case OP_MVN: - case OP_ORR: - case OP_RSB: - case OP_RSC: - case OP_SBC: - case OP_SUB: - case OP_TEQ: - case OP_TST: - return DisassembleALU(opcode, insn); - case OP_B: - case OP_BL: - return DisassembleBranch(addr, opcode, insn); - case OP_BKPT: - return DisassembleBKPT(insn); - case OP_BLX: - // not supported yet - break; - case OP_BX: - return DisassembleBX(insn); - case OP_CDP: - return "cdp"; - case OP_CLREX: - return "clrex"; - case OP_CLZ: - return DisassembleCLZ(insn); - case OP_LDC: - return "ldc"; - case OP_LDM: - case OP_STM: - return DisassembleMemblock(opcode, insn); - case OP_LDR: - case OP_LDRB: - case OP_LDRBT: - case OP_LDRT: - case OP_STR: - case OP_STRB: - case OP_STRBT: - case OP_STRT: - return DisassembleMem(insn); - case OP_LDREX: - case OP_LDREXB: - case OP_LDREXD: - case OP_LDREXH: - case OP_STREX: - case OP_STREXB: - case OP_STREXD: - case OP_STREXH: - return DisassembleREX(opcode, insn); - case OP_LDRH: - case OP_LDRSB: - case OP_LDRSH: - case OP_STRH: - return DisassembleMemHalf(insn); - case OP_MCR: - case OP_MRC: - return DisassembleMCR(opcode, insn); - case OP_MLA: - return DisassembleMLA(opcode, insn); - case OP_MRS: - return DisassembleMRS(insn); - case OP_MSR: - return DisassembleMSR(insn); - case OP_MUL: - return DisassembleMUL(opcode, insn); - case OP_NOP: - case OP_SEV: - case OP_WFE: - case OP_WFI: - case OP_YIELD: - return DisassembleNoOperands(opcode, insn); - case OP_PKH: - return DisassemblePKH(insn); - case OP_PLD: - return DisassemblePLD(insn); - case OP_QADD16: - case OP_QADD8: - case OP_QASX: - case OP_QSAX: - case OP_QSUB16: - case OP_QSUB8: - case OP_SADD16: - case OP_SADD8: - case OP_SASX: - case OP_SHADD16: - case OP_SHADD8: - case OP_SHASX: - case OP_SHSAX: - case OP_SHSUB16: - case OP_SHSUB8: - case OP_SSAX: - case OP_SSUB16: - case OP_SSUB8: - case OP_UADD16: - case OP_UADD8: - case OP_UASX: - case OP_UHADD16: - case OP_UHADD8: - case OP_UHASX: - case OP_UHSAX: - case OP_UHSUB16: - case OP_UHSUB8: - case OP_UQADD16: - case OP_UQADD8: - case OP_UQASX: - case OP_UQSAX: - case OP_UQSUB16: - case OP_UQSUB8: - case OP_USAX: - case OP_USUB16: - case OP_USUB8: - return DisassembleParallelAddSub(opcode, insn); - case OP_REV: - case OP_REV16: - case OP_REVSH: - return DisassembleREV(opcode, insn); - case OP_SEL: - return DisassembleSEL(insn); - case OP_SMLAD: - case OP_SMLALD: - case OP_SMLSD: - case OP_SMLSLD: - case OP_SMMLA: - case OP_SMMLS: - case OP_SMMUL: - case OP_SMUAD: - case OP_SMUSD: - case OP_USAD8: - case OP_USADA8: - return DisassembleMediaMulDiv(opcode, insn); - case OP_SSAT: - case OP_SSAT16: - case OP_USAT: - case OP_USAT16: - return DisassembleSAT(opcode, insn); - case OP_STC: - return "stc"; - case OP_SWI: - return DisassembleSWI(insn); - case OP_SWP: - case OP_SWPB: - return DisassembleSWP(opcode, insn); - case OP_SXTAB: - case OP_SXTAB16: - case OP_SXTAH: - case OP_SXTB: - case OP_SXTB16: - case OP_SXTH: - case OP_UXTAB: - case OP_UXTAB16: - case OP_UXTAH: - case OP_UXTB: - case OP_UXTB16: - case OP_UXTH: - return DisassembleXT(opcode, insn); - case OP_UMLAL: - case OP_UMULL: - case OP_SMLAL: - case OP_SMULL: - return DisassembleUMLAL(opcode, insn); - default: - return "Error"; + case OP_INVALID: + return "Invalid"; + case OP_UNDEFINED: + return "Undefined"; + case OP_ADC: + case OP_ADD: + case OP_AND: + case OP_BIC: + case OP_CMN: + case OP_CMP: + case OP_EOR: + case OP_MOV: + case OP_MVN: + case OP_ORR: + case OP_RSB: + case OP_RSC: + case OP_SBC: + case OP_SUB: + case OP_TEQ: + case OP_TST: + return DisassembleALU(opcode, insn); + case OP_B: + case OP_BL: + return DisassembleBranch(addr, opcode, insn); + case OP_BKPT: + return DisassembleBKPT(insn); + case OP_BLX: + // not supported yet + break; + case OP_BX: + return DisassembleBX(insn); + case OP_CDP: + return "cdp"; + case OP_CLREX: + return "clrex"; + case OP_CLZ: + return DisassembleCLZ(insn); + case OP_LDC: + return "ldc"; + case OP_LDM: + case OP_STM: + return DisassembleMemblock(opcode, insn); + case OP_LDR: + case OP_LDRB: + case OP_LDRBT: + case OP_LDRT: + case OP_STR: + case OP_STRB: + case OP_STRBT: + case OP_STRT: + return DisassembleMem(insn); + case OP_LDREX: + case OP_LDREXB: + case OP_LDREXD: + case OP_LDREXH: + case OP_STREX: + case OP_STREXB: + case OP_STREXD: + case OP_STREXH: + return DisassembleREX(opcode, insn); + case OP_LDRH: + case OP_LDRSB: + case OP_LDRSH: + case OP_STRH: + return DisassembleMemHalf(insn); + case OP_MCR: + case OP_MRC: + return DisassembleMCR(opcode, insn); + case OP_MLA: + return DisassembleMLA(opcode, insn); + case OP_MRS: + return DisassembleMRS(insn); + case OP_MSR: + return DisassembleMSR(insn); + case OP_MUL: + return DisassembleMUL(opcode, insn); + case OP_NOP: + case OP_SEV: + case OP_WFE: + case OP_WFI: + case OP_YIELD: + return DisassembleNoOperands(opcode, insn); + case OP_PKH: + return DisassemblePKH(insn); + case OP_PLD: + return DisassemblePLD(insn); + case OP_QADD16: + case OP_QADD8: + case OP_QASX: + case OP_QSAX: + case OP_QSUB16: + case OP_QSUB8: + case OP_SADD16: + case OP_SADD8: + case OP_SASX: + case OP_SHADD16: + case OP_SHADD8: + case OP_SHASX: + case OP_SHSAX: + case OP_SHSUB16: + case OP_SHSUB8: + case OP_SSAX: + case OP_SSUB16: + case OP_SSUB8: + case OP_UADD16: + case OP_UADD8: + case OP_UASX: + case OP_UHADD16: + case OP_UHADD8: + case OP_UHASX: + case OP_UHSAX: + case OP_UHSUB16: + case OP_UHSUB8: + case OP_UQADD16: + case OP_UQADD8: + case OP_UQASX: + case OP_UQSAX: + case OP_UQSUB16: + case OP_UQSUB8: + case OP_USAX: + case OP_USUB16: + case OP_USUB8: + return DisassembleParallelAddSub(opcode, insn); + case OP_REV: + case OP_REV16: + case OP_REVSH: + return DisassembleREV(opcode, insn); + case OP_SEL: + return DisassembleSEL(insn); + case OP_SMLAD: + case OP_SMLALD: + case OP_SMLSD: + case OP_SMLSLD: + case OP_SMMLA: + case OP_SMMLS: + case OP_SMMUL: + case OP_SMUAD: + case OP_SMUSD: + case OP_USAD8: + case OP_USADA8: + return DisassembleMediaMulDiv(opcode, insn); + case OP_SSAT: + case OP_SSAT16: + case OP_USAT: + case OP_USAT16: + return DisassembleSAT(opcode, insn); + case OP_STC: + return "stc"; + case OP_SWI: + return DisassembleSWI(insn); + case OP_SWP: + case OP_SWPB: + return DisassembleSWP(opcode, insn); + case OP_SXTAB: + case OP_SXTAB16: + case OP_SXTAH: + case OP_SXTB: + case OP_SXTB16: + case OP_SXTH: + case OP_UXTAB: + case OP_UXTAB16: + case OP_UXTAH: + case OP_UXTB: + case OP_UXTB16: + case OP_UXTH: + return DisassembleXT(opcode, insn); + case OP_UMLAL: + case OP_UMULL: + case OP_SMLAL: + case OP_SMULL: + return DisassembleUMLAL(opcode, insn); + default: + return "Error"; } return nullptr; } -std::string ARM_Disasm::DisassembleALU(Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleALU(Opcode opcode, u32 insn) { static const u8 kNoOperand1 = 1; static const u8 kNoDest = 2; static const u8 kNoSbit = 4; @@ -421,18 +243,18 @@ std::string ARM_Disasm::DisassembleALU(Opcode opcode, u32 insn) const char* opname = opcode_names[opcode]; switch (opcode) { - case OP_CMN: - case OP_CMP: - case OP_TEQ: - case OP_TST: - flags = kNoDest | kNoSbit; - break; - case OP_MOV: - case OP_MVN: - flags = kNoOperand1; - break; - default: - break; + case OP_CMN: + case OP_CMP: + case OP_TEQ: + case OP_TST: + flags = kNoDest | kNoSbit; + break; + case OP_MOV: + case OP_MVN: + flags = kNoOperand1; + break; + default: + break; } // The "mov" instruction ignores the first operand (rn). @@ -448,13 +270,13 @@ std::string ARM_Disasm::DisassembleALU(Opcode opcode, u32 insn) rd_str = Common::StringFromFormat("r%d, ", rd); } - const char *sbit_str = ""; + const char* sbit_str = ""; if (bit_s && !(flags & kNoSbit)) sbit_str = "s"; if (is_immed) { - return Common::StringFromFormat("%s%s%s\t%s%s#%u ; 0x%x", - opname, cond_to_str(cond), sbit_str, rd_str.c_str(), rn_str.c_str(), immed, immed); + return Common::StringFromFormat("%s%s%s\t%s%s#%u ; 0x%x", opname, cond_to_str(cond), + sbit_str, rd_str.c_str(), rn_str.c_str(), immed, immed); } u8 shift_is_reg = (insn >> 4) & 1; @@ -468,30 +290,28 @@ std::string ARM_Disasm::DisassembleALU(Opcode opcode, u32 insn) rotated_val = (rotated_val >> rotate2) | (rotated_val << (32 - rotate2)); if (!shift_is_reg && shift_type == 0 && shift_amount == 0) { - return Common::StringFromFormat("%s%s%s\t%s%sr%d", - opname, cond_to_str(cond), sbit_str, rd_str.c_str(), rn_str.c_str(), rm); + return Common::StringFromFormat("%s%s%s\t%s%sr%d", opname, cond_to_str(cond), sbit_str, + rd_str.c_str(), rn_str.c_str(), rm); } - const char *shift_name = shift_names[shift_type]; + const char* shift_name = shift_names[shift_type]; if (shift_is_reg) { - return Common::StringFromFormat("%s%s%s\t%s%sr%d, %s r%d", - opname, cond_to_str(cond), sbit_str, rd_str.c_str(), rn_str.c_str(), rm, - shift_name, rs); + return Common::StringFromFormat("%s%s%s\t%s%sr%d, %s r%d", opname, cond_to_str(cond), + sbit_str, rd_str.c_str(), rn_str.c_str(), rm, shift_name, + rs); } if (shift_amount == 0) { if (shift_type == 3) { - return Common::StringFromFormat("%s%s%s\t%s%sr%d, RRX", - opname, cond_to_str(cond), sbit_str, rd_str.c_str(), rn_str.c_str(), rm); + return Common::StringFromFormat("%s%s%s\t%s%sr%d, RRX", opname, cond_to_str(cond), + sbit_str, rd_str.c_str(), rn_str.c_str(), rm); } shift_amount = 32; } - return Common::StringFromFormat("%s%s%s\t%s%sr%d, %s #%u", - opname, cond_to_str(cond), sbit_str, rd_str.c_str(), rn_str.c_str(), rm, - shift_name, shift_amount); + return Common::StringFromFormat("%s%s%s\t%s%sr%d, %s #%u", opname, cond_to_str(cond), sbit_str, + rd_str.c_str(), rn_str.c_str(), rm, shift_name, shift_amount); } -std::string ARM_Disasm::DisassembleBranch(u32 addr, Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleBranch(u32 addr, Opcode opcode, u32 insn) { u8 cond = (insn >> 28) & 0xf; u32 offset = insn & 0xffffff; // Sign-extend the 24-bit offset @@ -502,26 +322,23 @@ std::string ARM_Disasm::DisassembleBranch(u32 addr, Opcode opcode, u32 insn) offset <<= 2; offset += 8; addr += offset; - const char *opname = opcode_names[opcode]; + const char* opname = opcode_names[opcode]; return Common::StringFromFormat("%s%s\t0x%x", opname, cond_to_str(cond), addr); } -std::string ARM_Disasm::DisassembleBX(u32 insn) -{ +std::string ARM_Disasm::DisassembleBX(u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 rn = insn & 0xf; return Common::StringFromFormat("bx%s\tr%d", cond_to_str(cond), rn); } -std::string ARM_Disasm::DisassembleBKPT(u32 insn) -{ +std::string ARM_Disasm::DisassembleBKPT(u32 insn) { u8 cond = (insn >> 28) & 0xf; u32 immed = (((insn >> 8) & 0xfff) << 4) | (insn & 0xf); return Common::StringFromFormat("bkpt%s\t#%d", cond_to_str(cond), immed); } -std::string ARM_Disasm::DisassembleCLZ(u32 insn) -{ +std::string ARM_Disasm::DisassembleCLZ(u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 rd = (insn >> 12) & 0xf; u8 rm = insn & 0xf; @@ -545,9 +362,8 @@ std::string ARM_Disasm::DisassembleMediaMulDiv(Opcode opcode, u32 insn) { } std::string ext_reg = ""; - std::unordered_set<Opcode, std::hash<int>> with_ext_reg = { - OP_SMLAD, OP_SMLSD, OP_SMMLA, OP_SMMLS, OP_USADA8 - }; + std::unordered_set<Opcode, std::hash<int>> with_ext_reg = {OP_SMLAD, OP_SMLSD, OP_SMMLA, + OP_SMMLS, OP_USADA8}; if (with_ext_reg.find(opcode) != with_ext_reg.end()) ext_reg = Common::StringFromFormat(", r%u", ra); @@ -560,8 +376,7 @@ std::string ARM_Disasm::DisassembleMediaMulDiv(Opcode opcode, u32 insn) { ext_reg.c_str()); } -std::string ARM_Disasm::DisassembleMemblock(Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleMemblock(Opcode opcode, u32 insn) { std::string tmp_list; u8 cond = (insn >> 28) & 0xf; @@ -572,17 +387,17 @@ std::string ARM_Disasm::DisassembleMemblock(Opcode opcode, u32 insn) u8 rn = (insn >> 16) & 0xf; u16 reg_list = insn & 0xffff; - const char *opname = opcode_names[opcode]; + const char* opname = opcode_names[opcode]; - const char *bang = ""; + const char* bang = ""; if (write_back) bang = "!"; - const char *carret = ""; + const char* carret = ""; if (bit_s) carret = "^"; - const char *comma = ""; + const char* comma = ""; tmp_list[0] = 0; for (int ii = 0; ii < 16; ++ii) { if (reg_list & (1 << ii)) { @@ -591,7 +406,7 @@ std::string ARM_Disasm::DisassembleMemblock(Opcode opcode, u32 insn) } } - const char *addr_mode = ""; + const char* addr_mode = ""; if (is_pre) { if (is_up) { addr_mode = "ib"; @@ -606,12 +421,11 @@ std::string ARM_Disasm::DisassembleMemblock(Opcode opcode, u32 insn) } } - return Common::StringFromFormat("%s%s%s\tr%d%s, {%s}%s", - opname, cond_to_str(cond), addr_mode, rn, bang, tmp_list.c_str(), carret); + return Common::StringFromFormat("%s%s%s\tr%d%s, {%s}%s", opname, cond_to_str(cond), addr_mode, + rn, bang, tmp_list.c_str(), carret); } -std::string ARM_Disasm::DisassembleMem(u32 insn) -{ +std::string ARM_Disasm::DisassembleMem(u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 is_reg = (insn >> 25) & 0x1; u8 is_load = (insn >> 20) & 0x1; @@ -623,38 +437,40 @@ std::string ARM_Disasm::DisassembleMem(u32 insn) u8 rd = (insn >> 12) & 0xf; u16 offset = insn & 0xfff; - const char *opname = "ldr"; + const char* opname = "ldr"; if (!is_load) opname = "str"; - const char *bang = ""; + const char* bang = ""; if (write_back) bang = "!"; - const char *minus = ""; + const char* minus = ""; if (is_up == 0) minus = "-"; - const char *byte = ""; + const char* byte = ""; if (is_byte) byte = "b"; if (is_reg == 0) { if (is_pre) { if (offset == 0) { - return Common::StringFromFormat("%s%s%s\tr%d, [r%d]", - opname, cond_to_str(cond), byte, rd, rn); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d]", opname, cond_to_str(cond), + byte, rd, rn); } else { - return Common::StringFromFormat("%s%s%s\tr%d, [r%d, #%s%u]%s", - opname, cond_to_str(cond), byte, rd, rn, minus, offset, bang); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d, #%s%u]%s", opname, + cond_to_str(cond), byte, rd, rn, minus, offset, + bang); } } else { - const char *transfer = ""; + const char* transfer = ""; if (write_back) transfer = "t"; - return Common::StringFromFormat("%s%s%s%s\tr%d, [r%d], #%s%u", - opname, cond_to_str(cond), byte, transfer, rd, rn, minus, offset); + return Common::StringFromFormat("%s%s%s%s\tr%d, [r%d], #%s%u", opname, + cond_to_str(cond), byte, transfer, rd, rn, minus, + offset); } } @@ -662,48 +478,47 @@ std::string ARM_Disasm::DisassembleMem(u32 insn) u8 shift_type = (insn >> 5) & 0x3; u8 shift_amount = (insn >> 7) & 0x1f; - const char *shift_name = shift_names[shift_type]; + const char* shift_name = shift_names[shift_type]; if (is_pre) { if (shift_amount == 0) { if (shift_type == 0) { - return Common::StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d]%s", - opname, cond_to_str(cond), byte, rd, rn, minus, rm, bang); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d]%s", opname, + cond_to_str(cond), byte, rd, rn, minus, rm, bang); } if (shift_type == 3) { - return Common::StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d, RRX]%s", - opname, cond_to_str(cond), byte, rd, rn, minus, rm, bang); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d, RRX]%s", opname, + cond_to_str(cond), byte, rd, rn, minus, rm, bang); } shift_amount = 32; } - return Common::StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d, %s #%u]%s", - opname, cond_to_str(cond), byte, rd, rn, minus, rm, - shift_name, shift_amount, bang); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d, %s #%u]%s", opname, + cond_to_str(cond), byte, rd, rn, minus, rm, shift_name, + shift_amount, bang); } - const char *transfer = ""; + const char* transfer = ""; if (write_back) transfer = "t"; if (shift_amount == 0) { if (shift_type == 0) { - return Common::StringFromFormat("%s%s%s%s\tr%d, [r%d], %sr%d", - opname, cond_to_str(cond), byte, transfer, rd, rn, minus, rm); + return Common::StringFromFormat("%s%s%s%s\tr%d, [r%d], %sr%d", opname, + cond_to_str(cond), byte, transfer, rd, rn, minus, rm); } if (shift_type == 3) { - return Common::StringFromFormat("%s%s%s%s\tr%d, [r%d], %sr%d, RRX", - opname, cond_to_str(cond), byte, transfer, rd, rn, minus, rm); + return Common::StringFromFormat("%s%s%s%s\tr%d, [r%d], %sr%d, RRX", opname, + cond_to_str(cond), byte, transfer, rd, rn, minus, rm); } shift_amount = 32; } - return Common::StringFromFormat("%s%s%s%s\tr%d, [r%d], %sr%d, %s #%u", - opname, cond_to_str(cond), byte, transfer, rd, rn, minus, rm, - shift_name, shift_amount); + return Common::StringFromFormat("%s%s%s%s\tr%d, [r%d], %sr%d, %s #%u", opname, + cond_to_str(cond), byte, transfer, rd, rn, minus, rm, + shift_name, shift_amount); } -std::string ARM_Disasm::DisassembleMemHalf(u32 insn) -{ +std::string ARM_Disasm::DisassembleMemHalf(u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 is_load = (insn >> 20) & 0x1; u8 write_back = (insn >> 21) & 0x1; @@ -716,11 +531,11 @@ std::string ARM_Disasm::DisassembleMemHalf(u32 insn) u8 rm = insn & 0xf; u8 offset = (((insn >> 8) & 0xf) << 4) | (insn & 0xf); - const char *opname = "ldr"; + const char* opname = "ldr"; if (is_load == 0) opname = "str"; - const char *width = ""; + const char* width = ""; if (bits_65 == 1) width = "h"; else if (bits_65 == 2) @@ -728,38 +543,39 @@ std::string ARM_Disasm::DisassembleMemHalf(u32 insn) else width = "sh"; - const char *bang = ""; + const char* bang = ""; if (write_back) bang = "!"; - const char *minus = ""; + const char* minus = ""; if (is_up == 0) minus = "-"; if (is_immed) { if (is_pre) { if (offset == 0) { - return Common::StringFromFormat("%s%s%s\tr%d, [r%d]", opname, cond_to_str(cond), width, rd, rn); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d]", opname, cond_to_str(cond), + width, rd, rn); } else { - return Common::StringFromFormat("%s%s%s\tr%d, [r%d, #%s%u]%s", - opname, cond_to_str(cond), width, rd, rn, minus, offset, bang); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d, #%s%u]%s", opname, + cond_to_str(cond), width, rd, rn, minus, offset, + bang); } } else { - return Common::StringFromFormat("%s%s%s\tr%d, [r%d], #%s%u", - opname, cond_to_str(cond), width, rd, rn, minus, offset); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d], #%s%u", opname, cond_to_str(cond), + width, rd, rn, minus, offset); } } if (is_pre) { - return Common::StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d]%s", - opname, cond_to_str(cond), width, rd, rn, minus, rm, bang); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d, %sr%d]%s", opname, cond_to_str(cond), + width, rd, rn, minus, rm, bang); } else { - return Common::StringFromFormat("%s%s%s\tr%d, [r%d], %sr%d", - opname, cond_to_str(cond), width, rd, rn, minus, rm); + return Common::StringFromFormat("%s%s%s\tr%d, [r%d], %sr%d", opname, cond_to_str(cond), + width, rd, rn, minus, rm); } } -std::string ARM_Disasm::DisassembleMCR(Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleMCR(Opcode opcode, u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 crn = (insn >> 16) & 0xf; u8 crd = (insn >> 12) & 0xf; @@ -767,13 +583,12 @@ std::string ARM_Disasm::DisassembleMCR(Opcode opcode, u32 insn) u8 opcode2 = (insn >> 5) & 0x7; u8 crm = insn & 0xf; - const char *opname = opcode_names[opcode]; - return Common::StringFromFormat("%s%s\t%d, 0, r%d, cr%d, cr%d, {%d}", - opname, cond_to_str(cond), cpnum, crd, crn, crm, opcode2); + const char* opname = opcode_names[opcode]; + return Common::StringFromFormat("%s%s\t%d, 0, r%d, cr%d, cr%d, {%d}", opname, cond_to_str(cond), + cpnum, crd, crn, crm, opcode2); } -std::string ARM_Disasm::DisassembleMLA(Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleMLA(Opcode opcode, u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 rd = (insn >> 16) & 0xf; u8 rn = (insn >> 12) & 0xf; @@ -781,13 +596,12 @@ std::string ARM_Disasm::DisassembleMLA(Opcode opcode, u32 insn) u8 rm = insn & 0xf; u8 bit_s = (insn >> 20) & 1; - const char *opname = opcode_names[opcode]; - return Common::StringFromFormat("%s%s%s\tr%d, r%d, r%d, r%d", - opname, cond_to_str(cond), bit_s ? "s" : "", rd, rm, rs, rn); + const char* opname = opcode_names[opcode]; + return Common::StringFromFormat("%s%s%s\tr%d, r%d, r%d, r%d", opname, cond_to_str(cond), + bit_s ? "s" : "", rd, rm, rs, rn); } -std::string ARM_Disasm::DisassembleUMLAL(Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleUMLAL(Opcode opcode, u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 rdhi = (insn >> 16) & 0xf; u8 rdlo = (insn >> 12) & 0xf; @@ -795,26 +609,24 @@ std::string ARM_Disasm::DisassembleUMLAL(Opcode opcode, u32 insn) u8 rm = insn & 0xf; u8 bit_s = (insn >> 20) & 1; - const char *opname = opcode_names[opcode]; - return Common::StringFromFormat("%s%s%s\tr%d, r%d, r%d, r%d", - opname, cond_to_str(cond), bit_s ? "s" : "", rdlo, rdhi, rm, rs); + const char* opname = opcode_names[opcode]; + return Common::StringFromFormat("%s%s%s\tr%d, r%d, r%d, r%d", opname, cond_to_str(cond), + bit_s ? "s" : "", rdlo, rdhi, rm, rs); } -std::string ARM_Disasm::DisassembleMUL(Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleMUL(Opcode opcode, u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 rd = (insn >> 16) & 0xf; u8 rs = (insn >> 8) & 0xf; u8 rm = insn & 0xf; u8 bit_s = (insn >> 20) & 1; - const char *opname = opcode_names[opcode]; - return Common::StringFromFormat("%s%s%s\tr%d, r%d, r%d", - opname, cond_to_str(cond), bit_s ? "s" : "", rd, rm, rs); + const char* opname = opcode_names[opcode]; + return Common::StringFromFormat("%s%s%s\tr%d, r%d, r%d", opname, cond_to_str(cond), + bit_s ? "s" : "", rd, rm, rs); } -std::string ARM_Disasm::DisassembleMRS(u32 insn) -{ +std::string ARM_Disasm::DisassembleMRS(u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 rd = (insn >> 12) & 0xf; u8 ps = (insn >> 22) & 1; @@ -822,8 +634,7 @@ std::string ARM_Disasm::DisassembleMRS(u32 insn) return Common::StringFromFormat("mrs%s\tr%d, %s", cond_to_str(cond), rd, ps ? "spsr" : "cpsr"); } -std::string ARM_Disasm::DisassembleMSR(u32 insn) -{ +std::string ARM_Disasm::DisassembleMSR(u32 insn) { char flags[8]; int flag_index = 0; u8 cond = (insn >> 28) & 0xf; @@ -846,18 +657,17 @@ std::string ARM_Disasm::DisassembleMSR(u32 insn) u8 rotate = (insn >> 8) & 0xf; u8 rotate2 = rotate << 1; u32 rotated_val = (immed >> rotate2) | (immed << (32 - rotate2)); - return Common::StringFromFormat("msr%s\t%s_%s, #0x%x", - cond_to_str(cond), pd ? "spsr" : "cpsr", flags, rotated_val); + return Common::StringFromFormat("msr%s\t%s_%s, #0x%x", cond_to_str(cond), + pd ? "spsr" : "cpsr", flags, rotated_val); } u8 rm = insn & 0xf; - return Common::StringFromFormat("msr%s\t%s_%s, r%d", - cond_to_str(cond), pd ? "spsr" : "cpsr", flags, rm); + return Common::StringFromFormat("msr%s\t%s_%s, r%d", cond_to_str(cond), pd ? "spsr" : "cpsr", + flags, rm); } -std::string ARM_Disasm::DisassembleNoOperands(Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleNoOperands(Opcode opcode, u32 insn) { u32 cond = BITS(insn, 28, 31); return Common::StringFromFormat("%s%s", opcode_names[opcode], cond_to_str(cond)); } @@ -872,8 +682,7 @@ std::string ARM_Disasm::DisassembleParallelAddSub(Opcode opcode, u32 insn) { rd, rn, rm); } -std::string ARM_Disasm::DisassemblePKH(u32 insn) -{ +std::string ARM_Disasm::DisassemblePKH(u32 insn) { u32 cond = BITS(insn, 28, 31); u32 rn = BITS(insn, 16, 19); u32 rd = BITS(insn, 12, 15); @@ -896,13 +705,12 @@ std::string ARM_Disasm::DisassemblePKH(u32 insn) rd, rn, rm, shift.c_str()); } -std::string ARM_Disasm::DisassemblePLD(u32 insn) -{ +std::string ARM_Disasm::DisassemblePLD(u32 insn) { u8 is_reg = (insn >> 25) & 0x1; u8 is_up = (insn >> 23) & 0x1; u8 rn = (insn >> 16) & 0xf; - const char *minus = ""; + const char* minus = ""; if (is_up == 0) minus = "-"; @@ -924,8 +732,8 @@ std::string ARM_Disasm::DisassembleREV(Opcode opcode, u32 insn) { u32 rd = BITS(insn, 12, 15); u32 rm = BITS(insn, 0, 3); - return Common::StringFromFormat("%s%s\tr%u, r%u", opcode_names[opcode], cond_to_str(cond), - rd, rm); + return Common::StringFromFormat("%s%s\tr%u, r%u", opcode_names[opcode], cond_to_str(cond), rd, + rm); } std::string ARM_Disasm::DisassembleREX(Opcode opcode, u32 insn) { @@ -935,26 +743,26 @@ std::string ARM_Disasm::DisassembleREX(Opcode opcode, u32 insn) { u32 cond = BITS(insn, 28, 31); switch (opcode) { - case OP_STREX: - case OP_STREXB: - case OP_STREXH: - return Common::StringFromFormat("%s%s\tr%d, r%d, [r%d]", opcode_names[opcode], - cond_to_str(cond), rd, rt, rn); - case OP_STREXD: - return Common::StringFromFormat("%s%s\tr%d, r%d, r%d, [r%d]", opcode_names[opcode], - cond_to_str(cond), rd, rt, rt + 1, rn); - - // for LDREX instructions, rd corresponds to Rt from reference manual - case OP_LDREX: - case OP_LDREXB: - case OP_LDREXH: - return Common::StringFromFormat("%s%s\tr%d, [r%d]", opcode_names[opcode], - cond_to_str(cond), rd, rn); - case OP_LDREXD: - return Common::StringFromFormat("%s%s\tr%d, r%d, [r%d]", opcode_names[opcode], - cond_to_str(cond), rd, rd + 1, rn); - default: - return opcode_names[OP_UNDEFINED]; + case OP_STREX: + case OP_STREXB: + case OP_STREXH: + return Common::StringFromFormat("%s%s\tr%d, r%d, [r%d]", opcode_names[opcode], + cond_to_str(cond), rd, rt, rn); + case OP_STREXD: + return Common::StringFromFormat("%s%s\tr%d, r%d, r%d, [r%d]", opcode_names[opcode], + cond_to_str(cond), rd, rt, rt + 1, rn); + + // for LDREX instructions, rd corresponds to Rt from reference manual + case OP_LDREX: + case OP_LDREXB: + case OP_LDREXH: + return Common::StringFromFormat("%s%s\tr%d, [r%d]", opcode_names[opcode], cond_to_str(cond), + rd, rn); + case OP_LDREXD: + return Common::StringFromFormat("%s%s\tr%d, r%d, [r%d]", opcode_names[opcode], + cond_to_str(cond), rd, rd + 1, rn); + default: + return opcode_names[OP_UNDEFINED]; } } @@ -982,8 +790,8 @@ std::string ARM_Disasm::DisassembleSAT(Opcode opcode, u32 insn) { if (opcode == OP_SSAT || opcode == OP_SSAT16) sat_imm++; - return Common::StringFromFormat("%s%s\tr%u, #%u, r%u%s", opcode_names[opcode], cond_to_str(cond), rd, - sat_imm, rn, shift_part.c_str()); + return Common::StringFromFormat("%s%s\tr%u, #%u, r%u%s", opcode_names[opcode], + cond_to_str(cond), rd, sat_imm, rn, shift_part.c_str()); } std::string ARM_Disasm::DisassembleSEL(u32 insn) { @@ -996,27 +804,24 @@ std::string ARM_Disasm::DisassembleSEL(u32 insn) { rd, rn, rm); } -std::string ARM_Disasm::DisassembleSWI(u32 insn) -{ +std::string ARM_Disasm::DisassembleSWI(u32 insn) { u8 cond = (insn >> 28) & 0xf; u32 sysnum = insn & 0x00ffffff; return Common::StringFromFormat("swi%s 0x%x", cond_to_str(cond), sysnum); } -std::string ARM_Disasm::DisassembleSWP(Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleSWP(Opcode opcode, u32 insn) { u8 cond = (insn >> 28) & 0xf; u8 rn = (insn >> 16) & 0xf; u8 rd = (insn >> 12) & 0xf; u8 rm = insn & 0xf; - const char *opname = opcode_names[opcode]; + const char* opname = opcode_names[opcode]; return Common::StringFromFormat("%s%s\tr%d, r%d, [r%d]", opname, cond_to_str(cond), rd, rm, rn); } -std::string ARM_Disasm::DisassembleXT(Opcode opcode, u32 insn) -{ +std::string ARM_Disasm::DisassembleXT(Opcode opcode, u32 insn) { u32 cond = BITS(insn, 28, 31); u32 rn = BITS(insn, 16, 19); u32 rd = BITS(insn, 12, 15); @@ -1025,9 +830,7 @@ std::string ARM_Disasm::DisassembleXT(Opcode opcode, u32 insn) std::string rn_part = ""; static std::unordered_set<Opcode, std::hash<int>> extend_with_add = { - OP_SXTAB, OP_SXTAB16, OP_SXTAH, - OP_UXTAB, OP_UXTAB16, OP_UXTAH - }; + OP_SXTAB, OP_SXTAB16, OP_SXTAH, OP_UXTAB, OP_UXTAB16, OP_UXTAH}; if (extend_with_add.find(opcode) != extend_with_add.end()) rn_part = ", r" + std::to_string(rn); @@ -1042,14 +845,14 @@ std::string ARM_Disasm::DisassembleXT(Opcode opcode, u32 insn) Opcode ARM_Disasm::Decode(u32 insn) { u32 bits27_26 = (insn >> 26) & 0x3; switch (bits27_26) { - case 0x0: - return Decode00(insn); - case 0x1: - return Decode01(insn); - case 0x2: - return Decode10(insn); - case 0x3: - return Decode11(insn); + case 0x0: + return Decode00(insn); + case 0x1: + return Decode01(insn); + case 0x2: + return Decode10(insn); + case 0x3: + return Decode11(insn); } return OP_INVALID; } @@ -1198,28 +1001,28 @@ Opcode ARM_Disasm::DecodeSyncPrimitive(u32 insn) { u32 op = BITS(insn, 20, 23); u32 bit22 = BIT(insn, 22); switch (op) { - case 0x0: - if (bit22) - return OP_SWPB; - return OP_SWP; - case 0x8: - return OP_STREX; - case 0x9: - return OP_LDREX; - case 0xA: - return OP_STREXD; - case 0xB: - return OP_LDREXD; - case 0xC: - return OP_STREXB; - case 0xD: - return OP_LDREXB; - case 0xE: - return OP_STREXH; - case 0xF: - return OP_LDREXH; - default: - return OP_UNDEFINED; + case 0x0: + if (bit22) + return OP_SWPB; + return OP_SWP; + case 0x8: + return OP_STREX; + case 0x9: + return OP_LDREX; + case 0xA: + return OP_STREXD; + case 0xB: + return OP_LDREXD; + case 0xC: + return OP_STREXB; + case 0xD: + return OP_LDREXB; + case 0xE: + return OP_STREXH; + case 0xF: + return OP_LDREXH; + default: + return OP_UNDEFINED; } } @@ -1240,27 +1043,14 @@ Opcode ARM_Disasm::DecodeParallelAddSub(u32 insn) { static std::vector<Opcode> opcodes = { // op1 = 0 - OP_SADD16, OP_UADD16, - OP_SASX, OP_UASX, - OP_SSAX, OP_USAX, - OP_SSUB16, OP_USUB16, - OP_SADD8, OP_UADD8, - OP_SSUB8, OP_USUB8, + OP_SADD16, OP_UADD16, OP_SASX, OP_UASX, OP_SSAX, OP_USAX, OP_SSUB16, OP_USUB16, OP_SADD8, + OP_UADD8, OP_SSUB8, OP_USUB8, // op1 = 1 - OP_QADD16, OP_UQADD16, - OP_QASX, OP_UQASX, - OP_QSAX, OP_UQSAX, - OP_QSUB16, OP_UQSUB16, - OP_QADD8, OP_UQADD8, - OP_QSUB8, OP_UQSUB8, + OP_QADD16, OP_UQADD16, OP_QASX, OP_UQASX, OP_QSAX, OP_UQSAX, OP_QSUB16, OP_UQSUB16, + OP_QADD8, OP_UQADD8, OP_QSUB8, OP_UQSUB8, // op1 = 2 - OP_SHADD16, OP_UHADD16, - OP_SHASX, OP_UHASX, - OP_SHSAX, OP_UHSAX, - OP_SHSUB16, OP_UHSUB16, - OP_SHADD8, OP_UHADD8, - OP_SHSUB8, OP_UHSUB8 - }; + OP_SHADD16, OP_UHADD16, OP_SHASX, OP_UHASX, OP_SHSAX, OP_UHSAX, OP_SHSUB16, OP_UHSUB16, + OP_SHADD8, OP_UHADD8, OP_SHSUB8, OP_UHSUB8}; u32 opcode_index = op1 * 12 + op2 * 2 + is_unsigned; return opcodes[opcode_index]; @@ -1272,66 +1062,66 @@ Opcode ARM_Disasm::DecodePackingSaturationReversal(u32 insn) { u32 op2 = BITS(insn, 5, 7); switch (op1) { - case 0x0: - if (BIT(op2, 0) == 0) - return OP_PKH; - if (op2 == 0x3 && a != 0xf) - return OP_SXTAB16; - if (op2 == 0x3 && a == 0xf) - return OP_SXTB16; - if (op2 == 0x5) - return OP_SEL; - break; - case 0x2: - if (BIT(op2, 0) == 0) - return OP_SSAT; - if (op2 == 0x1) - return OP_SSAT16; - if (op2 == 0x3 && a != 0xf) - return OP_SXTAB; - if (op2 == 0x3 && a == 0xf) - return OP_SXTB; - break; - case 0x3: - if (op2 == 0x1) - return OP_REV; - if (BIT(op2, 0) == 0) - return OP_SSAT; - if (op2 == 0x3 && a != 0xf) - return OP_SXTAH; - if (op2 == 0x3 && a == 0xf) - return OP_SXTH; - if (op2 == 0x5) - return OP_REV16; - break; - case 0x4: - if (op2 == 0x3 && a != 0xf) - return OP_UXTAB16; - if (op2 == 0x3 && a == 0xf) - return OP_UXTB16; - break; - case 0x6: - if (BIT(op2, 0) == 0) - return OP_USAT; - if (op2 == 0x1) - return OP_USAT16; - if (op2 == 0x3 && a != 0xf) - return OP_UXTAB; - if (op2 == 0x3 && a == 0xf) - return OP_UXTB; - break; - case 0x7: - if (BIT(op2, 0) == 0) - return OP_USAT; - if (op2 == 0x3 && a != 0xf) - return OP_UXTAH; - if (op2 == 0x3 && a == 0xf) - return OP_UXTH; - if (op2 == 0x5) - return OP_REVSH; - break; - default: - break; + case 0x0: + if (BIT(op2, 0) == 0) + return OP_PKH; + if (op2 == 0x3 && a != 0xf) + return OP_SXTAB16; + if (op2 == 0x3 && a == 0xf) + return OP_SXTB16; + if (op2 == 0x5) + return OP_SEL; + break; + case 0x2: + if (BIT(op2, 0) == 0) + return OP_SSAT; + if (op2 == 0x1) + return OP_SSAT16; + if (op2 == 0x3 && a != 0xf) + return OP_SXTAB; + if (op2 == 0x3 && a == 0xf) + return OP_SXTB; + break; + case 0x3: + if (op2 == 0x1) + return OP_REV; + if (BIT(op2, 0) == 0) + return OP_SSAT; + if (op2 == 0x3 && a != 0xf) + return OP_SXTAH; + if (op2 == 0x3 && a == 0xf) + return OP_SXTH; + if (op2 == 0x5) + return OP_REV16; + break; + case 0x4: + if (op2 == 0x3 && a != 0xf) + return OP_UXTAB16; + if (op2 == 0x3 && a == 0xf) + return OP_UXTB16; + break; + case 0x6: + if (BIT(op2, 0) == 0) + return OP_USAT; + if (op2 == 0x1) + return OP_USAT16; + if (op2 == 0x3 && a != 0xf) + return OP_UXTAB; + if (op2 == 0x3 && a == 0xf) + return OP_UXTB; + break; + case 0x7: + if (BIT(op2, 0) == 0) + return OP_USAT; + if (op2 == 0x3 && a != 0xf) + return OP_UXTAH; + if (op2 == 0x3 && a == 0xf) + return OP_UXTH; + if (op2 == 0x5) + return OP_REVSH; + break; + default: + break; } return OP_UNDEFINED; @@ -1378,18 +1168,18 @@ Opcode ARM_Disasm::DecodeMSRImmAndHints(u32 insn) { if (op == 0 && op1 == 0) { switch (op2) { - case 0x0: - return OP_NOP; - case 0x1: - return OP_YIELD; - case 0x2: - return OP_WFE; - case 0x3: - return OP_WFI; - case 0x4: - return OP_SEV; - default: - return OP_UNDEFINED; + case 0x0: + return OP_NOP; + case 0x1: + return OP_YIELD; + case 0x2: + return OP_WFE; + case 0x3: + return OP_WFI; + case 0x4: + return OP_SEV; + default: + return OP_UNDEFINED; } } @@ -1402,37 +1192,37 @@ Opcode ARM_Disasm::DecodeMediaMulDiv(u32 insn) { u32 a = BITS(insn, 12, 15); switch (op1) { - case 0x0: - if (op2_h == 0x0) { - if (a != 0xf) - return OP_SMLAD; - else - return OP_SMUAD; - } else if (op2_h == 0x1) { - if (a != 0xf) - return OP_SMLSD; - else - return OP_SMUSD; - } - break; - case 0x4: - if (op2_h == 0x0) - return OP_SMLALD; - else if (op2_h == 0x1) - return OP_SMLSLD; - break; - case 0x5: - if (op2_h == 0x0) { - if (a != 0xf) - return OP_SMMLA; - else - return OP_SMMUL; - } else if (op2_h == 0x3) { - return OP_SMMLS; - } - break; - default: - break; + case 0x0: + if (op2_h == 0x0) { + if (a != 0xf) + return OP_SMLAD; + else + return OP_SMUAD; + } else if (op2_h == 0x1) { + if (a != 0xf) + return OP_SMLSD; + else + return OP_SMUSD; + } + break; + case 0x4: + if (op2_h == 0x0) + return OP_SMLALD; + else if (op2_h == 0x1) + return OP_SMLSLD; + break; + case 0x5: + if (op2_h == 0x0) { + if (a != 0xf) + return OP_SMMLA; + else + return OP_SMMUL; + } else if (op2_h == 0x3) { + return OP_SMMLS; + } + break; + default: + break; } return OP_UNDEFINED; @@ -1444,23 +1234,23 @@ Opcode ARM_Disasm::DecodeMedia(u32 insn) { u32 op2 = BITS(insn, 5, 7); switch (BITS(op1, 3, 4)) { - case 0x0: - // unsigned and signed parallel addition and subtraction - return DecodeParallelAddSub(insn); - case 0x1: - // Packing, unpacking, saturation, and reversal - return DecodePackingSaturationReversal(insn); - case 0x2: - // Signed multiply, signed and unsigned divide - return DecodeMediaMulDiv(insn); - case 0x3: - if (op2 == 0 && rd == 0xf) - return OP_USAD8; - if (op2 == 0 && rd != 0xf) - return OP_USADA8; - break; - default: - break; + case 0x0: + // unsigned and signed parallel addition and subtraction + return DecodeParallelAddSub(insn); + case 0x1: + // Packing, unpacking, saturation, and reversal + return DecodePackingSaturationReversal(insn); + case 0x2: + // Signed multiply, signed and unsigned divide + return DecodeMediaMulDiv(insn); + case 0x3: + if (op2 == 0 && rd == 0xf) + return OP_USAD8; + if (op2 == 0 && rd != 0xf) + return OP_USADA8; + break; + default: + break; } return OP_UNDEFINED; @@ -1508,46 +1298,46 @@ Opcode ARM_Disasm::DecodeALU(u32 insn) { return OP_UNDEFINED; } switch (opcode) { - case 0x0: - return OP_AND; - case 0x1: - return OP_EOR; - case 0x2: - return OP_SUB; - case 0x3: - return OP_RSB; - case 0x4: - return OP_ADD; - case 0x5: - return OP_ADC; - case 0x6: - return OP_SBC; - case 0x7: - return OP_RSC; - case 0x8: - if (bit_s) - return OP_TST; - return OP_MRS; - case 0x9: - if (bit_s) - return OP_TEQ; - return OP_MSR; - case 0xa: - if (bit_s) - return OP_CMP; - return OP_MRS; - case 0xb: - if (bit_s) - return OP_CMN; - return OP_MSR; - case 0xc: - return OP_ORR; - case 0xd: - return OP_MOV; - case 0xe: - return OP_BIC; - case 0xf: - return OP_MVN; + case 0x0: + return OP_AND; + case 0x1: + return OP_EOR; + case 0x2: + return OP_SUB; + case 0x3: + return OP_RSB; + case 0x4: + return OP_ADD; + case 0x5: + return OP_ADC; + case 0x6: + return OP_SBC; + case 0x7: + return OP_RSC; + case 0x8: + if (bit_s) + return OP_TST; + return OP_MRS; + case 0x9: + if (bit_s) + return OP_TEQ; + return OP_MSR; + case 0xa: + if (bit_s) + return OP_CMP; + return OP_MRS; + case 0xb: + if (bit_s) + return OP_CMN; + return OP_MSR; + case 0xc: + return OP_ORR; + case 0xd: + return OP_MOV; + case 0xe: + return OP_BIC; + case 0xf: + return OP_MVN; } // Unreachable return OP_INVALID; diff --git a/src/core/arm/disassembler/arm_disasm.h b/src/core/arm/disassembler/arm_disasm.h index 53d9c6a74..300e228ed 100644 --- a/src/core/arm/disassembler/arm_disasm.h +++ b/src/core/arm/disassembler/arm_disasm.h @@ -3,7 +3,6 @@ #pragma once #include <string> - #include "common/common_types.h" // Note: this list of opcodes must match the list used to initialize @@ -187,53 +186,53 @@ enum Opcode { OP_THUMB_SWI, OP_THUMB_TST, - OP_END // must be last + OP_END // must be last }; class ARM_Disasm { - public: - static std::string Disassemble(u32 addr, u32 insn); - static Opcode Decode(u32 insn); +public: + static std::string Disassemble(u32 addr, u32 insn); + static Opcode Decode(u32 insn); - private: - static Opcode Decode00(u32 insn); - static Opcode Decode01(u32 insn); - static Opcode Decode10(u32 insn); - static Opcode Decode11(u32 insn); - static Opcode DecodeSyncPrimitive(u32 insn); - static Opcode DecodeParallelAddSub(u32 insn); - static Opcode DecodePackingSaturationReversal(u32 insn); - static Opcode DecodeMUL(u32 insn); - static Opcode DecodeMSRImmAndHints(u32 insn); - static Opcode DecodeMediaMulDiv(u32 insn); - static Opcode DecodeMedia(u32 insn); - static Opcode DecodeLDRH(u32 insn); - static Opcode DecodeALU(u32 insn); +private: + static Opcode Decode00(u32 insn); + static Opcode Decode01(u32 insn); + static Opcode Decode10(u32 insn); + static Opcode Decode11(u32 insn); + static Opcode DecodeSyncPrimitive(u32 insn); + static Opcode DecodeParallelAddSub(u32 insn); + static Opcode DecodePackingSaturationReversal(u32 insn); + static Opcode DecodeMUL(u32 insn); + static Opcode DecodeMSRImmAndHints(u32 insn); + static Opcode DecodeMediaMulDiv(u32 insn); + static Opcode DecodeMedia(u32 insn); + static Opcode DecodeLDRH(u32 insn); + static Opcode DecodeALU(u32 insn); - static std::string DisassembleALU(Opcode opcode, u32 insn); - static std::string DisassembleBranch(u32 addr, Opcode opcode, u32 insn); - static std::string DisassembleBX(u32 insn); - static std::string DisassembleBKPT(u32 insn); - static std::string DisassembleCLZ(u32 insn); - static std::string DisassembleMediaMulDiv(Opcode opcode, u32 insn); - static std::string DisassembleMemblock(Opcode opcode, u32 insn); - static std::string DisassembleMem(u32 insn); - static std::string DisassembleMemHalf(u32 insn); - static std::string DisassembleMCR(Opcode opcode, u32 insn); - static std::string DisassembleMLA(Opcode opcode, u32 insn); - static std::string DisassembleUMLAL(Opcode opcode, u32 insn); - static std::string DisassembleMUL(Opcode opcode, u32 insn); - static std::string DisassembleMRS(u32 insn); - static std::string DisassembleMSR(u32 insn); - static std::string DisassembleNoOperands(Opcode opcode, u32 insn); - static std::string DisassembleParallelAddSub(Opcode opcode, u32 insn); - static std::string DisassemblePKH(u32 insn); - static std::string DisassemblePLD(u32 insn); - static std::string DisassembleREV(Opcode opcode, u32 insn); - static std::string DisassembleREX(Opcode opcode, u32 insn); - static std::string DisassembleSAT(Opcode opcode, u32 insn); - static std::string DisassembleSEL(u32 insn); - static std::string DisassembleSWI(u32 insn); - static std::string DisassembleSWP(Opcode opcode, u32 insn); - static std::string DisassembleXT(Opcode opcode, u32 insn); + static std::string DisassembleALU(Opcode opcode, u32 insn); + static std::string DisassembleBranch(u32 addr, Opcode opcode, u32 insn); + static std::string DisassembleBX(u32 insn); + static std::string DisassembleBKPT(u32 insn); + static std::string DisassembleCLZ(u32 insn); + static std::string DisassembleMediaMulDiv(Opcode opcode, u32 insn); + static std::string DisassembleMemblock(Opcode opcode, u32 insn); + static std::string DisassembleMem(u32 insn); + static std::string DisassembleMemHalf(u32 insn); + static std::string DisassembleMCR(Opcode opcode, u32 insn); + static std::string DisassembleMLA(Opcode opcode, u32 insn); + static std::string DisassembleUMLAL(Opcode opcode, u32 insn); + static std::string DisassembleMUL(Opcode opcode, u32 insn); + static std::string DisassembleMRS(u32 insn); + static std::string DisassembleMSR(u32 insn); + static std::string DisassembleNoOperands(Opcode opcode, u32 insn); + static std::string DisassembleParallelAddSub(Opcode opcode, u32 insn); + static std::string DisassemblePKH(u32 insn); + static std::string DisassemblePLD(u32 insn); + static std::string DisassembleREV(Opcode opcode, u32 insn); + static std::string DisassembleREX(Opcode opcode, u32 insn); + static std::string DisassembleSAT(Opcode opcode, u32 insn); + static std::string DisassembleSEL(u32 insn); + static std::string DisassembleSWI(u32 insn); + static std::string DisassembleSWP(Opcode opcode, u32 insn); + static std::string DisassembleXT(Opcode opcode, u32 insn); }; diff --git a/src/core/arm/disassembler/load_symbol_map.cpp b/src/core/arm/disassembler/load_symbol_map.cpp index eb20bf6f7..6863c103a 100644 --- a/src/core/arm/disassembler/load_symbol_map.cpp +++ b/src/core/arm/disassembler/load_symbol_map.cpp @@ -5,10 +5,8 @@ #include <sstream> #include <string> #include <vector> - -#include "common/symbols.h" #include "common/file_util.h" - +#include "common/symbols.h" #include "core/arm/disassembler/load_symbol_map.h" /* diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index a521aec7c..b4444c869 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -2,11 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <dynarmic/dynarmic.h> #include "common/assert.h" #include "common/microprofile.h" - -#include <dynarmic/dynarmic.h> - #include "core/arm/dynarmic/arm_dynarmic.h" #include "core/arm/dyncom/arm_dyncom_interpreter.h" #include "core/core.h" diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index d493cabd5..ced86d29b 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -5,11 +5,8 @@ #pragma once #include <memory> - #include <dynarmic/dynarmic.h> - #include "common/common_types.h" - #include "core/arm/arm_interface.h" #include "core/arm/skyeye_common/armstate.h" diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp index d84917529..34c7f945e 100644 --- a/src/core/arm/dyncom/arm_dyncom.cpp +++ b/src/core/arm/dyncom/arm_dyncom.cpp @@ -4,16 +4,13 @@ #include <cstring> #include <memory> - -#include "core/arm/skyeye_common/armstate.h" -#include "core/arm/skyeye_common/armsupp.h" -#include "core/arm/skyeye_common/vfp/vfp.h" - #include "core/arm/dyncom/arm_dyncom.h" #include "core/arm/dyncom/arm_dyncom_interpreter.h" #include "core/arm/dyncom/arm_dyncom_run.h" #include "core/arm/dyncom/arm_dyncom_trans.h" - +#include "core/arm/skyeye_common/armstate.h" +#include "core/arm/skyeye_common/armsupp.h" +#include "core/arm/skyeye_common/vfp/vfp.h" #include "core/core.h" #include "core/core_timing.h" @@ -21,8 +18,7 @@ ARM_DynCom::ARM_DynCom(PrivilegeMode initial_mode) { state = std::make_unique<ARMul_State>(initial_mode); } -ARM_DynCom::~ARM_DynCom() { -} +ARM_DynCom::~ARM_DynCom() {} void ARM_DynCom::ClearInstructionCache() { state->instruction_cache.clear(); diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h index 70f71a828..65db1f0f9 100644 --- a/src/core/arm/dyncom/arm_dyncom.h +++ b/src/core/arm/dyncom/arm_dyncom.h @@ -5,9 +5,7 @@ #pragma once #include <memory> - #include "common/common_types.h" - #include "core/arm/arm_interface.h" #include "core/arm/skyeye_common/arm_regformat.h" #include "core/arm/skyeye_common/armstate.h" diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp index 247d379e3..64dcaae08 100644 --- a/src/core/arm/dyncom/arm_dyncom_dec.cpp +++ b/src/core/arm/dyncom/arm_dyncom_dec.cpp @@ -5,6 +5,7 @@ #include "core/arm/dyncom/arm_dyncom_dec.h" #include "core/arm/skyeye_common/armsupp.h" +// clang-format off const InstructionSetEncodingItem arm_instruction[] = { { "vmla", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 0, 4, 4, 0 }}, { "vmls", 5, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 1, 4, 4, 0 }}, @@ -206,6 +207,7 @@ const InstructionSetEncodingItem arm_instruction[] = { { "bbl", 1, 0, { 25, 27, 0x00000005 }}, }; + const InstructionSetEncodingItem arm_exclusion_code[] = { { "vmla", 0, ARMVFP2, { 0 }}, { "vmls", 0, ARMVFP2, { 0 }}, @@ -411,6 +413,7 @@ const InstructionSetEncodingItem arm_exclusion_code[] = { { "blx_1_thumb", 0, INVALID, { 0 }}, // Should be located at table[-2] { "invalid", 0, INVALID, { 0 }} }; +// clang-format on ARMDecodeStatus DecodeARMInstruction(u32 instr, s32* idx) { int n = 0; @@ -427,12 +430,15 @@ ARMDecodeStatus DecodeARMInstruction(u32 instr, s32* idx) { continue; while (n) { - if (arm_instruction[i].content[base + 1] == 31 && arm_instruction[i].content[base] == 0) { + if (arm_instruction[i].content[base + 1] == 31 && + arm_instruction[i].content[base] == 0) { // clrex if (instr != arm_instruction[i].content[base + 2]) { break; } - } else if (BITS(instr, arm_instruction[i].content[base], arm_instruction[i].content[base + 1]) != arm_instruction[i].content[base + 2]) { + } else if (BITS(instr, arm_instruction[i].content[base], + arm_instruction[i].content[base + 1]) != + arm_instruction[i].content[base + 2]) { break; } base += 3; @@ -448,7 +454,9 @@ ARMDecodeStatus DecodeARMInstruction(u32 instr, s32* idx) { if (n != 0) { base = 0; while (n) { - if (BITS(instr, arm_exclusion_code[i].content[base], arm_exclusion_code[i].content[base + 1]) != arm_exclusion_code[i].content[base + 2]) { + if (BITS(instr, arm_exclusion_code[i].content[base], + arm_exclusion_code[i].content[base + 1]) != + arm_exclusion_code[i].content[base + 2]) { break; } base += 3; diff --git a/src/core/arm/dyncom/arm_dyncom_dec.h b/src/core/arm/dyncom/arm_dyncom_dec.h index d7170e0fc..2fb7ac37c 100644 --- a/src/core/arm/dyncom/arm_dyncom_dec.h +++ b/src/core/arm/dyncom/arm_dyncom_dec.h @@ -6,15 +6,12 @@ #include "common/common_types.h" -enum class ARMDecodeStatus { - SUCCESS, - FAILURE -}; +enum class ARMDecodeStatus { SUCCESS, FAILURE }; ARMDecodeStatus DecodeARMInstruction(u32 instr, s32* idx); struct InstructionSetEncodingItem { - const char *name; + const char* name; int attribute_value; int version; u32 content[21]; diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index c8d45c6db..7b8616702 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp @@ -6,34 +6,31 @@ #include <algorithm> #include <cstdio> - #include "common/common_types.h" #include "common/logging/log.h" #include "common/microprofile.h" - -#include "core/memory.h" -#include "core/hle/svc.h" #include "core/arm/disassembler/arm_disasm.h" #include "core/arm/dyncom/arm_dyncom_dec.h" #include "core/arm/dyncom/arm_dyncom_interpreter.h" +#include "core/arm/dyncom/arm_dyncom_run.h" #include "core/arm/dyncom/arm_dyncom_thumb.h" #include "core/arm/dyncom/arm_dyncom_trans.h" -#include "core/arm/dyncom/arm_dyncom_run.h" #include "core/arm/skyeye_common/armstate.h" #include "core/arm/skyeye_common/armsupp.h" #include "core/arm/skyeye_common/vfp/vfp.h" - #include "core/gdbstub/gdbstub.h" +#include "core/hle/svc.h" +#include "core/memory.h" -#define RM BITS(sht_oper, 0, 3) -#define RS BITS(sht_oper, 8, 11) +#define RM BITS(sht_oper, 0, 3) +#define RS BITS(sht_oper, 8, 11) -#define glue(x, y) x ## y -#define DPO(s) glue(DataProcessingOperands, s) +#define glue(x, y) x##y +#define DPO(s) glue(DataProcessingOperands, s) #define ROTATE_RIGHT(n, i, l) ((n << (l - i)) | (n >> i)) -#define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i)) +#define ROTATE_LEFT(n, i, l) ((n >> (l - i)) | (n << i)) #define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32) -#define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32) +#define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32) static bool CondPassed(const ARMul_State* cpu, unsigned int cond) { const bool n_flag = cpu->NFlag != 0; @@ -232,17 +229,19 @@ static unsigned int DPO(RotateRightByRegister)(ARMul_State* cpu, unsigned int sh return shifter_operand; } -#define DEBUG_MSG LOG_DEBUG(Core_ARM11, "inst is %x", inst); CITRA_IGNORE_EXIT(0) +#define DEBUG_MSG \ + LOG_DEBUG(Core_ARM11, "inst is %x", inst); \ + CITRA_IGNORE_EXIT(0) -#define LnSWoUB(s) glue(LnSWoUB, s) -#define MLnS(s) glue(MLnS, s) -#define LdnStM(s) glue(LdnStM, s) +#define LnSWoUB(s) glue(LnSWoUB, s) +#define MLnS(s) glue(MLnS, s) +#define LdnStM(s) glue(LdnStM, s) -#define W_BIT BIT(inst, 21) -#define U_BIT BIT(inst, 23) -#define I_BIT BIT(inst, 25) -#define P_BIT BIT(inst, 24) -#define OFFSET_12 BITS(inst, 0, 11) +#define W_BIT BIT(inst, 21) +#define U_BIT BIT(inst, 23) +#define I_BIT BIT(inst, 25) +#define P_BIT BIT(inst, 24) +#define OFFSET_12 BITS(inst, 0, 11) static void LnSWoUB(ImmediateOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) { unsigned int Rn = BITS(inst, 16, 19); @@ -271,7 +270,8 @@ static void LnSWoUB(RegisterOffset)(ARMul_State* cpu, unsigned int inst, unsigne virt_addr = addr; } -static void LnSWoUB(ImmediatePostIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) { +static void LnSWoUB(ImmediatePostIndexed)(ARMul_State* cpu, unsigned int inst, + unsigned int& virt_addr) { unsigned int Rn = BITS(inst, 16, 19); unsigned int addr = CHECK_READ_REG15_WA(cpu, Rn); @@ -283,7 +283,8 @@ static void LnSWoUB(ImmediatePostIndexed)(ARMul_State* cpu, unsigned int inst, u virt_addr = addr; } -static void LnSWoUB(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) { +static void LnSWoUB(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst, + unsigned int& virt_addr) { unsigned int Rn = BITS(inst, 16, 19); unsigned int addr; @@ -301,7 +302,7 @@ static void LnSWoUB(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst, un static void MLnS(RegisterPreIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) { unsigned int addr; unsigned int Rn = BITS(inst, 16, 19); - unsigned int Rm = BITS(inst, 0, 3); + unsigned int Rm = BITS(inst, 0, 3); unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); @@ -316,7 +317,8 @@ static void MLnS(RegisterPreIndexed)(ARMul_State* cpu, unsigned int inst, unsign cpu->Reg[Rn] = addr; } -static void LnSWoUB(RegisterPreIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) { +static void LnSWoUB(RegisterPreIndexed)(ARMul_State* cpu, unsigned int inst, + unsigned int& virt_addr) { unsigned int Rn = BITS(inst, 16, 19); unsigned int Rm = BITS(inst, 0, 3); unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); @@ -335,7 +337,8 @@ static void LnSWoUB(RegisterPreIndexed)(ARMul_State* cpu, unsigned int inst, uns } } -static void LnSWoUB(ScaledRegisterPreIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) { +static void LnSWoUB(ScaledRegisterPreIndexed)(ARMul_State* cpu, unsigned int inst, + unsigned int& virt_addr) { unsigned int shift = BITS(inst, 5, 6); unsigned int shift_imm = BITS(inst, 7, 11); unsigned int Rn = BITS(inst, 16, 19); @@ -386,7 +389,8 @@ static void LnSWoUB(ScaledRegisterPreIndexed)(ARMul_State* cpu, unsigned int ins cpu->Reg[Rn] = addr; } -static void LnSWoUB(ScaledRegisterPostIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) { +static void LnSWoUB(ScaledRegisterPostIndexed)(ARMul_State* cpu, unsigned int inst, + unsigned int& virt_addr) { unsigned int shift = BITS(inst, 5, 6); unsigned int shift_imm = BITS(inst, 7, 11); unsigned int Rn = BITS(inst, 16, 19); @@ -435,9 +439,10 @@ static void LnSWoUB(ScaledRegisterPostIndexed)(ARMul_State* cpu, unsigned int in } } -static void LnSWoUB(RegisterPostIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) { +static void LnSWoUB(RegisterPostIndexed)(ARMul_State* cpu, unsigned int inst, + unsigned int& virt_addr) { unsigned int Rn = BITS(inst, 16, 19); - unsigned int Rm = BITS(inst, 0, 3); + unsigned int Rm = BITS(inst, 0, 3); unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); virt_addr = CHECK_READ_REG15_WA(cpu, Rn); @@ -454,7 +459,7 @@ static void LnSWoUB(RegisterPostIndexed)(ARMul_State* cpu, unsigned int inst, un static void MLnS(ImmediateOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) { unsigned int immedL = BITS(inst, 0, 3); unsigned int immedH = BITS(inst, 8, 11); - unsigned int Rn = BITS(inst, 16, 19); + unsigned int Rn = BITS(inst, 16, 19); unsigned int addr; unsigned int offset_8 = (immedH << 4) | immedL; @@ -470,7 +475,7 @@ static void MLnS(ImmediateOffset)(ARMul_State* cpu, unsigned int inst, unsigned static void MLnS(RegisterOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) { unsigned int addr; unsigned int Rn = BITS(inst, 16, 19); - unsigned int Rm = BITS(inst, 0, 3); + unsigned int Rm = BITS(inst, 0, 3); unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); @@ -482,10 +487,11 @@ static void MLnS(RegisterOffset)(ARMul_State* cpu, unsigned int inst, unsigned i virt_addr = addr; } -static void MLnS(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) { - unsigned int Rn = BITS(inst, 16, 19); - unsigned int immedH = BITS(inst, 8, 11); - unsigned int immedL = BITS(inst, 0, 3); +static void MLnS(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst, + unsigned int& virt_addr) { + unsigned int Rn = BITS(inst, 16, 19); + unsigned int immedH = BITS(inst, 8, 11); + unsigned int immedL = BITS(inst, 0, 3); unsigned int addr; unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); unsigned int offset_8 = (immedH << 4) | immedL; @@ -501,10 +507,11 @@ static void MLnS(ImmediatePreIndexed)(ARMul_State* cpu, unsigned int inst, unsig cpu->Reg[Rn] = addr; } -static void MLnS(ImmediatePostIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) { - unsigned int Rn = BITS(inst, 16, 19); - unsigned int immedH = BITS(inst, 8, 11); - unsigned int immedL = BITS(inst, 0, 3); +static void MLnS(ImmediatePostIndexed)(ARMul_State* cpu, unsigned int inst, + unsigned int& virt_addr) { + unsigned int Rn = BITS(inst, 16, 19); + unsigned int immedH = BITS(inst, 8, 11); + unsigned int immedL = BITS(inst, 0, 3); unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); virt_addr = rn; @@ -520,9 +527,10 @@ static void MLnS(ImmediatePostIndexed)(ARMul_State* cpu, unsigned int inst, unsi } } -static void MLnS(RegisterPostIndexed)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) { +static void MLnS(RegisterPostIndexed)(ARMul_State* cpu, unsigned int inst, + unsigned int& virt_addr) { unsigned int Rn = BITS(inst, 16, 19); - unsigned int Rm = BITS(inst, 0, 3); + unsigned int Rm = BITS(inst, 0, 3); unsigned int rm = CHECK_READ_REG15_WA(cpu, Rm); virt_addr = CHECK_READ_REG15_WA(cpu, Rn); @@ -541,7 +549,8 @@ static void LdnStM(DecrementBefore)(ARMul_State* cpu, unsigned int inst, unsigne int count = 0; while (i) { - if (i & 1) count++; + if (i & 1) + count++; i = i >> 1; } @@ -557,7 +566,8 @@ static void LdnStM(IncrementBefore)(ARMul_State* cpu, unsigned int inst, unsigne int count = 0; while (i) { - if (i & 1) count++; + if (i & 1) + count++; i = i >> 1; } @@ -572,8 +582,9 @@ static void LdnStM(IncrementAfter)(ARMul_State* cpu, unsigned int inst, unsigned unsigned int i = BITS(inst, 0, 15); int count = 0; - while(i) { - if (i & 1) count++; + while (i) { + if (i & 1) + count++; i = i >> 1; } @@ -587,8 +598,9 @@ static void LdnStM(DecrementAfter)(ARMul_State* cpu, unsigned int inst, unsigned unsigned int Rn = BITS(inst, 16, 19); unsigned int i = BITS(inst, 0, 15); int count = 0; - while(i) { - if(i & 1) count++; + while (i) { + if (i & 1) + count++; i = i >> 1; } unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); @@ -601,7 +613,8 @@ static void LdnStM(DecrementAfter)(ARMul_State* cpu, unsigned int inst, unsigned } } -static void LnSWoUB(ScaledRegisterOffset)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr) { +static void LnSWoUB(ScaledRegisterOffset)(ARMul_State* cpu, unsigned int inst, + unsigned int& virt_addr) { unsigned int shift = BITS(inst, 5, 6); unsigned int shift_imm = BITS(inst, 7, 11); unsigned int Rn = BITS(inst, 16, 19); @@ -693,17 +706,23 @@ get_addr_fp_t GetAddressingOp(unsigned int inst) { return LnSWoUB(RegisterPostIndexed); } else if (BITS(inst, 24, 27) == 6 && BIT(inst, 21) == 0 && BIT(inst, 4) == 0) { return LnSWoUB(ScaledRegisterPostIndexed); - } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { + } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && + BIT(inst, 4) == 1) { return MLnS(ImmediateOffset); - } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { + } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && + BIT(inst, 4) == 1) { return MLnS(RegisterOffset); - } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { + } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 3 && BIT(inst, 7) == 1 && + BIT(inst, 4) == 1) { return MLnS(ImmediatePreIndexed); - } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { + } else if (BITS(inst, 24, 27) == 1 && BITS(inst, 21, 22) == 1 && BIT(inst, 7) == 1 && + BIT(inst, 4) == 1) { return MLnS(RegisterPreIndexed); - } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { + } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 2 && BIT(inst, 7) == 1 && + BIT(inst, 4) == 1) { return MLnS(ImmediatePostIndexed); - } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && BIT(inst, 4) == 1) { + } else if (BITS(inst, 24, 27) == 0 && BITS(inst, 21, 22) == 0 && BIT(inst, 7) == 1 && + BIT(inst, 4) == 1) { return MLnS(RegisterPostIndexed); } else if (BITS(inst, 23, 27) == 0x11) { return LdnStM(IncrementAfter); @@ -732,14 +751,12 @@ get_addr_fp_t GetAddressingOpLoadStoreT(unsigned int inst) { return nullptr; } -enum { - FETCH_SUCCESS, - FETCH_FAILURE -}; +enum { FETCH_SUCCESS, FETCH_FAILURE }; -static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_inst, u32* inst_size, ARM_INST_PTR* ptr_inst_base) { +static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_inst, u32* inst_size, + ARM_INST_PTR* ptr_inst_base) { // Check if in Thumb mode - ThumbDecodeStatus ret = TranslateThumbInstruction (addr, inst, arm_inst, inst_size); + ThumbDecodeStatus ret = TranslateThumbInstruction(addr, inst, arm_inst, inst_size); if (ret == ThumbDecodeStatus::BRANCH) { int inst_index; int table_length = arm_instruction_trans_len; @@ -748,7 +765,7 @@ static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_ins switch ((tinstr & 0xF800) >> 11) { case 26: case 27: - if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){ + if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)) { inst_index = table_length - 4; *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); } else { @@ -785,21 +802,21 @@ static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_ins return ret; } -enum { - KEEP_GOING, - FETCH_EXCEPTION -}; +enum { KEEP_GOING, FETCH_EXCEPTION }; MICROPROFILE_DEFINE(DynCom_Decode, "DynCom", "Decode", MP_RGB(255, 64, 64)); -static unsigned int InterpreterTranslateInstruction(const ARMul_State* cpu, const u32 phys_addr, ARM_INST_PTR& inst_base) { +static unsigned int InterpreterTranslateInstruction(const ARMul_State* cpu, const u32 phys_addr, + ARM_INST_PTR& inst_base) { unsigned int inst_size = 4; unsigned int inst = Memory::Read32(phys_addr & 0xFFFFFFFC); - // If we are in Thumb mode, we'll translate one Thumb instruction to the corresponding ARM instruction + // If we are in Thumb mode, we'll translate one Thumb instruction to the corresponding ARM + // instruction if (cpu->TFlag) { u32 arm_inst; - ThumbDecodeStatus state = DecodeThumbInstruction(inst, phys_addr, &arm_inst, &inst_size, &inst_base); + ThumbDecodeStatus state = + DecodeThumbInstruction(inst, phys_addr, &arm_inst, &inst_size, &inst_base); // We have translated the Thumb branch instruction in the Thumb decoder if (state == ThumbDecodeStatus::BRANCH) { @@ -811,8 +828,10 @@ static unsigned int InterpreterTranslateInstruction(const ARMul_State* cpu, cons int idx; if (DecodeARMInstruction(inst, &idx) == ARMDecodeStatus::FAILURE) { std::string disasm = ARM_Disasm::Disassemble(phys_addr, inst); - LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : %s [%x]", phys_addr, disasm.c_str(), inst); - LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]); + LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : %s [%x]", phys_addr, + disasm.c_str(), inst); + LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, + cpu->Reg[15]); CITRA_IGNORE_EXIT(-1); } inst_base = arm_instruction_trans[idx](inst, idx); @@ -875,12 +894,25 @@ static int InterpreterTranslateSingle(ARMul_State* cpu, int& bb_start, u32 addr) static int clz(unsigned int x) { int n; - if (x == 0) return (32); + if (x == 0) + return (32); n = 1; - if ((x >> 16) == 0) { n = n + 16; x = x << 16;} - if ((x >> 24) == 0) { n = n + 8; x = x << 8;} - if ((x >> 28) == 0) { n = n + 4; x = x << 4;} - if ((x >> 30) == 0) { n = n + 2; x = x << 2;} + if ((x >> 16) == 0) { + n = n + 16; + x = x << 16; + } + if ((x >> 24) == 0) { + n = n + 8; + x = x << 8; + } + if ((x >> 28) == 0) { + n = n + 4; + x = x << 4; + } + if ((x >> 30) == 0) { + n = n + 2; + x = x << 2; + } n = n - (x >> 31); return n; } @@ -892,310 +924,698 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { GDBStub::BreakpointAddress breakpoint_data; - #undef RM - #undef RS - - #define CRn inst_cream->crn - #define OPCODE_1 inst_cream->opcode_1 - #define OPCODE_2 inst_cream->opcode_2 - #define CRm inst_cream->crm - #define RD cpu->Reg[inst_cream->Rd] - #define RD2 cpu->Reg[inst_cream->Rd + 1] - #define RN cpu->Reg[inst_cream->Rn] - #define RM cpu->Reg[inst_cream->Rm] - #define RS cpu->Reg[inst_cream->Rs] - #define RDHI cpu->Reg[inst_cream->RdHi] - #define RDLO cpu->Reg[inst_cream->RdLo] - #define LINK_RTN_ADDR (cpu->Reg[14] = cpu->Reg[15] + 4) - #define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24) - #define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand) - - #define FETCH_INST if (inst_base->br != TransExtData::NON_BRANCH) goto DISPATCH; \ - inst_base = (arm_inst *)&trans_cache_buf[ptr] - - #define INC_PC(l) ptr += sizeof(arm_inst) + l - #define INC_PC_STUB ptr += sizeof(arm_inst) - -#define GDB_BP_CHECK \ - cpu->Cpsr &= ~(1 << 5); \ - cpu->Cpsr |= cpu->TFlag << 5; \ - if (GDBStub::g_server_enabled) { \ - if (GDBStub::IsMemoryBreak() || (breakpoint_data.type != GDBStub::BreakpointType::None && PC == breakpoint_data.address)) { \ - GDBStub::Break(); \ - goto END; \ - } \ +#undef RM +#undef RS + +#define CRn inst_cream->crn +#define OPCODE_1 inst_cream->opcode_1 +#define OPCODE_2 inst_cream->opcode_2 +#define CRm inst_cream->crm +#define RD cpu->Reg[inst_cream->Rd] +#define RD2 cpu->Reg[inst_cream->Rd + 1] +#define RN cpu->Reg[inst_cream->Rn] +#define RM cpu->Reg[inst_cream->Rm] +#define RS cpu->Reg[inst_cream->Rs] +#define RDHI cpu->Reg[inst_cream->RdHi] +#define RDLO cpu->Reg[inst_cream->RdLo] +#define LINK_RTN_ADDR (cpu->Reg[14] = cpu->Reg[15] + 4) +#define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24) +#define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand) + +#define FETCH_INST \ + if (inst_base->br != TransExtData::NON_BRANCH) \ + goto DISPATCH; \ + inst_base = (arm_inst*)&trans_cache_buf[ptr] + +#define INC_PC(l) ptr += sizeof(arm_inst) + l +#define INC_PC_STUB ptr += sizeof(arm_inst) + +#define GDB_BP_CHECK \ + cpu->Cpsr &= ~(1 << 5); \ + cpu->Cpsr |= cpu->TFlag << 5; \ + if (GDBStub::g_server_enabled) { \ + if (GDBStub::IsMemoryBreak() || (breakpoint_data.type != GDBStub::BreakpointType::None && \ + PC == breakpoint_data.address)) { \ + GDBStub::Break(); \ + goto END; \ + } \ } // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback to a // clunky switch statement. #if defined __GNUC__ || defined __clang__ -#define GOTO_NEXT_INST \ - GDB_BP_CHECK; \ - if (num_instrs >= cpu->NumInstrsToExecute) goto END; \ - num_instrs++; \ - goto *InstLabel[inst_base->idx] +#define GOTO_NEXT_INST \ + GDB_BP_CHECK; \ + if (num_instrs >= cpu->NumInstrsToExecute) \ + goto END; \ + num_instrs++; \ + goto* InstLabel[inst_base->idx] #else -#define GOTO_NEXT_INST \ - GDB_BP_CHECK; \ - if (num_instrs >= cpu->NumInstrsToExecute) goto END; \ - num_instrs++; \ - switch(inst_base->idx) { \ - case 0: goto VMLA_INST; \ - case 1: goto VMLS_INST; \ - case 2: goto VNMLA_INST; \ - case 3: goto VNMLS_INST; \ - case 4: goto VNMUL_INST; \ - case 5: goto VMUL_INST; \ - case 6: goto VADD_INST; \ - case 7: goto VSUB_INST; \ - case 8: goto VDIV_INST; \ - case 9: goto VMOVI_INST; \ - case 10: goto VMOVR_INST; \ - case 11: goto VABS_INST; \ - case 12: goto VNEG_INST; \ - case 13: goto VSQRT_INST; \ - case 14: goto VCMP_INST; \ - case 15: goto VCMP2_INST; \ - case 16: goto VCVTBDS_INST; \ - case 17: goto VCVTBFF_INST; \ - case 18: goto VCVTBFI_INST; \ - case 19: goto VMOVBRS_INST; \ - case 20: goto VMSR_INST; \ - case 21: goto VMOVBRC_INST; \ - case 22: goto VMRS_INST; \ - case 23: goto VMOVBCR_INST; \ - case 24: goto VMOVBRRSS_INST; \ - case 25: goto VMOVBRRD_INST; \ - case 26: goto VSTR_INST; \ - case 27: goto VPUSH_INST; \ - case 28: goto VSTM_INST; \ - case 29: goto VPOP_INST; \ - case 30: goto VLDR_INST; \ - case 31: goto VLDM_INST ; \ - case 32: goto SRS_INST; \ - case 33: goto RFE_INST; \ - case 34: goto BKPT_INST; \ - case 35: goto BLX_INST; \ - case 36: goto CPS_INST; \ - case 37: goto PLD_INST; \ - case 38: goto SETEND_INST; \ - case 39: goto CLREX_INST; \ - case 40: goto REV16_INST; \ - case 41: goto USAD8_INST; \ - case 42: goto SXTB_INST; \ - case 43: goto UXTB_INST; \ - case 44: goto SXTH_INST; \ - case 45: goto SXTB16_INST; \ - case 46: goto UXTH_INST; \ - case 47: goto UXTB16_INST; \ - case 48: goto CPY_INST; \ - case 49: goto UXTAB_INST; \ - case 50: goto SSUB8_INST; \ - case 51: goto SHSUB8_INST; \ - case 52: goto SSUBADDX_INST; \ - case 53: goto STREX_INST; \ - case 54: goto STREXB_INST; \ - case 55: goto SWP_INST; \ - case 56: goto SWPB_INST; \ - case 57: goto SSUB16_INST; \ - case 58: goto SSAT16_INST; \ - case 59: goto SHSUBADDX_INST; \ - case 60: goto QSUBADDX_INST; \ - case 61: goto SHADDSUBX_INST; \ - case 62: goto SHADD8_INST; \ - case 63: goto SHADD16_INST; \ - case 64: goto SEL_INST; \ - case 65: goto SADDSUBX_INST; \ - case 66: goto SADD8_INST; \ - case 67: goto SADD16_INST; \ - case 68: goto SHSUB16_INST; \ - case 69: goto UMAAL_INST; \ - case 70: goto UXTAB16_INST; \ - case 71: goto USUBADDX_INST; \ - case 72: goto USUB8_INST; \ - case 73: goto USUB16_INST; \ - case 74: goto USAT16_INST; \ - case 75: goto USADA8_INST; \ - case 76: goto UQSUBADDX_INST; \ - case 77: goto UQSUB8_INST; \ - case 78: goto UQSUB16_INST; \ - case 79: goto UQADDSUBX_INST; \ - case 80: goto UQADD8_INST; \ - case 81: goto UQADD16_INST; \ - case 82: goto SXTAB_INST; \ - case 83: goto UHSUBADDX_INST; \ - case 84: goto UHSUB8_INST; \ - case 85: goto UHSUB16_INST; \ - case 86: goto UHADDSUBX_INST; \ - case 87: goto UHADD8_INST; \ - case 88: goto UHADD16_INST; \ - case 89: goto UADDSUBX_INST; \ - case 90: goto UADD8_INST; \ - case 91: goto UADD16_INST; \ - case 92: goto SXTAH_INST; \ - case 93: goto SXTAB16_INST; \ - case 94: goto QADD8_INST; \ - case 95: goto BXJ_INST; \ - case 96: goto CLZ_INST; \ - case 97: goto UXTAH_INST; \ - case 98: goto BX_INST; \ - case 99: goto REV_INST; \ - case 100: goto BLX_INST; \ - case 101: goto REVSH_INST; \ - case 102: goto QADD_INST; \ - case 103: goto QADD16_INST; \ - case 104: goto QADDSUBX_INST; \ - case 105: goto LDREX_INST; \ - case 106: goto QDADD_INST; \ - case 107: goto QDSUB_INST; \ - case 108: goto QSUB_INST; \ - case 109: goto LDREXB_INST; \ - case 110: goto QSUB8_INST; \ - case 111: goto QSUB16_INST; \ - case 112: goto SMUAD_INST; \ - case 113: goto SMMUL_INST; \ - case 114: goto SMUSD_INST; \ - case 115: goto SMLSD_INST; \ - case 116: goto SMLSLD_INST; \ - case 117: goto SMMLA_INST; \ - case 118: goto SMMLS_INST; \ - case 119: goto SMLALD_INST; \ - case 120: goto SMLAD_INST; \ - case 121: goto SMLAW_INST; \ - case 122: goto SMULW_INST; \ - case 123: goto PKHTB_INST; \ - case 124: goto PKHBT_INST; \ - case 125: goto SMUL_INST; \ - case 126: goto SMLALXY_INST; \ - case 127: goto SMLA_INST; \ - case 128: goto MCRR_INST; \ - case 129: goto MRRC_INST; \ - case 130: goto CMP_INST; \ - case 131: goto TST_INST; \ - case 132: goto TEQ_INST; \ - case 133: goto CMN_INST; \ - case 134: goto SMULL_INST; \ - case 135: goto UMULL_INST; \ - case 136: goto UMLAL_INST; \ - case 137: goto SMLAL_INST; \ - case 138: goto MUL_INST; \ - case 139: goto MLA_INST; \ - case 140: goto SSAT_INST; \ - case 141: goto USAT_INST; \ - case 142: goto MRS_INST; \ - case 143: goto MSR_INST; \ - case 144: goto AND_INST; \ - case 145: goto BIC_INST; \ - case 146: goto LDM_INST; \ - case 147: goto EOR_INST; \ - case 148: goto ADD_INST; \ - case 149: goto RSB_INST; \ - case 150: goto RSC_INST; \ - case 151: goto SBC_INST; \ - case 152: goto ADC_INST; \ - case 153: goto SUB_INST; \ - case 154: goto ORR_INST; \ - case 155: goto MVN_INST; \ - case 156: goto MOV_INST; \ - case 157: goto STM_INST; \ - case 158: goto LDM_INST; \ - case 159: goto LDRSH_INST; \ - case 160: goto STM_INST; \ - case 161: goto LDM_INST; \ - case 162: goto LDRSB_INST; \ - case 163: goto STRD_INST; \ - case 164: goto LDRH_INST; \ - case 165: goto STRH_INST; \ - case 166: goto LDRD_INST; \ - case 167: goto STRT_INST; \ - case 168: goto STRBT_INST; \ - case 169: goto LDRBT_INST; \ - case 170: goto LDRT_INST; \ - case 171: goto MRC_INST; \ - case 172: goto MCR_INST; \ - case 173: goto MSR_INST; \ - case 174: goto MSR_INST; \ - case 175: goto MSR_INST; \ - case 176: goto MSR_INST; \ - case 177: goto MSR_INST; \ - case 178: goto LDRB_INST; \ - case 179: goto STRB_INST; \ - case 180: goto LDR_INST; \ - case 181: goto LDRCOND_INST ; \ - case 182: goto STR_INST; \ - case 183: goto CDP_INST; \ - case 184: goto STC_INST; \ - case 185: goto LDC_INST; \ - case 186: goto LDREXD_INST; \ - case 187: goto STREXD_INST; \ - case 188: goto LDREXH_INST; \ - case 189: goto STREXH_INST; \ - case 190: goto NOP_INST; \ - case 191: goto YIELD_INST; \ - case 192: goto WFE_INST; \ - case 193: goto WFI_INST; \ - case 194: goto SEV_INST; \ - case 195: goto SWI_INST; \ - case 196: goto BBL_INST; \ - case 197: goto B_2_THUMB ; \ - case 198: goto B_COND_THUMB ; \ - case 199: goto BL_1_THUMB ; \ - case 200: goto BL_2_THUMB ; \ - case 201: goto BLX_1_THUMB ; \ - case 202: goto DISPATCH; \ - case 203: goto INIT_INST_LENGTH; \ - case 204: goto END; \ +#define GOTO_NEXT_INST \ + GDB_BP_CHECK; \ + if (num_instrs >= cpu->NumInstrsToExecute) \ + goto END; \ + num_instrs++; \ + switch (inst_base->idx) { \ + case 0: \ + goto VMLA_INST; \ + case 1: \ + goto VMLS_INST; \ + case 2: \ + goto VNMLA_INST; \ + case 3: \ + goto VNMLS_INST; \ + case 4: \ + goto VNMUL_INST; \ + case 5: \ + goto VMUL_INST; \ + case 6: \ + goto VADD_INST; \ + case 7: \ + goto VSUB_INST; \ + case 8: \ + goto VDIV_INST; \ + case 9: \ + goto VMOVI_INST; \ + case 10: \ + goto VMOVR_INST; \ + case 11: \ + goto VABS_INST; \ + case 12: \ + goto VNEG_INST; \ + case 13: \ + goto VSQRT_INST; \ + case 14: \ + goto VCMP_INST; \ + case 15: \ + goto VCMP2_INST; \ + case 16: \ + goto VCVTBDS_INST; \ + case 17: \ + goto VCVTBFF_INST; \ + case 18: \ + goto VCVTBFI_INST; \ + case 19: \ + goto VMOVBRS_INST; \ + case 20: \ + goto VMSR_INST; \ + case 21: \ + goto VMOVBRC_INST; \ + case 22: \ + goto VMRS_INST; \ + case 23: \ + goto VMOVBCR_INST; \ + case 24: \ + goto VMOVBRRSS_INST; \ + case 25: \ + goto VMOVBRRD_INST; \ + case 26: \ + goto VSTR_INST; \ + case 27: \ + goto VPUSH_INST; \ + case 28: \ + goto VSTM_INST; \ + case 29: \ + goto VPOP_INST; \ + case 30: \ + goto VLDR_INST; \ + case 31: \ + goto VLDM_INST; \ + case 32: \ + goto SRS_INST; \ + case 33: \ + goto RFE_INST; \ + case 34: \ + goto BKPT_INST; \ + case 35: \ + goto BLX_INST; \ + case 36: \ + goto CPS_INST; \ + case 37: \ + goto PLD_INST; \ + case 38: \ + goto SETEND_INST; \ + case 39: \ + goto CLREX_INST; \ + case 40: \ + goto REV16_INST; \ + case 41: \ + goto USAD8_INST; \ + case 42: \ + goto SXTB_INST; \ + case 43: \ + goto UXTB_INST; \ + case 44: \ + goto SXTH_INST; \ + case 45: \ + goto SXTB16_INST; \ + case 46: \ + goto UXTH_INST; \ + case 47: \ + goto UXTB16_INST; \ + case 48: \ + goto CPY_INST; \ + case 49: \ + goto UXTAB_INST; \ + case 50: \ + goto SSUB8_INST; \ + case 51: \ + goto SHSUB8_INST; \ + case 52: \ + goto SSUBADDX_INST; \ + case 53: \ + goto STREX_INST; \ + case 54: \ + goto STREXB_INST; \ + case 55: \ + goto SWP_INST; \ + case 56: \ + goto SWPB_INST; \ + case 57: \ + goto SSUB16_INST; \ + case 58: \ + goto SSAT16_INST; \ + case 59: \ + goto SHSUBADDX_INST; \ + case 60: \ + goto QSUBADDX_INST; \ + case 61: \ + goto SHADDSUBX_INST; \ + case 62: \ + goto SHADD8_INST; \ + case 63: \ + goto SHADD16_INST; \ + case 64: \ + goto SEL_INST; \ + case 65: \ + goto SADDSUBX_INST; \ + case 66: \ + goto SADD8_INST; \ + case 67: \ + goto SADD16_INST; \ + case 68: \ + goto SHSUB16_INST; \ + case 69: \ + goto UMAAL_INST; \ + case 70: \ + goto UXTAB16_INST; \ + case 71: \ + goto USUBADDX_INST; \ + case 72: \ + goto USUB8_INST; \ + case 73: \ + goto USUB16_INST; \ + case 74: \ + goto USAT16_INST; \ + case 75: \ + goto USADA8_INST; \ + case 76: \ + goto UQSUBADDX_INST; \ + case 77: \ + goto UQSUB8_INST; \ + case 78: \ + goto UQSUB16_INST; \ + case 79: \ + goto UQADDSUBX_INST; \ + case 80: \ + goto UQADD8_INST; \ + case 81: \ + goto UQADD16_INST; \ + case 82: \ + goto SXTAB_INST; \ + case 83: \ + goto UHSUBADDX_INST; \ + case 84: \ + goto UHSUB8_INST; \ + case 85: \ + goto UHSUB16_INST; \ + case 86: \ + goto UHADDSUBX_INST; \ + case 87: \ + goto UHADD8_INST; \ + case 88: \ + goto UHADD16_INST; \ + case 89: \ + goto UADDSUBX_INST; \ + case 90: \ + goto UADD8_INST; \ + case 91: \ + goto UADD16_INST; \ + case 92: \ + goto SXTAH_INST; \ + case 93: \ + goto SXTAB16_INST; \ + case 94: \ + goto QADD8_INST; \ + case 95: \ + goto BXJ_INST; \ + case 96: \ + goto CLZ_INST; \ + case 97: \ + goto UXTAH_INST; \ + case 98: \ + goto BX_INST; \ + case 99: \ + goto REV_INST; \ + case 100: \ + goto BLX_INST; \ + case 101: \ + goto REVSH_INST; \ + case 102: \ + goto QADD_INST; \ + case 103: \ + goto QADD16_INST; \ + case 104: \ + goto QADDSUBX_INST; \ + case 105: \ + goto LDREX_INST; \ + case 106: \ + goto QDADD_INST; \ + case 107: \ + goto QDSUB_INST; \ + case 108: \ + goto QSUB_INST; \ + case 109: \ + goto LDREXB_INST; \ + case 110: \ + goto QSUB8_INST; \ + case 111: \ + goto QSUB16_INST; \ + case 112: \ + goto SMUAD_INST; \ + case 113: \ + goto SMMUL_INST; \ + case 114: \ + goto SMUSD_INST; \ + case 115: \ + goto SMLSD_INST; \ + case 116: \ + goto SMLSLD_INST; \ + case 117: \ + goto SMMLA_INST; \ + case 118: \ + goto SMMLS_INST; \ + case 119: \ + goto SMLALD_INST; \ + case 120: \ + goto SMLAD_INST; \ + case 121: \ + goto SMLAW_INST; \ + case 122: \ + goto SMULW_INST; \ + case 123: \ + goto PKHTB_INST; \ + case 124: \ + goto PKHBT_INST; \ + case 125: \ + goto SMUL_INST; \ + case 126: \ + goto SMLALXY_INST; \ + case 127: \ + goto SMLA_INST; \ + case 128: \ + goto MCRR_INST; \ + case 129: \ + goto MRRC_INST; \ + case 130: \ + goto CMP_INST; \ + case 131: \ + goto TST_INST; \ + case 132: \ + goto TEQ_INST; \ + case 133: \ + goto CMN_INST; \ + case 134: \ + goto SMULL_INST; \ + case 135: \ + goto UMULL_INST; \ + case 136: \ + goto UMLAL_INST; \ + case 137: \ + goto SMLAL_INST; \ + case 138: \ + goto MUL_INST; \ + case 139: \ + goto MLA_INST; \ + case 140: \ + goto SSAT_INST; \ + case 141: \ + goto USAT_INST; \ + case 142: \ + goto MRS_INST; \ + case 143: \ + goto MSR_INST; \ + case 144: \ + goto AND_INST; \ + case 145: \ + goto BIC_INST; \ + case 146: \ + goto LDM_INST; \ + case 147: \ + goto EOR_INST; \ + case 148: \ + goto ADD_INST; \ + case 149: \ + goto RSB_INST; \ + case 150: \ + goto RSC_INST; \ + case 151: \ + goto SBC_INST; \ + case 152: \ + goto ADC_INST; \ + case 153: \ + goto SUB_INST; \ + case 154: \ + goto ORR_INST; \ + case 155: \ + goto MVN_INST; \ + case 156: \ + goto MOV_INST; \ + case 157: \ + goto STM_INST; \ + case 158: \ + goto LDM_INST; \ + case 159: \ + goto LDRSH_INST; \ + case 160: \ + goto STM_INST; \ + case 161: \ + goto LDM_INST; \ + case 162: \ + goto LDRSB_INST; \ + case 163: \ + goto STRD_INST; \ + case 164: \ + goto LDRH_INST; \ + case 165: \ + goto STRH_INST; \ + case 166: \ + goto LDRD_INST; \ + case 167: \ + goto STRT_INST; \ + case 168: \ + goto STRBT_INST; \ + case 169: \ + goto LDRBT_INST; \ + case 170: \ + goto LDRT_INST; \ + case 171: \ + goto MRC_INST; \ + case 172: \ + goto MCR_INST; \ + case 173: \ + goto MSR_INST; \ + case 174: \ + goto MSR_INST; \ + case 175: \ + goto MSR_INST; \ + case 176: \ + goto MSR_INST; \ + case 177: \ + goto MSR_INST; \ + case 178: \ + goto LDRB_INST; \ + case 179: \ + goto STRB_INST; \ + case 180: \ + goto LDR_INST; \ + case 181: \ + goto LDRCOND_INST; \ + case 182: \ + goto STR_INST; \ + case 183: \ + goto CDP_INST; \ + case 184: \ + goto STC_INST; \ + case 185: \ + goto LDC_INST; \ + case 186: \ + goto LDREXD_INST; \ + case 187: \ + goto STREXD_INST; \ + case 188: \ + goto LDREXH_INST; \ + case 189: \ + goto STREXH_INST; \ + case 190: \ + goto NOP_INST; \ + case 191: \ + goto YIELD_INST; \ + case 192: \ + goto WFE_INST; \ + case 193: \ + goto WFI_INST; \ + case 194: \ + goto SEV_INST; \ + case 195: \ + goto SWI_INST; \ + case 196: \ + goto BBL_INST; \ + case 197: \ + goto B_2_THUMB; \ + case 198: \ + goto B_COND_THUMB; \ + case 199: \ + goto BL_1_THUMB; \ + case 200: \ + goto BL_2_THUMB; \ + case 201: \ + goto BLX_1_THUMB; \ + case 202: \ + goto DISPATCH; \ + case 203: \ + goto INIT_INST_LENGTH; \ + case 204: \ + goto END; \ } #endif - #define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0) - #define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1) - #define UPDATE_CFLAG_WITH_SC (cpu->CFlag = cpu->shifter_carry_out) - - #define SAVE_NZCVT cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | \ - (cpu->NFlag << 31) | \ - (cpu->ZFlag << 30) | \ - (cpu->CFlag << 29) | \ - (cpu->VFlag << 28) | \ - (cpu->TFlag << 5) - #define LOAD_NZCVT cpu->NFlag = (cpu->Cpsr >> 31); \ - cpu->ZFlag = (cpu->Cpsr >> 30) & 1; \ - cpu->CFlag = (cpu->Cpsr >> 29) & 1; \ - cpu->VFlag = (cpu->Cpsr >> 28) & 1; \ - cpu->TFlag = (cpu->Cpsr >> 5) & 1; - - #define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE) - #define PC (cpu->Reg[15]) - - // GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback - // to a clunky switch statement. +#define UPDATE_NFLAG(dst) (cpu->NFlag = BIT(dst, 31) ? 1 : 0) +#define UPDATE_ZFLAG(dst) (cpu->ZFlag = dst ? 0 : 1) +#define UPDATE_CFLAG_WITH_SC (cpu->CFlag = cpu->shifter_carry_out) + +#define SAVE_NZCVT \ + cpu->Cpsr = (cpu->Cpsr & 0x0fffffdf) | (cpu->NFlag << 31) | (cpu->ZFlag << 30) | \ + (cpu->CFlag << 29) | (cpu->VFlag << 28) | (cpu->TFlag << 5) +#define LOAD_NZCVT \ + cpu->NFlag = (cpu->Cpsr >> 31); \ + cpu->ZFlag = (cpu->Cpsr >> 30) & 1; \ + cpu->CFlag = (cpu->Cpsr >> 29) & 1; \ + cpu->VFlag = (cpu->Cpsr >> 28) & 1; \ + cpu->TFlag = (cpu->Cpsr >> 5) & 1; + +#define CurrentModeHasSPSR (cpu->Mode != SYSTEM32MODE) && (cpu->Mode != USER32MODE) +#define PC (cpu->Reg[15]) + +// GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback +// to a clunky switch statement. #if defined __GNUC__ || defined __clang__ - void *InstLabel[] = { - &&VMLA_INST, &&VMLS_INST, &&VNMLA_INST, &&VNMLS_INST, &&VNMUL_INST, &&VMUL_INST, &&VADD_INST, &&VSUB_INST, - &&VDIV_INST, &&VMOVI_INST, &&VMOVR_INST, &&VABS_INST, &&VNEG_INST, &&VSQRT_INST, &&VCMP_INST, &&VCMP2_INST, &&VCVTBDS_INST, - &&VCVTBFF_INST, &&VCVTBFI_INST, &&VMOVBRS_INST, &&VMSR_INST, &&VMOVBRC_INST, &&VMRS_INST, &&VMOVBCR_INST, &&VMOVBRRSS_INST, - &&VMOVBRRD_INST, &&VSTR_INST, &&VPUSH_INST, &&VSTM_INST, &&VPOP_INST, &&VLDR_INST, &&VLDM_INST, - - &&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST, - &&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST, - &&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST, - &&SHADD8_INST,&&SHADD16_INST,&&SEL_INST,&&SADDSUBX_INST,&&SADD8_INST,&&SADD16_INST,&&SHSUB16_INST,&&UMAAL_INST,&&UXTAB16_INST, - &&USUBADDX_INST,&&USUB8_INST,&&USUB16_INST,&&USAT16_INST,&&USADA8_INST,&&UQSUBADDX_INST,&&UQSUB8_INST,&&UQSUB16_INST, - &&UQADDSUBX_INST,&&UQADD8_INST,&&UQADD16_INST,&&SXTAB_INST,&&UHSUBADDX_INST,&&UHSUB8_INST,&&UHSUB16_INST,&&UHADDSUBX_INST,&&UHADD8_INST, - &&UHADD16_INST,&&UADDSUBX_INST,&&UADD8_INST,&&UADD16_INST,&&SXTAH_INST,&&SXTAB16_INST,&&QADD8_INST,&&BXJ_INST,&&CLZ_INST,&&UXTAH_INST, - &&BX_INST,&&REV_INST,&&BLX_INST,&&REVSH_INST,&&QADD_INST,&&QADD16_INST,&&QADDSUBX_INST,&&LDREX_INST,&&QDADD_INST,&&QDSUB_INST, - &&QSUB_INST,&&LDREXB_INST,&&QSUB8_INST,&&QSUB16_INST,&&SMUAD_INST,&&SMMUL_INST,&&SMUSD_INST,&&SMLSD_INST,&&SMLSLD_INST,&&SMMLA_INST, - &&SMMLS_INST,&&SMLALD_INST,&&SMLAD_INST,&&SMLAW_INST,&&SMULW_INST,&&PKHTB_INST,&&PKHBT_INST,&&SMUL_INST,&&SMLALXY_INST,&&SMLA_INST, - &&MCRR_INST,&&MRRC_INST,&&CMP_INST,&&TST_INST,&&TEQ_INST,&&CMN_INST,&&SMULL_INST,&&UMULL_INST,&&UMLAL_INST,&&SMLAL_INST,&&MUL_INST, - &&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST, - &&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST, - &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST, - &&MSR_INST, &&MSR_INST, &&MSR_INST, &&MSR_INST, &&MSR_INST, - &&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_INST, &&LDREXD_INST, - &&STREXD_INST,&&LDREXH_INST,&&STREXH_INST, &&NOP_INST, &&YIELD_INST, &&WFE_INST, &&WFI_INST, &&SEV_INST, &&SWI_INST,&&BBL_INST, - &&B_2_THUMB, &&B_COND_THUMB,&&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH, - &&INIT_INST_LENGTH,&&END - }; + void* InstLabel[] = {&&VMLA_INST, + &&VMLS_INST, + &&VNMLA_INST, + &&VNMLS_INST, + &&VNMUL_INST, + &&VMUL_INST, + &&VADD_INST, + &&VSUB_INST, + &&VDIV_INST, + &&VMOVI_INST, + &&VMOVR_INST, + &&VABS_INST, + &&VNEG_INST, + &&VSQRT_INST, + &&VCMP_INST, + &&VCMP2_INST, + &&VCVTBDS_INST, + &&VCVTBFF_INST, + &&VCVTBFI_INST, + &&VMOVBRS_INST, + &&VMSR_INST, + &&VMOVBRC_INST, + &&VMRS_INST, + &&VMOVBCR_INST, + &&VMOVBRRSS_INST, + &&VMOVBRRD_INST, + &&VSTR_INST, + &&VPUSH_INST, + &&VSTM_INST, + &&VPOP_INST, + &&VLDR_INST, + &&VLDM_INST, + + &&SRS_INST, + &&RFE_INST, + &&BKPT_INST, + &&BLX_INST, + &&CPS_INST, + &&PLD_INST, + &&SETEND_INST, + &&CLREX_INST, + &&REV16_INST, + &&USAD8_INST, + &&SXTB_INST, + &&UXTB_INST, + &&SXTH_INST, + &&SXTB16_INST, + &&UXTH_INST, + &&UXTB16_INST, + &&CPY_INST, + &&UXTAB_INST, + &&SSUB8_INST, + &&SHSUB8_INST, + &&SSUBADDX_INST, + &&STREX_INST, + &&STREXB_INST, + &&SWP_INST, + &&SWPB_INST, + &&SSUB16_INST, + &&SSAT16_INST, + &&SHSUBADDX_INST, + &&QSUBADDX_INST, + &&SHADDSUBX_INST, + &&SHADD8_INST, + &&SHADD16_INST, + &&SEL_INST, + &&SADDSUBX_INST, + &&SADD8_INST, + &&SADD16_INST, + &&SHSUB16_INST, + &&UMAAL_INST, + &&UXTAB16_INST, + &&USUBADDX_INST, + &&USUB8_INST, + &&USUB16_INST, + &&USAT16_INST, + &&USADA8_INST, + &&UQSUBADDX_INST, + &&UQSUB8_INST, + &&UQSUB16_INST, + &&UQADDSUBX_INST, + &&UQADD8_INST, + &&UQADD16_INST, + &&SXTAB_INST, + &&UHSUBADDX_INST, + &&UHSUB8_INST, + &&UHSUB16_INST, + &&UHADDSUBX_INST, + &&UHADD8_INST, + &&UHADD16_INST, + &&UADDSUBX_INST, + &&UADD8_INST, + &&UADD16_INST, + &&SXTAH_INST, + &&SXTAB16_INST, + &&QADD8_INST, + &&BXJ_INST, + &&CLZ_INST, + &&UXTAH_INST, + &&BX_INST, + &&REV_INST, + &&BLX_INST, + &&REVSH_INST, + &&QADD_INST, + &&QADD16_INST, + &&QADDSUBX_INST, + &&LDREX_INST, + &&QDADD_INST, + &&QDSUB_INST, + &&QSUB_INST, + &&LDREXB_INST, + &&QSUB8_INST, + &&QSUB16_INST, + &&SMUAD_INST, + &&SMMUL_INST, + &&SMUSD_INST, + &&SMLSD_INST, + &&SMLSLD_INST, + &&SMMLA_INST, + &&SMMLS_INST, + &&SMLALD_INST, + &&SMLAD_INST, + &&SMLAW_INST, + &&SMULW_INST, + &&PKHTB_INST, + &&PKHBT_INST, + &&SMUL_INST, + &&SMLALXY_INST, + &&SMLA_INST, + &&MCRR_INST, + &&MRRC_INST, + &&CMP_INST, + &&TST_INST, + &&TEQ_INST, + &&CMN_INST, + &&SMULL_INST, + &&UMULL_INST, + &&UMLAL_INST, + &&SMLAL_INST, + &&MUL_INST, + &&MLA_INST, + &&SSAT_INST, + &&USAT_INST, + &&MRS_INST, + &&MSR_INST, + &&AND_INST, + &&BIC_INST, + &&LDM_INST, + &&EOR_INST, + &&ADD_INST, + &&RSB_INST, + &&RSC_INST, + &&SBC_INST, + &&ADC_INST, + &&SUB_INST, + &&ORR_INST, + &&MVN_INST, + &&MOV_INST, + &&STM_INST, + &&LDM_INST, + &&LDRSH_INST, + &&STM_INST, + &&LDM_INST, + &&LDRSB_INST, + &&STRD_INST, + &&LDRH_INST, + &&STRH_INST, + &&LDRD_INST, + &&STRT_INST, + &&STRBT_INST, + &&LDRBT_INST, + &&LDRT_INST, + &&MRC_INST, + &&MCR_INST, + &&MSR_INST, + &&MSR_INST, + &&MSR_INST, + &&MSR_INST, + &&MSR_INST, + &&LDRB_INST, + &&STRB_INST, + &&LDR_INST, + &&LDRCOND_INST, + &&STR_INST, + &&CDP_INST, + &&STC_INST, + &&LDC_INST, + &&LDREXD_INST, + &&STREXD_INST, + &&LDREXH_INST, + &&STREXH_INST, + &&NOP_INST, + &&YIELD_INST, + &&WFE_INST, + &&WFI_INST, + &&SEV_INST, + &&SWI_INST, + &&BBL_INST, + &&B_2_THUMB, + &&B_COND_THUMB, + &&BL_1_THUMB, + &&BL_2_THUMB, + &&BLX_1_THUMB, + &&DISPATCH, + &&INIT_INST_LENGTH, + &&END}; #endif arm_inst* inst_base; unsigned int addr; @@ -1204,516 +1624,517 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { int ptr; LOAD_NZCVT; - DISPATCH: - { - if (!cpu->NirqSig) { - if (!(cpu->Cpsr & 0x80)) { - goto END; - } +DISPATCH : { + if (!cpu->NirqSig) { + if (!(cpu->Cpsr & 0x80)) { + goto END; } + } - if (cpu->TFlag) - cpu->Reg[15] &= 0xfffffffe; - else - cpu->Reg[15] &= 0xfffffffc; - - // Find the cached instruction cream, otherwise translate it... - auto itr = cpu->instruction_cache.find(cpu->Reg[15]); - if (itr != cpu->instruction_cache.end()) { - ptr = itr->second; - } else if (cpu->NumInstrsToExecute != 1) { - if (InterpreterTranslateBlock(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION) - goto END; - } else { - if (InterpreterTranslateSingle(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION) - goto END; - } + if (cpu->TFlag) + cpu->Reg[15] &= 0xfffffffe; + else + cpu->Reg[15] &= 0xfffffffc; + + // Find the cached instruction cream, otherwise translate it... + auto itr = cpu->instruction_cache.find(cpu->Reg[15]); + if (itr != cpu->instruction_cache.end()) { + ptr = itr->second; + } else if (cpu->NumInstrsToExecute != 1) { + if (InterpreterTranslateBlock(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION) + goto END; + } else { + if (InterpreterTranslateSingle(cpu, ptr, cpu->Reg[15]) == FETCH_EXCEPTION) + goto END; + } - // Find breakpoint if one exists within the block - if (GDBStub::g_server_enabled && GDBStub::IsConnected()) { - breakpoint_data = GDBStub::GetNextBreakpointFromAddress(cpu->Reg[15], GDBStub::BreakpointType::Execute); - } + // Find breakpoint if one exists within the block + if (GDBStub::g_server_enabled && GDBStub::IsConnected()) { + breakpoint_data = + GDBStub::GetNextBreakpointFromAddress(cpu->Reg[15], GDBStub::BreakpointType::Execute); + } - inst_base = (arm_inst *)&trans_cache_buf[ptr]; - GOTO_NEXT_INST; + inst_base = (arm_inst*)&trans_cache_buf[ptr]; + GOTO_NEXT_INST; +} +ADC_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + adc_inst* const inst_cream = (adc_inst*)inst_base->component; + + u32 rn_val = RN; + if (inst_cream->Rn == 15) + rn_val += 2 * cpu->GetInstructionSize(); + + bool carry; + bool overflow; + RD = AddWithCarry(rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); + + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); + LOAD_NZCVT; + } + } else if (inst_cream->S) { + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); + cpu->CFlag = carry; + cpu->VFlag = overflow; + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(adc_inst)); + goto DISPATCH; + } } - ADC_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - adc_inst* const inst_cream = (adc_inst*)inst_base->component; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(adc_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +ADD_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + add_inst* const inst_cream = (add_inst*)inst_base->component; - u32 rn_val = RN; - if (inst_cream->Rn == 15) - rn_val += 2 * cpu->GetInstructionSize(); + u32 rn_val = CHECK_READ_REG15_WA(cpu, inst_cream->Rn); - bool carry; - bool overflow; - RD = AddWithCarry(rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); + bool carry; + bool overflow; + RD = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow); - if (inst_cream->S && (inst_cream->Rd == 15)) { - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(RD); - UPDATE_ZFLAG(RD); - cpu->CFlag = carry; - cpu->VFlag = overflow; - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(adc_inst)); - goto DISPATCH; + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F); + LOAD_NZCVT; } + } else if (inst_cream->S) { + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); + cpu->CFlag = carry; + cpu->VFlag = overflow; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(adc_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - ADD_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - add_inst* const inst_cream = (add_inst*)inst_base->component; - - u32 rn_val = CHECK_READ_REG15_WA(cpu, inst_cream->Rn); - - bool carry; - bool overflow; - RD = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow); - - if (inst_cream->S && (inst_cream->Rd == 15)) { - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(RD); - UPDATE_ZFLAG(RD); - cpu->CFlag = carry; - cpu->VFlag = overflow; - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(add_inst)); - goto DISPATCH; - } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(add_inst)); + goto DISPATCH; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(add_inst)); - FETCH_INST; - GOTO_NEXT_INST; } - AND_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - and_inst* const inst_cream = (and_inst*)inst_base->component; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(add_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +AND_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + and_inst* const inst_cream = (and_inst*)inst_base->component; - u32 lop = RN; - u32 rop = SHIFTER_OPERAND; + u32 lop = RN; + u32 rop = SHIFTER_OPERAND; - if (inst_cream->Rn == 15) - lop += 2 * cpu->GetInstructionSize(); + if (inst_cream->Rn == 15) + lop += 2 * cpu->GetInstructionSize(); - RD = lop & rop; + RD = lop & rop; - if (inst_cream->S && (inst_cream->Rd == 15)) { - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(RD); - UPDATE_ZFLAG(RD); - UPDATE_CFLAG_WITH_SC; - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(and_inst)); - goto DISPATCH; + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F); + LOAD_NZCVT; } + } else if (inst_cream->S) { + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); + UPDATE_CFLAG_WITH_SC; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(and_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - BBL_INST: - { - if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { - bbl_inst *inst_cream = (bbl_inst *)inst_base->component; - if (inst_cream->L) { - LINK_RTN_ADDR; - } - SET_PC; - INC_PC(sizeof(bbl_inst)); + if (inst_cream->Rd == 15) { + INC_PC(sizeof(and_inst)); goto DISPATCH; } - cpu->Reg[15] += cpu->GetInstructionSize(); + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(and_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +BBL_INST : { + if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { + bbl_inst* inst_cream = (bbl_inst*)inst_base->component; + if (inst_cream->L) { + LINK_RTN_ADDR; + } + SET_PC; INC_PC(sizeof(bbl_inst)); goto DISPATCH; } - BIC_INST: - { - bic_inst *inst_cream = (bic_inst *)inst_base->component; - if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { - u32 lop = RN; - if (inst_cream->Rn == 15) { - lop += 2 * cpu->GetInstructionSize(); - } - u32 rop = SHIFTER_OPERAND; - RD = lop & (~rop); - if ((inst_cream->S) && (inst_cream->Rd == 15)) { - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(RD); - UPDATE_ZFLAG(RD); - UPDATE_CFLAG_WITH_SC; - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(bic_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(bic_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - BKPT_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - bkpt_inst* const inst_cream = (bkpt_inst*)inst_base->component; - LOG_DEBUG(Core_ARM11, "Breakpoint instruction hit. Immediate: 0x%08X", inst_cream->imm); + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(bbl_inst)); + goto DISPATCH; +} +BIC_INST : { + bic_inst* inst_cream = (bic_inst*)inst_base->component; + if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { + u32 lop = RN; + if (inst_cream->Rn == 15) { + lop += 2 * cpu->GetInstructionSize(); } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(bkpt_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - BLX_INST: - { - blx_inst *inst_cream = (blx_inst *)inst_base->component; - if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { - unsigned int inst = inst_cream->inst; - if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { - const u32 jump_address = cpu->Reg[inst_cream->val.Rm]; - cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize()); - if(cpu->TFlag) - cpu->Reg[14] |= 0x1; - cpu->Reg[15] = jump_address & 0xfffffffe; - cpu->TFlag = jump_address & 0x1; - } else { - cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize()); - cpu->TFlag = 0x1; - int signed_int = inst_cream->val.signed_immed_24; - signed_int = (signed_int & 0x800000) ? (0x3F000000 | signed_int) : signed_int; - signed_int = signed_int << 2; - cpu->Reg[15] = cpu->Reg[15] + 8 + signed_int + (BIT(inst, 24) << 1); + u32 rop = SHIFTER_OPERAND; + RD = lop & (~rop); + if ((inst_cream->S) && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); + LOAD_NZCVT; } - INC_PC(sizeof(blx_inst)); + } else if (inst_cream->S) { + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); + UPDATE_CFLAG_WITH_SC; + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(bic_inst)); goto DISPATCH; } - cpu->Reg[15] += cpu->GetInstructionSize(); + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(bic_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +BKPT_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + bkpt_inst* const inst_cream = (bkpt_inst*)inst_base->component; + LOG_DEBUG(Core_ARM11, "Breakpoint instruction hit. Immediate: 0x%08X", inst_cream->imm); + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(bkpt_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +BLX_INST : { + blx_inst* inst_cream = (blx_inst*)inst_base->component; + if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { + unsigned int inst = inst_cream->inst; + if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { + const u32 jump_address = cpu->Reg[inst_cream->val.Rm]; + cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize()); + if (cpu->TFlag) + cpu->Reg[14] |= 0x1; + cpu->Reg[15] = jump_address & 0xfffffffe; + cpu->TFlag = jump_address & 0x1; + } else { + cpu->Reg[14] = (cpu->Reg[15] + cpu->GetInstructionSize()); + cpu->TFlag = 0x1; + int signed_int = inst_cream->val.signed_immed_24; + signed_int = (signed_int & 0x800000) ? (0x3F000000 | signed_int) : signed_int; + signed_int = signed_int << 2; + cpu->Reg[15] = cpu->Reg[15] + 8 + signed_int + (BIT(inst, 24) << 1); + } INC_PC(sizeof(blx_inst)); goto DISPATCH; } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(blx_inst)); + goto DISPATCH; +} - BX_INST: - BXJ_INST: - { - // Note that only the 'fail' case of BXJ is emulated. This is because - // the facilities for Jazelle emulation are not implemented. - // - // According to the ARM documentation on BXJ, if setting the J bit in the APSR - // fails, then BXJ functions identically like a regular BX instruction. - // - // This is sufficient for citra, as the CPU for the 3DS does not implement Jazelle. - - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - bx_inst* const inst_cream = (bx_inst*)inst_base->component; +BX_INST: +BXJ_INST : { + // Note that only the 'fail' case of BXJ is emulated. This is because + // the facilities for Jazelle emulation are not implemented. + // + // According to the ARM documentation on BXJ, if setting the J bit in the APSR + // fails, then BXJ functions identically like a regular BX instruction. + // + // This is sufficient for citra, as the CPU for the 3DS does not implement Jazelle. - u32 address = RM; + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + bx_inst* const inst_cream = (bx_inst*)inst_base->component; - if (inst_cream->Rm == 15) - address += 2 * cpu->GetInstructionSize(); + u32 address = RM; - cpu->TFlag = address & 1; - cpu->Reg[15] = address & 0xfffffffe; - INC_PC(sizeof(bx_inst)); - goto DISPATCH; - } + if (inst_cream->Rm == 15) + address += 2 * cpu->GetInstructionSize(); - cpu->Reg[15] += cpu->GetInstructionSize(); + cpu->TFlag = address & 1; + cpu->Reg[15] = address & 0xfffffffe; INC_PC(sizeof(bx_inst)); goto DISPATCH; } - CDP_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - // Undefined instruction here - cpu->NumInstrsToExecute = 0; - return num_instrs; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(bx_inst)); + goto DISPATCH; +} + +CDP_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + // Undefined instruction here + cpu->NumInstrsToExecute = 0; + return num_instrs; + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(cdp_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} + +CLREX_INST : { + cpu->UnsetExclusiveMemoryAddress(); + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(clrex_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +CLZ_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + clz_inst* inst_cream = (clz_inst*)inst_base->component; + RD = clz(RM); + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(clz_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +CMN_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + cmn_inst* const inst_cream = (cmn_inst*)inst_base->component; + + u32 rn_val = RN; + if (inst_cream->Rn == 15) + rn_val += 2 * cpu->GetInstructionSize(); + + bool carry; + bool overflow; + u32 result = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow); + + UPDATE_NFLAG(result); + UPDATE_ZFLAG(result); + cpu->CFlag = carry; + cpu->VFlag = overflow; + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(cmn_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +CMP_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + cmp_inst* const inst_cream = (cmp_inst*)inst_base->component; + + u32 rn_val = RN; + if (inst_cream->Rn == 15) + rn_val += 2 * cpu->GetInstructionSize(); + + bool carry; + bool overflow; + u32 result = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow); + + UPDATE_NFLAG(result); + UPDATE_ZFLAG(result); + cpu->CFlag = carry; + cpu->VFlag = overflow; + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(cmp_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +CPS_INST : { + cps_inst* inst_cream = (cps_inst*)inst_base->component; + u32 aif_val = 0; + u32 aif_mask = 0; + if (cpu->InAPrivilegedMode()) { + if (inst_cream->imod1) { + if (inst_cream->A) { + aif_val |= (inst_cream->imod0 << 8); + aif_mask |= 1 << 8; + } + if (inst_cream->I) { + aif_val |= (inst_cream->imod0 << 7); + aif_mask |= 1 << 7; + } + if (inst_cream->F) { + aif_val |= (inst_cream->imod0 << 6); + aif_mask |= 1 << 6; + } + aif_mask = ~aif_mask; + cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(cdp_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - - CLREX_INST: - { - cpu->UnsetExclusiveMemoryAddress(); - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(clrex_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - CLZ_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - clz_inst* inst_cream = (clz_inst*)inst_base->component; - RD = clz(RM); + if (inst_cream->mmod) { + cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode; + cpu->ChangePrivilegeMode(inst_cream->mode); } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(clz_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - CMN_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - cmn_inst* const inst_cream = (cmn_inst*)inst_base->component; - - u32 rn_val = RN; - if (inst_cream->Rn == 15) - rn_val += 2 * cpu->GetInstructionSize(); - - bool carry; - bool overflow; - u32 result = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow); - - UPDATE_NFLAG(result); - UPDATE_ZFLAG(result); - cpu->CFlag = carry; - cpu->VFlag = overflow; + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(cps_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +CPY_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + mov_inst* inst_cream = (mov_inst*)inst_base->component; + + RD = SHIFTER_OPERAND; + if (inst_cream->Rd == 15) { + INC_PC(sizeof(mov_inst)); + goto DISPATCH; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(cmn_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - CMP_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - cmp_inst* const inst_cream = (cmp_inst*)inst_base->component; - - u32 rn_val = RN; - if (inst_cream->Rn == 15) - rn_val += 2 * cpu->GetInstructionSize(); - - bool carry; - bool overflow; - u32 result = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow); - - UPDATE_NFLAG(result); - UPDATE_ZFLAG(result); - cpu->CFlag = carry; - cpu->VFlag = overflow; + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(mov_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +EOR_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + eor_inst* inst_cream = (eor_inst*)inst_base->component; + + u32 lop = RN; + if (inst_cream->Rn == 15) { + lop += 2 * cpu->GetInstructionSize(); } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(cmp_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - CPS_INST: - { - cps_inst *inst_cream = (cps_inst *)inst_base->component; - u32 aif_val = 0; - u32 aif_mask = 0; - if (cpu->InAPrivilegedMode()) { - if (inst_cream->imod1) { - if (inst_cream->A) { - aif_val |= (inst_cream->imod0 << 8); - aif_mask |= 1 << 8; - } - if (inst_cream->I) { - aif_val |= (inst_cream->imod0 << 7); - aif_mask |= 1 << 7; - } - if (inst_cream->F) { - aif_val |= (inst_cream->imod0 << 6); - aif_mask |= 1 << 6; - } - aif_mask = ~aif_mask; - cpu->Cpsr = (cpu->Cpsr & aif_mask) | aif_val; - } - if (inst_cream->mmod) { - cpu->Cpsr = (cpu->Cpsr & 0xffffffe0) | inst_cream->mode; - cpu->ChangePrivilegeMode(inst_cream->mode); + u32 rop = SHIFTER_OPERAND; + RD = lop ^ rop; + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); + LOAD_NZCVT; } + } else if (inst_cream->S) { + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); + UPDATE_CFLAG_WITH_SC; + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(eor_inst)); + goto DISPATCH; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(cps_inst)); - FETCH_INST; - GOTO_NEXT_INST; } - CPY_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - mov_inst* inst_cream = (mov_inst*)inst_base->component; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(eor_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +LDC_INST : { + // Instruction not implemented + // LOG_CRITICAL(Core_ARM11, "unimplemented instruction"); + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ldc_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +LDM_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; + inst_cream->get_addr(cpu, inst_cream->inst, addr); - RD = SHIFTER_OPERAND; - if (inst_cream->Rd == 15) { - INC_PC(sizeof(mov_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(mov_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - EOR_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - eor_inst* inst_cream = (eor_inst*)inst_base->component; - - u32 lop = RN; - if (inst_cream->Rn == 15) { - lop += 2 * cpu->GetInstructionSize(); - } - u32 rop = SHIFTER_OPERAND; - RD = lop ^ rop; - if (inst_cream->S && (inst_cream->Rd == 15)) { - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); - LOAD_NZCVT; + unsigned int inst = inst_cream->inst; + if (BIT(inst, 22) && !BIT(inst, 15)) { + for (int i = 0; i < 13; i++) { + if (BIT(inst, i)) { + cpu->Reg[i] = cpu->ReadMemory32(addr); + addr += 4; } - } else if (inst_cream->S) { - UPDATE_NFLAG(RD); - UPDATE_ZFLAG(RD); - UPDATE_CFLAG_WITH_SC; } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(eor_inst)); - goto DISPATCH; + if (BIT(inst, 13)) { + if (cpu->Mode == USER32MODE) + cpu->Reg[13] = cpu->ReadMemory32(addr); + else + cpu->Reg_usr[0] = cpu->ReadMemory32(addr); + + addr += 4; } - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(eor_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDC_INST: - { - // Instruction not implemented - //LOG_CRITICAL(Core_ARM11, "unimplemented instruction"); - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ldc_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDM_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - ldst_inst* inst_cream = (ldst_inst*)inst_base->component; - inst_cream->get_addr(cpu, inst_cream->inst, addr); - - unsigned int inst = inst_cream->inst; - if (BIT(inst, 22) && !BIT(inst, 15)) { - for (int i = 0; i < 13; i++) { - if(BIT(inst, i)) { - cpu->Reg[i] = cpu->ReadMemory32(addr); - addr += 4; + if (BIT(inst, 14)) { + if (cpu->Mode == USER32MODE) + cpu->Reg[14] = cpu->ReadMemory32(addr); + else + cpu->Reg_usr[1] = cpu->ReadMemory32(addr); + + addr += 4; + } + } else if (!BIT(inst, 22)) { + for (int i = 0; i < 16; i++) { + if (BIT(inst, i)) { + unsigned int ret = cpu->ReadMemory32(addr); + + // For armv5t, should enter thumb when bits[0] is non-zero. + if (i == 15) { + cpu->TFlag = ret & 0x1; + ret &= 0xFFFFFFFE; } - } - if (BIT(inst, 13)) { - if (cpu->Mode == USER32MODE) - cpu->Reg[13] = cpu->ReadMemory32(addr); - else - cpu->Reg_usr[0] = cpu->ReadMemory32(addr); + cpu->Reg[i] = ret; addr += 4; } - if (BIT(inst, 14)) { - if (cpu->Mode == USER32MODE) - cpu->Reg[14] = cpu->ReadMemory32(addr); - else - cpu->Reg_usr[1] = cpu->ReadMemory32(addr); - + } + } else if (BIT(inst, 22) && BIT(inst, 15)) { + for (int i = 0; i < 15; i++) { + if (BIT(inst, i)) { + cpu->Reg[i] = cpu->ReadMemory32(addr); addr += 4; } - } else if (!BIT(inst, 22)) { - for(int i = 0; i < 16; i++ ){ - if(BIT(inst, i)){ - unsigned int ret = cpu->ReadMemory32(addr); - - // For armv5t, should enter thumb when bits[0] is non-zero. - if(i == 15){ - cpu->TFlag = ret & 0x1; - ret &= 0xFFFFFFFE; - } - - cpu->Reg[i] = ret; - addr += 4; - } - } - } else if (BIT(inst, 22) && BIT(inst, 15)) { - for(int i = 0; i < 15; i++ ){ - if(BIT(inst, i)){ - cpu->Reg[i] = cpu->ReadMemory32(addr); - addr += 4; - } - } - - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F); - LOAD_NZCVT; - } - - cpu->Reg[15] = cpu->ReadMemory32(addr); } - if (BIT(inst, 15)) { - INC_PC(sizeof(ldst_inst)); - goto DISPATCH; + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F); + LOAD_NZCVT; } + + cpu->Reg[15] = cpu->ReadMemory32(addr); + } + + if (BIT(inst, 15)) { + INC_PC(sizeof(ldst_inst)); + goto DISPATCH; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; } - SXTH_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - sxth_inst* inst_cream = (sxth_inst*)inst_base->component; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +SXTH_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + sxth_inst* inst_cream = (sxth_inst*)inst_base->component; - unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate); - if (BIT(operand2, 15)) { - operand2 |= 0xffff0000; - } else { - operand2 &= 0xffff; - } - RD = operand2; + unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate); + if (BIT(operand2, 15)) { + operand2 |= 0xffff0000; + } else { + operand2 &= 0xffff; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(sxth_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDR_INST: - { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; + RD = operand2; + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(sxth_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +LDR_INST : { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; + inst_cream->get_addr(cpu, inst_cream->inst, addr); + + unsigned int value = cpu->ReadMemory32(addr); + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; + + if (BITS(inst_cream->inst, 12, 15) == 15) { + // For armv5t, should enter thumb when bits[0] is non-zero. + cpu->TFlag = value & 0x1; + cpu->Reg[15] &= 0xFFFFFFFE; + INC_PC(sizeof(ldst_inst)); + goto DISPATCH; + } + + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +LDRCOND_INST : { + if (CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_cream->get_addr(cpu, inst_cream->inst, addr); unsigned int value = cpu->ReadMemory32(addr); @@ -1726,2546 +2147,2433 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) { INC_PC(sizeof(ldst_inst)); goto DISPATCH; } + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +UXTH_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + uxth_inst* inst_cream = (uxth_inst*)inst_base->component; + RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff; + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(uxth_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +UXTAH_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + uxtah_inst* inst_cream = (uxtah_inst*)inst_base->component; + unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff; - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDRCOND_INST: - { - if (CondPassed(cpu, inst_base->cond)) { - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; - inst_cream->get_addr(cpu, inst_cream->inst, addr); - - unsigned int value = cpu->ReadMemory32(addr); - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; - - if (BITS(inst_cream->inst, 12, 15) == 15) { - // For armv5t, should enter thumb when bits[0] is non-zero. - cpu->TFlag = value & 0x1; - cpu->Reg[15] &= 0xFFFFFFFE; - INC_PC(sizeof(ldst_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - UXTH_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - uxth_inst* inst_cream = (uxth_inst*)inst_base->component; - RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff; - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(uxth_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - UXTAH_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - uxtah_inst* inst_cream = (uxtah_inst*)inst_base->component; - unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff; - - RD = RN + operand2; - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(uxtah_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDRB_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - ldst_inst* inst_cream = (ldst_inst*)inst_base->component; - inst_cream->get_addr(cpu, inst_cream->inst, addr); - - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory8(addr); - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; + RD = RN + operand2; + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(uxtah_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +LDRB_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; + inst_cream->get_addr(cpu, inst_cream->inst, addr); + + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory8(addr); } - LDRBT_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - ldst_inst* inst_cream = (ldst_inst*)inst_base->component; - inst_cream->get_addr(cpu, inst_cream->inst, addr); + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +LDRBT_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; + inst_cream->get_addr(cpu, inst_cream->inst, addr); - const u32 dest_index = BITS(inst_cream->inst, 12, 15); - const u32 previous_mode = cpu->Mode; + const u32 dest_index = BITS(inst_cream->inst, 12, 15); + const u32 previous_mode = cpu->Mode; - cpu->ChangePrivilegeMode(USER32MODE); - const u8 value = cpu->ReadMemory8(addr); - cpu->ChangePrivilegeMode(previous_mode); + cpu->ChangePrivilegeMode(USER32MODE); + const u8 value = cpu->ReadMemory8(addr); + cpu->ChangePrivilegeMode(previous_mode); - cpu->Reg[dest_index] = value; - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDRD_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - ldst_inst* inst_cream = (ldst_inst*)inst_base->component; - // Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || addr[2] == 0) - inst_cream->get_addr(cpu, inst_cream->inst, addr); - - // The 3DS doesn't have LPAE (Large Physical Access Extension), so it - // wouldn't do this as a single read. - cpu->Reg[BITS(inst_cream->inst, 12, 15) + 0] = cpu->ReadMemory32(addr); - cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = cpu->ReadMemory32(addr + 4); - - // No dispatch since this operation should not modify R15 - } - cpu->Reg[15] += 4; - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; + cpu->Reg[dest_index] = value; } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +LDRD_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; + // Should check if RD is even-numbered, Rd != 14, addr[0:1] == 0, (CP15_reg1_U == 1 || + // addr[2] == 0) + inst_cream->get_addr(cpu, inst_cream->inst, addr); - LDREX_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; - unsigned int read_addr = RN; - - cpu->SetExclusiveMemoryAddress(read_addr); + // The 3DS doesn't have LPAE (Large Physical Access Extension), so it + // wouldn't do this as a single read. + cpu->Reg[BITS(inst_cream->inst, 12, 15) + 0] = cpu->ReadMemory32(addr); + cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1] = cpu->ReadMemory32(addr + 4); - RD = cpu->ReadMemory32(read_addr); - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(generic_arm_inst)); - FETCH_INST; - GOTO_NEXT_INST; + // No dispatch since this operation should not modify R15 } - LDREXB_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; - unsigned int read_addr = RN; + cpu->Reg[15] += 4; + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - cpu->SetExclusiveMemoryAddress(read_addr); +LDREX_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; + unsigned int read_addr = RN; - RD = cpu->ReadMemory8(read_addr); - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(generic_arm_inst)); - FETCH_INST; - GOTO_NEXT_INST; + cpu->SetExclusiveMemoryAddress(read_addr); + + RD = cpu->ReadMemory32(read_addr); } - LDREXH_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; - unsigned int read_addr = RN; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +LDREXB_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; + unsigned int read_addr = RN; - cpu->SetExclusiveMemoryAddress(read_addr); + cpu->SetExclusiveMemoryAddress(read_addr); - RD = cpu->ReadMemory16(read_addr); - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(generic_arm_inst)); - FETCH_INST; - GOTO_NEXT_INST; + RD = cpu->ReadMemory8(read_addr); } - LDREXD_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; - unsigned int read_addr = RN; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +LDREXH_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; + unsigned int read_addr = RN; - cpu->SetExclusiveMemoryAddress(read_addr); + cpu->SetExclusiveMemoryAddress(read_addr); - RD = cpu->ReadMemory32(read_addr); - RD2 = cpu->ReadMemory32(read_addr + 4); - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(generic_arm_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDRH_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - ldst_inst* inst_cream = (ldst_inst*)inst_base->component; - inst_cream->get_addr(cpu, inst_cream->inst, addr); - - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory16(addr); - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDRSB_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - ldst_inst* inst_cream = (ldst_inst*)inst_base->component; - inst_cream->get_addr(cpu, inst_cream->inst, addr); - unsigned int value = cpu->ReadMemory8(addr); - if (BIT(value, 7)) { - value |= 0xffffff00; - } - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - LDRSH_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - ldst_inst* inst_cream = (ldst_inst*)inst_base->component; - inst_cream->get_addr(cpu, inst_cream->inst, addr); - - unsigned int value = cpu->ReadMemory16(addr); - if (BIT(value, 15)) { - value |= 0xffff0000; - } - cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; + RD = cpu->ReadMemory16(read_addr); } - LDRT_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - ldst_inst* inst_cream = (ldst_inst*)inst_base->component; - inst_cream->get_addr(cpu, inst_cream->inst, addr); + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +LDREXD_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; + unsigned int read_addr = RN; - const u32 dest_index = BITS(inst_cream->inst, 12, 15); - const u32 previous_mode = cpu->Mode; + cpu->SetExclusiveMemoryAddress(read_addr); - cpu->ChangePrivilegeMode(USER32MODE); - const u32 value = cpu->ReadMemory32(addr); - cpu->ChangePrivilegeMode(previous_mode); + RD = cpu->ReadMemory32(read_addr); + RD2 = cpu->ReadMemory32(read_addr + 4); + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +LDRH_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; + inst_cream->get_addr(cpu, inst_cream->inst, addr); - cpu->Reg[dest_index] = value; + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = cpu->ReadMemory16(addr); + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +LDRSB_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; + inst_cream->get_addr(cpu, inst_cream->inst, addr); + unsigned int value = cpu->ReadMemory8(addr); + if (BIT(value, 7)) { + value |= 0xffffff00; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; } - MCR_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - mcr_inst* inst_cream = (mcr_inst*)inst_base->component; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +LDRSH_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; + inst_cream->get_addr(cpu, inst_cream->inst, addr); - unsigned int inst = inst_cream->inst; - if (inst_cream->Rd == 15) { - DEBUG_MSG; - } else { - if (inst_cream->cp_num == 15) - cpu->WriteCP15Register(RD, CRn, OPCODE_1, CRm, OPCODE_2); - } + unsigned int value = cpu->ReadMemory16(addr); + if (BIT(value, 15)) { + value |= 0xffff0000; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(mcr_inst)); - FETCH_INST; - GOTO_NEXT_INST; + cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +LDRT_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; + inst_cream->get_addr(cpu, inst_cream->inst, addr); - MCRR_INST: - { - // Stubbed, as the MPCore doesn't have any registers that are accessible - // through this instruction. - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - mcrr_inst* const inst_cream = (mcrr_inst*)inst_base->component; + const u32 dest_index = BITS(inst_cream->inst, 12, 15); + const u32 previous_mode = cpu->Mode; - LOG_ERROR(Core_ARM11, "MCRR executed | Coprocessor: %u, CRm %u, opc1: %u, Rt: %u, Rt2: %u", - inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, inst_cream->rt2); + cpu->ChangePrivilegeMode(USER32MODE); + const u32 value = cpu->ReadMemory32(addr); + cpu->ChangePrivilegeMode(previous_mode); + + cpu->Reg[dest_index] = value; + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +MCR_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + mcr_inst* inst_cream = (mcr_inst*)inst_base->component; + + unsigned int inst = inst_cream->inst; + if (inst_cream->Rd == 15) { + DEBUG_MSG; + } else { + if (inst_cream->cp_num == 15) + cpu->WriteCP15Register(RD, CRn, OPCODE_1, CRm, OPCODE_2); } + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(mcr_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} + +MCRR_INST : { + // Stubbed, as the MPCore doesn't have any registers that are accessible + // through this instruction. + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + mcrr_inst* const inst_cream = (mcrr_inst*)inst_base->component; - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(mcrr_inst)); - FETCH_INST; - GOTO_NEXT_INST; + LOG_ERROR(Core_ARM11, "MCRR executed | Coprocessor: %u, CRm %u, opc1: %u, Rt: %u, Rt2: %u", + inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, + inst_cream->rt2); } - MLA_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - mla_inst* inst_cream = (mla_inst*)inst_base->component; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(mcrr_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - u64 rm = RM; - u64 rs = RS; - u64 rn = RN; +MLA_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + mla_inst* inst_cream = (mla_inst*)inst_base->component; - RD = static_cast<u32>((rm * rs + rn) & 0xffffffff); - if (inst_cream->S) { - UPDATE_NFLAG(RD); - UPDATE_ZFLAG(RD); - } + u64 rm = RM; + u64 rs = RS; + u64 rn = RN; + + RD = static_cast<u32>((rm * rs + rn) & 0xffffffff); + if (inst_cream->S) { + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(mla_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - MOV_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - mov_inst* inst_cream = (mov_inst*)inst_base->component; - - RD = SHIFTER_OPERAND; - if (inst_cream->S && (inst_cream->Rd == 15)) { - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(RD); - UPDATE_ZFLAG(RD); - UPDATE_CFLAG_WITH_SC; - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(mov_inst)); - goto DISPATCH; + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(mla_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +MOV_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + mov_inst* inst_cream = (mov_inst*)inst_base->component; + + RD = SHIFTER_OPERAND; + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); + LOAD_NZCVT; } + } else if (inst_cream->S) { + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); + UPDATE_CFLAG_WITH_SC; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(mov_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - MRC_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - mrc_inst* inst_cream = (mrc_inst*)inst_base->component; - - if (inst_cream->cp_num == 15) { - const uint32_t value = cpu->ReadCP15Register(CRn, OPCODE_1, CRm, OPCODE_2); - - if (inst_cream->Rd == 15) { - cpu->Cpsr = (cpu->Cpsr & ~0xF0000000) | (value & 0xF0000000); - LOAD_NZCVT; - } else { - RD = value; - } - } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(mov_inst)); + goto DISPATCH; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(mrc_inst)); - FETCH_INST; - GOTO_NEXT_INST; } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(mov_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +MRC_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + mrc_inst* inst_cream = (mrc_inst*)inst_base->component; - MRRC_INST: - { - // Stubbed, as the MPCore doesn't have any registers that are accessible - // through this instruction. - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - mcrr_inst* const inst_cream = (mcrr_inst*)inst_base->component; + if (inst_cream->cp_num == 15) { + const uint32_t value = cpu->ReadCP15Register(CRn, OPCODE_1, CRm, OPCODE_2); - LOG_ERROR(Core_ARM11, "MRRC executed | Coprocessor: %u, CRm %u, opc1: %u, Rt: %u, Rt2: %u", - inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, inst_cream->rt2); + if (inst_cream->Rd == 15) { + cpu->Cpsr = (cpu->Cpsr & ~0xF0000000) | (value & 0xF0000000); + LOAD_NZCVT; + } else { + RD = value; + } } + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(mrc_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(mcrr_inst)); - FETCH_INST; - GOTO_NEXT_INST; +MRRC_INST : { + // Stubbed, as the MPCore doesn't have any registers that are accessible + // through this instruction. + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + mcrr_inst* const inst_cream = (mcrr_inst*)inst_base->component; + + LOG_ERROR(Core_ARM11, "MRRC executed | Coprocessor: %u, CRm %u, opc1: %u, Rt: %u, Rt2: %u", + inst_cream->cp_num, inst_cream->crm, inst_cream->opcode_1, inst_cream->rt, + inst_cream->rt2); } - MRS_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - mrs_inst* inst_cream = (mrs_inst*)inst_base->component; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(mcrr_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - if (inst_cream->R) { - RD = cpu->Spsr_copy; - } else { - SAVE_NZCVT; - RD = cpu->Cpsr; - } +MRS_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + mrs_inst* inst_cream = (mrs_inst*)inst_base->component; + + if (inst_cream->R) { + RD = cpu->Spsr_copy; + } else { + SAVE_NZCVT; + RD = cpu->Cpsr; + } + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(mrs_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +MSR_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + msr_inst* inst_cream = (msr_inst*)inst_base->component; + const u32 UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020; + unsigned int inst = inst_cream->inst; + unsigned int operand; + + if (BIT(inst, 25)) { + int rot_imm = BITS(inst, 8, 11) * 2; + operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm); + } else { + operand = cpu->Reg[BITS(inst, 0, 3)]; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(mrs_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - MSR_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - msr_inst* inst_cream = (msr_inst*)inst_base->component; - const u32 UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020; - unsigned int inst = inst_cream->inst; - unsigned int operand; - - if (BIT(inst, 25)) { - int rot_imm = BITS(inst, 8, 11) * 2; - operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm); + u32 byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0) | + (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0); + u32 mask = 0; + if (!inst_cream->R) { + if (cpu->InAPrivilegedMode()) { + if ((operand & StateMask) != 0) { + /// UNPREDICTABLE + DEBUG_MSG; + } else + mask = byte_mask & (UserMask | PrivMask); } else { - operand = cpu->Reg[BITS(inst, 0, 3)]; + mask = byte_mask & UserMask; } - u32 byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0) - | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0); - u32 mask = 0; - if (!inst_cream->R) { - if (cpu->InAPrivilegedMode()) { - if ((operand & StateMask) != 0) { - /// UNPREDICTABLE - DEBUG_MSG; - } else - mask = byte_mask & (UserMask | PrivMask); - } else { - mask = byte_mask & UserMask; - } - SAVE_NZCVT; + SAVE_NZCVT; - cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask); - cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F); - LOAD_NZCVT; - } else { - if (CurrentModeHasSPSR) { - mask = byte_mask & (UserMask | PrivMask | StateMask); - cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask); - } + cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask); + cpu->ChangePrivilegeMode(cpu->Cpsr & 0x1F); + LOAD_NZCVT; + } else { + if (CurrentModeHasSPSR) { + mask = byte_mask & (UserMask | PrivMask | StateMask); + cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask); } } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(msr_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - MUL_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - mul_inst* inst_cream = (mul_inst*)inst_base->component; - - u64 rm = RM; - u64 rs = RS; - RD = static_cast<u32>((rm * rs) & 0xffffffff); - if (inst_cream->S) { - UPDATE_NFLAG(RD); - UPDATE_ZFLAG(RD); - } + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(msr_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +MUL_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + mul_inst* inst_cream = (mul_inst*)inst_base->component; + + u64 rm = RM; + u64 rs = RS; + RD = static_cast<u32>((rm * rs) & 0xffffffff); + if (inst_cream->S) { + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(mul_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - MVN_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - mvn_inst* const inst_cream = (mvn_inst*)inst_base->component; - - RD = ~SHIFTER_OPERAND; - - if (inst_cream->S && (inst_cream->Rd == 15)) { - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(RD); - UPDATE_ZFLAG(RD); - UPDATE_CFLAG_WITH_SC; - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(mvn_inst)); - goto DISPATCH; + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(mul_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +MVN_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + mvn_inst* const inst_cream = (mvn_inst*)inst_base->component; + + RD = ~SHIFTER_OPERAND; + + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); + LOAD_NZCVT; } + } else if (inst_cream->S) { + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); + UPDATE_CFLAG_WITH_SC; + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(mvn_inst)); + goto DISPATCH; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(mvn_inst)); - FETCH_INST; - GOTO_NEXT_INST; } - ORR_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - orr_inst* const inst_cream = (orr_inst*)inst_base->component; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(mvn_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +ORR_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + orr_inst* const inst_cream = (orr_inst*)inst_base->component; - u32 lop = RN; - u32 rop = SHIFTER_OPERAND; + u32 lop = RN; + u32 rop = SHIFTER_OPERAND; - if (inst_cream->Rn == 15) - lop += 2 * cpu->GetInstructionSize(); + if (inst_cream->Rn == 15) + lop += 2 * cpu->GetInstructionSize(); - RD = lop | rop; + RD = lop | rop; - if (inst_cream->S && (inst_cream->Rd == 15)) { - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(RD); - UPDATE_ZFLAG(RD); - UPDATE_CFLAG_WITH_SC; - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(orr_inst)); - goto DISPATCH; + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); + LOAD_NZCVT; } + } else if (inst_cream->S) { + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); + UPDATE_CFLAG_WITH_SC; + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(orr_inst)); + goto DISPATCH; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(orr_inst)); - FETCH_INST; - GOTO_NEXT_INST; } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(orr_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - NOP_INST: - { - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC_STUB; - FETCH_INST; - GOTO_NEXT_INST; +NOP_INST : { + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC_STUB; + FETCH_INST; + GOTO_NEXT_INST; +} + +PKHBT_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + pkh_inst* inst_cream = (pkh_inst*)inst_base->component; + RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000); } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(pkh_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - PKHBT_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - pkh_inst *inst_cream = (pkh_inst *)inst_base->component; - RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000); - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(pkh_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - - PKHTB_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - pkh_inst *inst_cream = (pkh_inst *)inst_base->component; - int shift_imm = inst_cream->imm ? inst_cream->imm : 31; - RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000); - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(pkh_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - - PLD_INST: - { - // Not implemented. PLD is a hint instruction, so it's optional. - - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(pld_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - - QADD_INST: - QDADD_INST: - QDSUB_INST: - QSUB_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; - const u8 op1 = inst_cream->op1; - const u32 rm_val = RM; - const u32 rn_val = RN; +PKHTB_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + pkh_inst* inst_cream = (pkh_inst*)inst_base->component; + int shift_imm = inst_cream->imm ? inst_cream->imm : 31; + RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000); + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(pkh_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - u32 result = 0; +PLD_INST : { + // Not implemented. PLD is a hint instruction, so it's optional. - // QADD - if (op1 == 0x00) { - result = rm_val + rn_val; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(pld_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - if (AddOverflow(rm_val, rn_val, result)) { - result = POS(result) ? 0x80000000 : 0x7FFFFFFF; - cpu->Cpsr |= (1 << 27); - } - } - // QSUB - else if (op1 == 0x01) { - result = rm_val - rn_val; +QADD_INST: +QDADD_INST: +QDSUB_INST: +QSUB_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; + const u8 op1 = inst_cream->op1; + const u32 rm_val = RM; + const u32 rn_val = RN; - if (SubOverflow(rm_val, rn_val, result)) { - result = POS(result) ? 0x80000000 : 0x7FFFFFFF; - cpu->Cpsr |= (1 << 27); - } - } - // QDADD - else if (op1 == 0x02) { - u32 mul = (rn_val * 2); + u32 result = 0; - if (AddOverflow(rn_val, rn_val, rn_val * 2)) { - mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF; - cpu->Cpsr |= (1 << 27); - } + // QADD + if (op1 == 0x00) { + result = rm_val + rn_val; - result = mul + rm_val; + if (AddOverflow(rm_val, rn_val, result)) { + result = POS(result) ? 0x80000000 : 0x7FFFFFFF; + cpu->Cpsr |= (1 << 27); + } + } + // QSUB + else if (op1 == 0x01) { + result = rm_val - rn_val; - if (AddOverflow(rm_val, mul, result)) { - result = POS(result) ? 0x80000000 : 0x7FFFFFFF; - cpu->Cpsr |= (1 << 27); - } + if (SubOverflow(rm_val, rn_val, result)) { + result = POS(result) ? 0x80000000 : 0x7FFFFFFF; + cpu->Cpsr |= (1 << 27); } - // QDSUB - else if (op1 == 0x03) { - u32 mul = (rn_val * 2); + } + // QDADD + else if (op1 == 0x02) { + u32 mul = (rn_val * 2); - if (AddOverflow(rn_val, rn_val, mul)) { - mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF; - cpu->Cpsr |= (1 << 27); - } + if (AddOverflow(rn_val, rn_val, rn_val * 2)) { + mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF; + cpu->Cpsr |= (1 << 27); + } - result = rm_val - mul; + result = mul + rm_val; - if (SubOverflow(rm_val, mul, result)) { - result = POS(result) ? 0x80000000 : 0x7FFFFFFF; - cpu->Cpsr |= (1 << 27); - } + if (AddOverflow(rm_val, mul, result)) { + result = POS(result) ? 0x80000000 : 0x7FFFFFFF; + cpu->Cpsr |= (1 << 27); } - - RD = result; } + // QDSUB + else if (op1 == 0x03) { + u32 mul = (rn_val * 2); - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(generic_arm_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - - QADD8_INST: - QADD16_INST: - QADDSUBX_INST: - QSUB8_INST: - QSUB16_INST: - QSUBADDX_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; - const u16 rm_lo = (RM & 0xFFFF); - const u16 rm_hi = ((RM >> 16) & 0xFFFF); - const u16 rn_lo = (RN & 0xFFFF); - const u16 rn_hi = ((RN >> 16) & 0xFFFF); - const u8 op2 = inst_cream->op2; - - u16 lo_result = 0; - u16 hi_result = 0; - - // QADD16 - if (op2 == 0x00) { - lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo); - hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi); - } - // QASX - else if (op2 == 0x01) { - lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi); - hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo); - } - // QSAX - else if (op2 == 0x02) { - lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi); - hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo); - } - // QSUB16 - else if (op2 == 0x03) { - lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo); - hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi); - } - // QADD8 - else if (op2 == 0x04) { - lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) | - ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8; - hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) | - ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8; + if (AddOverflow(rn_val, rn_val, mul)) { + mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF; + cpu->Cpsr |= (1 << 27); } - // QSUB8 - else if (op2 == 0x07) { - lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) | - ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8; - hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) | - ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8; + + result = rm_val - mul; + + if (SubOverflow(rm_val, mul, result)) { + result = POS(result) ? 0x80000000 : 0x7FFFFFFF; + cpu->Cpsr |= (1 << 27); } + } - RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); + RD = result; + } + + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} + +QADD8_INST: +QADD16_INST: +QADDSUBX_INST: +QSUB8_INST: +QSUB16_INST: +QSUBADDX_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; + const u16 rm_lo = (RM & 0xFFFF); + const u16 rm_hi = ((RM >> 16) & 0xFFFF); + const u16 rn_lo = (RN & 0xFFFF); + const u16 rn_hi = ((RN >> 16) & 0xFFFF); + const u8 op2 = inst_cream->op2; + + u16 lo_result = 0; + u16 hi_result = 0; + + // QADD16 + if (op2 == 0x00) { + lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_lo); + hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_hi); + } + // QASX + else if (op2 == 0x01) { + lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_hi); + hi_result = ARMul_SignedSaturatedAdd16(rn_hi, rm_lo); + } + // QSAX + else if (op2 == 0x02) { + lo_result = ARMul_SignedSaturatedAdd16(rn_lo, rm_hi); + hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_lo); + } + // QSUB16 + else if (op2 == 0x03) { + lo_result = ARMul_SignedSaturatedSub16(rn_lo, rm_lo); + hi_result = ARMul_SignedSaturatedSub16(rn_hi, rm_hi); + } + // QADD8 + else if (op2 == 0x04) { + lo_result = ARMul_SignedSaturatedAdd8(rn_lo & 0xFF, rm_lo & 0xFF) | + ARMul_SignedSaturatedAdd8(rn_lo >> 8, rm_lo >> 8) << 8; + hi_result = ARMul_SignedSaturatedAdd8(rn_hi & 0xFF, rm_hi & 0xFF) | + ARMul_SignedSaturatedAdd8(rn_hi >> 8, rm_hi >> 8) << 8; + } + // QSUB8 + else if (op2 == 0x07) { + lo_result = ARMul_SignedSaturatedSub8(rn_lo & 0xFF, rm_lo & 0xFF) | + ARMul_SignedSaturatedSub8(rn_lo >> 8, rm_lo >> 8) << 8; + hi_result = ARMul_SignedSaturatedSub8(rn_hi & 0xFF, rm_hi & 0xFF) | + ARMul_SignedSaturatedSub8(rn_hi >> 8, rm_hi >> 8) << 8; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(generic_arm_inst)); - FETCH_INST; - GOTO_NEXT_INST; + RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); } - REV_INST: - REV16_INST: - REVSH_INST: - { + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - rev_inst* const inst_cream = (rev_inst*)inst_base->component; +REV_INST: +REV16_INST: +REVSH_INST : { - const u8 op1 = inst_cream->op1; - const u8 op2 = inst_cream->op2; + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + rev_inst* const inst_cream = (rev_inst*)inst_base->component; - // REV - if (op1 == 0x03 && op2 == 0x01) { - RD = ((RM & 0xFF) << 24) | (((RM >> 8) & 0xFF) << 16) | (((RM >> 16) & 0xFF) << 8) | ((RM >> 24) & 0xFF); - } - // REV16 - else if (op1 == 0x03 && op2 == 0x05) { - RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8) | ((RM & 0xFF0000) << 8) | ((RM & 0xFF000000) >> 8); - } - // REVSH - else if (op1 == 0x07 && op2 == 0x05) { - RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8); - if (RD & 0x8000) - RD |= 0xffff0000; - } - } + const u8 op1 = inst_cream->op1; + const u8 op2 = inst_cream->op2; - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(rev_inst)); - FETCH_INST; - GOTO_NEXT_INST; + // REV + if (op1 == 0x03 && op2 == 0x01) { + RD = ((RM & 0xFF) << 24) | (((RM >> 8) & 0xFF) << 16) | (((RM >> 16) & 0xFF) << 8) | + ((RM >> 24) & 0xFF); + } + // REV16 + else if (op1 == 0x03 && op2 == 0x05) { + RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8) | ((RM & 0xFF0000) << 8) | + ((RM & 0xFF000000) >> 8); + } + // REVSH + else if (op1 == 0x07 && op2 == 0x05) { + RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8); + if (RD & 0x8000) + RD |= 0xffff0000; + } } - RFE_INST: - { - // RFE is unconditional - ldst_inst* const inst_cream = (ldst_inst*)inst_base->component; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(rev_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - u32 address = 0; - inst_cream->get_addr(cpu, inst_cream->inst, address); +RFE_INST : { + // RFE is unconditional + ldst_inst* const inst_cream = (ldst_inst*)inst_base->component; - cpu->Cpsr = cpu->ReadMemory32(address); - cpu->Reg[15] = cpu->ReadMemory32(address + 4); + u32 address = 0; + inst_cream->get_addr(cpu, inst_cream->inst, address); - INC_PC(sizeof(ldst_inst)); - goto DISPATCH; - } + cpu->Cpsr = cpu->ReadMemory32(address); + cpu->Reg[15] = cpu->ReadMemory32(address + 4); + + INC_PC(sizeof(ldst_inst)); + goto DISPATCH; +} - RSB_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - rsb_inst* const inst_cream = (rsb_inst*)inst_base->component; +RSB_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + rsb_inst* const inst_cream = (rsb_inst*)inst_base->component; - u32 rn_val = RN; - if (inst_cream->Rn == 15) - rn_val += 2 * cpu->GetInstructionSize(); + u32 rn_val = RN; + if (inst_cream->Rn == 15) + rn_val += 2 * cpu->GetInstructionSize(); - bool carry; - bool overflow; - RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, 1, &carry, &overflow); + bool carry; + bool overflow; + RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, 1, &carry, &overflow); - if (inst_cream->S && (inst_cream->Rd == 15)) { - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(RD); - UPDATE_ZFLAG(RD); - cpu->CFlag = carry; - cpu->VFlag = overflow; + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); + LOAD_NZCVT; } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(rsb_inst)); - goto DISPATCH; + } else if (inst_cream->S) { + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); + cpu->CFlag = carry; + cpu->VFlag = overflow; + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(rsb_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(rsb_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +RSC_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + rsc_inst* const inst_cream = (rsc_inst*)inst_base->component; + + u32 rn_val = RN; + if (inst_cream->Rn == 15) + rn_val += 2 * cpu->GetInstructionSize(); + + bool carry; + bool overflow; + RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); + + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); + LOAD_NZCVT; } + } else if (inst_cream->S) { + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); + cpu->CFlag = carry; + cpu->VFlag = overflow; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(rsb_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - RSC_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - rsc_inst* const inst_cream = (rsc_inst*)inst_base->component; - - u32 rn_val = RN; - if (inst_cream->Rn == 15) - rn_val += 2 * cpu->GetInstructionSize(); - - bool carry; - bool overflow; - RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); - - if (inst_cream->S && (inst_cream->Rd == 15)) { - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(RD); - UPDATE_ZFLAG(RD); - cpu->CFlag = carry; - cpu->VFlag = overflow; + if (inst_cream->Rd == 15) { + INC_PC(sizeof(rsc_inst)); + goto DISPATCH; + } + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(rsc_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} + +SADD8_INST: +SSUB8_INST: +SADD16_INST: +SADDSUBX_INST: +SSUBADDX_INST: +SSUB16_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; + const u8 op2 = inst_cream->op2; + + if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) { + const s16 rn_lo = (RN & 0xFFFF); + const s16 rn_hi = ((RN >> 16) & 0xFFFF); + const s16 rm_lo = (RM & 0xFFFF); + const s16 rm_hi = ((RM >> 16) & 0xFFFF); + + s32 lo_result = 0; + s32 hi_result = 0; + + // SADD16 + if (inst_cream->op2 == 0x00) { + lo_result = (rn_lo + rm_lo); + hi_result = (rn_hi + rm_hi); } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(rsc_inst)); - goto DISPATCH; + // SASX + else if (op2 == 0x01) { + lo_result = (rn_lo - rm_hi); + hi_result = (rn_hi + rm_lo); + } + // SSAX + else if (op2 == 0x02) { + lo_result = (rn_lo + rm_hi); + hi_result = (rn_hi - rm_lo); + } + // SSUB16 + else if (op2 == 0x03) { + lo_result = (rn_lo - rm_lo); + hi_result = (rn_hi - rm_hi); } - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(rsc_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - - SADD8_INST: - SSUB8_INST: - SADD16_INST: - SADDSUBX_INST: - SSUBADDX_INST: - SSUB16_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; - const u8 op2 = inst_cream->op2; - - if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) { - const s16 rn_lo = (RN & 0xFFFF); - const s16 rn_hi = ((RN >> 16) & 0xFFFF); - const s16 rm_lo = (RM & 0xFFFF); - const s16 rm_hi = ((RM >> 16) & 0xFFFF); - - s32 lo_result = 0; - s32 hi_result = 0; - - // SADD16 - if (inst_cream->op2 == 0x00) { - lo_result = (rn_lo + rm_lo); - hi_result = (rn_hi + rm_hi); - } - // SASX - else if (op2 == 0x01) { - lo_result = (rn_lo - rm_hi); - hi_result = (rn_hi + rm_lo); - } - // SSAX - else if (op2 == 0x02) { - lo_result = (rn_lo + rm_hi); - hi_result = (rn_hi - rm_lo); - } - // SSUB16 - else if (op2 == 0x03) { - lo_result = (rn_lo - rm_lo); - hi_result = (rn_hi - rm_hi); - } - RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); + RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); - if (lo_result >= 0) { - cpu->Cpsr |= (1 << 16); - cpu->Cpsr |= (1 << 17); - } else { - cpu->Cpsr &= ~(1 << 16); - cpu->Cpsr &= ~(1 << 17); - } + if (lo_result >= 0) { + cpu->Cpsr |= (1 << 16); + cpu->Cpsr |= (1 << 17); + } else { + cpu->Cpsr &= ~(1 << 16); + cpu->Cpsr &= ~(1 << 17); + } - if (hi_result >= 0) { - cpu->Cpsr |= (1 << 18); - cpu->Cpsr |= (1 << 19); - } else { - cpu->Cpsr &= ~(1 << 18); - cpu->Cpsr &= ~(1 << 19); - } + if (hi_result >= 0) { + cpu->Cpsr |= (1 << 18); + cpu->Cpsr |= (1 << 19); + } else { + cpu->Cpsr &= ~(1 << 18); + cpu->Cpsr &= ~(1 << 19); + } + } else if (op2 == 0x04 || op2 == 0x07) { + s32 lo_val1, lo_val2; + s32 hi_val1, hi_val2; + + // SADD8 + if (op2 == 0x04) { + lo_val1 = (s32)(s8)(RN & 0xFF) + (s32)(s8)(RM & 0xFF); + lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) + (s32)(s8)((RM >> 8) & 0xFF); + hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) + (s32)(s8)((RM >> 16) & 0xFF); + hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) + (s32)(s8)((RM >> 24) & 0xFF); + } + // SSUB8 + else { + lo_val1 = (s32)(s8)(RN & 0xFF) - (s32)(s8)(RM & 0xFF); + lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) - (s32)(s8)((RM >> 8) & 0xFF); + hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) - (s32)(s8)((RM >> 16) & 0xFF); + hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) - (s32)(s8)((RM >> 24) & 0xFF); } - else if (op2 == 0x04 || op2 == 0x07) { - s32 lo_val1, lo_val2; - s32 hi_val1, hi_val2; - - // SADD8 - if (op2 == 0x04) { - lo_val1 = (s32)(s8)(RN & 0xFF) + (s32)(s8)(RM & 0xFF); - lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) + (s32)(s8)((RM >> 8) & 0xFF); - hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) + (s32)(s8)((RM >> 16) & 0xFF); - hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) + (s32)(s8)((RM >> 24) & 0xFF); - } - // SSUB8 - else { - lo_val1 = (s32)(s8)(RN & 0xFF) - (s32)(s8)(RM & 0xFF); - lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) - (s32)(s8)((RM >> 8) & 0xFF); - hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) - (s32)(s8)((RM >> 16) & 0xFF); - hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) - (s32)(s8)((RM >> 24) & 0xFF); - } - RD = ((lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) | ((hi_val2 & 0xFF) << 24)); + RD = ((lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) | + ((hi_val2 & 0xFF) << 24)); - if (lo_val1 >= 0) - cpu->Cpsr |= (1 << 16); - else - cpu->Cpsr &= ~(1 << 16); + if (lo_val1 >= 0) + cpu->Cpsr |= (1 << 16); + else + cpu->Cpsr &= ~(1 << 16); - if (lo_val2 >= 0) - cpu->Cpsr |= (1 << 17); - else - cpu->Cpsr &= ~(1 << 17); + if (lo_val2 >= 0) + cpu->Cpsr |= (1 << 17); + else + cpu->Cpsr &= ~(1 << 17); - if (hi_val1 >= 0) - cpu->Cpsr |= (1 << 18); - else - cpu->Cpsr &= ~(1 << 18); + if (hi_val1 >= 0) + cpu->Cpsr |= (1 << 18); + else + cpu->Cpsr &= ~(1 << 18); - if (hi_val2 >= 0) - cpu->Cpsr |= (1 << 19); - else - cpu->Cpsr &= ~(1 << 19); - } + if (hi_val2 >= 0) + cpu->Cpsr |= (1 << 19); + else + cpu->Cpsr &= ~(1 << 19); } - - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(generic_arm_inst)); - FETCH_INST; - GOTO_NEXT_INST; } - SBC_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - sbc_inst* const inst_cream = (sbc_inst*)inst_base->component; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - u32 rn_val = RN; - if (inst_cream->Rn == 15) - rn_val += 2 * cpu->GetInstructionSize(); +SBC_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + sbc_inst* const inst_cream = (sbc_inst*)inst_base->component; - bool carry; - bool overflow; - RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); + u32 rn_val = RN; + if (inst_cream->Rn == 15) + rn_val += 2 * cpu->GetInstructionSize(); - if (inst_cream->S && (inst_cream->Rd == 15)) { - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(RD); - UPDATE_ZFLAG(RD); - cpu->CFlag = carry; - cpu->VFlag = overflow; - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(sbc_inst)); - goto DISPATCH; + bool carry; + bool overflow; + RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); + + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); + LOAD_NZCVT; } + } else if (inst_cream->S) { + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); + cpu->CFlag = carry; + cpu->VFlag = overflow; + } + if (inst_cream->Rd == 15) { + INC_PC(sizeof(sbc_inst)); + goto DISPATCH; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(sbc_inst)); - FETCH_INST; - GOTO_NEXT_INST; } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(sbc_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - SEL_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; +SEL_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; - const u32 to = RM; - const u32 from = RN; - const u32 cpsr = cpu->Cpsr; + const u32 to = RM; + const u32 from = RN; + const u32 cpsr = cpu->Cpsr; - u32 result; - if (cpsr & (1 << 16)) - result = from & 0xff; - else - result = to & 0xff; - - if (cpsr & (1 << 17)) - result |= from & 0x0000ff00; - else - result |= to & 0x0000ff00; + u32 result; + if (cpsr & (1 << 16)) + result = from & 0xff; + else + result = to & 0xff; - if (cpsr & (1 << 18)) - result |= from & 0x00ff0000; - else - result |= to & 0x00ff0000; + if (cpsr & (1 << 17)) + result |= from & 0x0000ff00; + else + result |= to & 0x0000ff00; - if (cpsr & (1 << 19)) - result |= from & 0xff000000; - else - result |= to & 0xff000000; + if (cpsr & (1 << 18)) + result |= from & 0x00ff0000; + else + result |= to & 0x00ff0000; - RD = result; - } + if (cpsr & (1 << 19)) + result |= from & 0xff000000; + else + result |= to & 0xff000000; - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(generic_arm_inst)); - FETCH_INST; - GOTO_NEXT_INST; + RD = result; } - SETEND_INST: - { - // SETEND is unconditional - setend_inst* const inst_cream = (setend_inst*)inst_base->component; - const bool big_endian = (inst_cream->set_bigend == 1); + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - if (big_endian) - cpu->Cpsr |= (1 << 9); - else - cpu->Cpsr &= ~(1 << 9); +SETEND_INST : { + // SETEND is unconditional + setend_inst* const inst_cream = (setend_inst*)inst_base->component; + const bool big_endian = (inst_cream->set_bigend == 1); - LOG_WARNING(Core_ARM11, "SETEND %s executed", big_endian ? "BE" : "LE"); + if (big_endian) + cpu->Cpsr |= (1 << 9); + else + cpu->Cpsr &= ~(1 << 9); - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(setend_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } + LOG_WARNING(Core_ARM11, "SETEND %s executed", big_endian ? "BE" : "LE"); - SEV_INST: - { - // Stubbed, as SEV is a hint instruction. - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - LOG_TRACE(Core_ARM11, "SEV executed."); - } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(setend_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC_STUB; - FETCH_INST; - GOTO_NEXT_INST; +SEV_INST : { + // Stubbed, as SEV is a hint instruction. + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + LOG_TRACE(Core_ARM11, "SEV executed."); } - SHADD8_INST: - SHADD16_INST: - SHADDSUBX_INST: - SHSUB8_INST: - SHSUB16_INST: - SHSUBADDX_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC_STUB; + FETCH_INST; + GOTO_NEXT_INST; +} - const u8 op2 = inst_cream->op2; - const u32 rm_val = RM; - const u32 rn_val = RN; +SHADD8_INST: +SHADD16_INST: +SHADDSUBX_INST: +SHSUB8_INST: +SHSUB16_INST: +SHSUBADDX_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; - if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) { - s32 lo_result = 0; - s32 hi_result = 0; + const u8 op2 = inst_cream->op2; + const u32 rm_val = RM; + const u32 rn_val = RN; - // SHADD16 - if (op2 == 0x00) { - lo_result = ((s16)(rn_val & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1; - hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1; - } - // SHASX - else if (op2 == 0x01) { - lo_result = ((s16)(rn_val & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1; - hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1; - } - // SHSAX - else if (op2 == 0x02) { - lo_result = ((s16)(rn_val & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1; - hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1; - } - // SHSUB16 - else if (op2 == 0x03) { - lo_result = ((s16)(rn_val & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1; - hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1; - } + if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) { + s32 lo_result = 0; + s32 hi_result = 0; - RD = ((lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16)); + // SHADD16 + if (op2 == 0x00) { + lo_result = ((s16)(rn_val & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1; + hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1; + } + // SHASX + else if (op2 == 0x01) { + lo_result = ((s16)(rn_val & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1; + hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1; + } + // SHSAX + else if (op2 == 0x02) { + lo_result = ((s16)(rn_val & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1; + hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1; + } + // SHSUB16 + else if (op2 == 0x03) { + lo_result = ((s16)(rn_val & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1; + hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1; } - else if (op2 == 0x04 || op2 == 0x07) { - s16 lo_val1, lo_val2; - s16 hi_val1, hi_val2; - - // SHADD8 - if (op2 == 0x04) { - lo_val1 = ((s8)(rn_val & 0xFF) + (s8)(rm_val & 0xFF)) >> 1; - lo_val2 = ((s8)((rn_val >> 8) & 0xFF) + (s8)((rm_val >> 8) & 0xFF)) >> 1; - hi_val1 = ((s8)((rn_val >> 16) & 0xFF) + (s8)((rm_val >> 16) & 0xFF)) >> 1; - hi_val2 = ((s8)((rn_val >> 24) & 0xFF) + (s8)((rm_val >> 24) & 0xFF)) >> 1; - } - // SHSUB8 - else { - lo_val1 = ((s8)(rn_val & 0xFF) - (s8)(rm_val & 0xFF)) >> 1; - lo_val2 = ((s8)((rn_val >> 8) & 0xFF) - (s8)((rm_val >> 8) & 0xFF)) >> 1; + RD = ((lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16)); + } else if (op2 == 0x04 || op2 == 0x07) { + s16 lo_val1, lo_val2; + s16 hi_val1, hi_val2; - hi_val1 = ((s8)((rn_val >> 16) & 0xFF) - (s8)((rm_val >> 16) & 0xFF)) >> 1; - hi_val2 = ((s8)((rn_val >> 24) & 0xFF) - (s8)((rm_val >> 24) & 0xFF)) >> 1; - } + // SHADD8 + if (op2 == 0x04) { + lo_val1 = ((s8)(rn_val & 0xFF) + (s8)(rm_val & 0xFF)) >> 1; + lo_val2 = ((s8)((rn_val >> 8) & 0xFF) + (s8)((rm_val >> 8) & 0xFF)) >> 1; - RD = (lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) | ((hi_val2 & 0xFF) << 24); + hi_val1 = ((s8)((rn_val >> 16) & 0xFF) + (s8)((rm_val >> 16) & 0xFF)) >> 1; + hi_val2 = ((s8)((rn_val >> 24) & 0xFF) + (s8)((rm_val >> 24) & 0xFF)) >> 1; } - } - - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(generic_arm_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - - SMLA_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - smla_inst* inst_cream = (smla_inst*)inst_base->component; - s32 operand1, operand2; - if (inst_cream->x == 0) - operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); - else - operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31); + // SHSUB8 + else { + lo_val1 = ((s8)(rn_val & 0xFF) - (s8)(rm_val & 0xFF)) >> 1; + lo_val2 = ((s8)((rn_val >> 8) & 0xFF) - (s8)((rm_val >> 8) & 0xFF)) >> 1; - if (inst_cream->y == 0) - operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15); - else - operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); + hi_val1 = ((s8)((rn_val >> 16) & 0xFF) - (s8)((rm_val >> 16) & 0xFF)) >> 1; + hi_val2 = ((s8)((rn_val >> 24) & 0xFF) - (s8)((rm_val >> 24) & 0xFF)) >> 1; + } - u32 product = operand1 * operand2; - u32 result = product + RN; - if (AddOverflow(product, RN, result)) - cpu->Cpsr |= (1 << 27); - RD = result; + RD = (lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) | + ((hi_val2 & 0xFF) << 24); } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(smla_inst)); - FETCH_INST; - GOTO_NEXT_INST; } - SMLAD_INST: - SMLSD_INST: - SMUAD_INST: - SMUSD_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - smlad_inst* const inst_cream = (smlad_inst*)inst_base->component; - const u8 op2 = inst_cream->op2; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} + +SMLA_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + smla_inst* inst_cream = (smla_inst*)inst_base->component; + s32 operand1, operand2; + if (inst_cream->x == 0) + operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); + else + operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31); - u32 rm_val = cpu->Reg[inst_cream->Rm]; - const u32 rn_val = cpu->Reg[inst_cream->Rn]; + if (inst_cream->y == 0) + operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15); + else + operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); + + u32 product = operand1 * operand2; + u32 result = product + RN; + if (AddOverflow(product, RN, result)) + cpu->Cpsr |= (1 << 27); + RD = result; + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(smla_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - if (inst_cream->m) - rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16)); +SMLAD_INST: +SMLSD_INST: +SMUAD_INST: +SMUSD_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + smlad_inst* const inst_cream = (smlad_inst*)inst_base->component; + const u8 op2 = inst_cream->op2; - const s16 rm_lo = (rm_val & 0xFFFF); - const s16 rm_hi = ((rm_val >> 16) & 0xFFFF); - const s16 rn_lo = (rn_val & 0xFFFF); - const s16 rn_hi = ((rn_val >> 16) & 0xFFFF); + u32 rm_val = cpu->Reg[inst_cream->Rm]; + const u32 rn_val = cpu->Reg[inst_cream->Rn]; - const u32 product1 = (rn_lo * rm_lo); - const u32 product2 = (rn_hi * rm_hi); + if (inst_cream->m) + rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16)); - // SMUAD and SMLAD - if (BIT(op2, 1) == 0) { - u32 rd_val = (product1 + product2); + const s16 rm_lo = (rm_val & 0xFFFF); + const s16 rm_hi = ((rm_val >> 16) & 0xFFFF); + const s16 rn_lo = (rn_val & 0xFFFF); + const s16 rn_hi = ((rn_val >> 16) & 0xFFFF); - if (inst_cream->Ra != 15) { - rd_val += cpu->Reg[inst_cream->Ra]; + const u32 product1 = (rn_lo * rm_lo); + const u32 product2 = (rn_hi * rm_hi); - if (ARMul_AddOverflowQ(product1 + product2, cpu->Reg[inst_cream->Ra])) - cpu->Cpsr |= (1 << 27); - } + // SMUAD and SMLAD + if (BIT(op2, 1) == 0) { + u32 rd_val = (product1 + product2); - RD = rd_val; + if (inst_cream->Ra != 15) { + rd_val += cpu->Reg[inst_cream->Ra]; - if (ARMul_AddOverflowQ(product1, product2)) + if (ARMul_AddOverflowQ(product1 + product2, cpu->Reg[inst_cream->Ra])) cpu->Cpsr |= (1 << 27); } - // SMUSD and SMLSD - else { - u32 rd_val = (product1 - product2); - if (inst_cream->Ra != 15) { - rd_val += cpu->Reg[inst_cream->Ra]; + RD = rd_val; - if (ARMul_AddOverflowQ(product1 - product2, cpu->Reg[inst_cream->Ra])) - cpu->Cpsr |= (1 << 27); - } + if (ARMul_AddOverflowQ(product1, product2)) + cpu->Cpsr |= (1 << 27); + } + // SMUSD and SMLSD + else { + u32 rd_val = (product1 - product2); + + if (inst_cream->Ra != 15) { + rd_val += cpu->Reg[inst_cream->Ra]; - RD = rd_val; + if (ARMul_AddOverflowQ(product1 - product2, cpu->Reg[inst_cream->Ra])) + cpu->Cpsr |= (1 << 27); } - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(smlad_inst)); - FETCH_INST; - GOTO_NEXT_INST; + RD = rd_val; + } } - SMLAL_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - umlal_inst* inst_cream = (umlal_inst*)inst_base->component; - long long int rm = RM; - long long int rs = RS; - if (BIT(rm, 31)) { - rm |= 0xffffffff00000000LL; - } - if (BIT(rs, 31)) { - rs |= 0xffffffff00000000LL; - } - long long int rst = rm * rs; - long long int rdhi32 = RDHI; - long long int hilo = (rdhi32 << 32) + RDLO; - rst += hilo; - RDLO = BITS(rst, 0, 31); - RDHI = BITS(rst, 32, 63); - if (inst_cream->S) { - cpu->NFlag = BIT(RDHI, 31); - cpu->ZFlag = (RDHI == 0 && RDLO == 0); - } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(smlad_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} + +SMLAL_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + umlal_inst* inst_cream = (umlal_inst*)inst_base->component; + long long int rm = RM; + long long int rs = RS; + if (BIT(rm, 31)) { + rm |= 0xffffffff00000000LL; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(umlal_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - - SMLALXY_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - smlalxy_inst* const inst_cream = (smlalxy_inst*)inst_base->component; - - u64 operand1 = RN; - u64 operand2 = RM; - - if (inst_cream->x != 0) - operand1 >>= 16; - if (inst_cream->y != 0) - operand2 >>= 16; - operand1 &= 0xFFFF; - if (operand1 & 0x8000) - operand1 -= 65536; - operand2 &= 0xFFFF; - if (operand2 & 0x8000) - operand2 -= 65536; - - u64 dest = ((u64)RDHI << 32 | RDLO) + (operand1 * operand2); - RDLO = (dest & 0xFFFFFFFF); - RDHI = ((dest >> 32) & 0xFFFFFFFF); + if (BIT(rs, 31)) { + rs |= 0xffffffff00000000LL; + } + long long int rst = rm * rs; + long long int rdhi32 = RDHI; + long long int hilo = (rdhi32 << 32) + RDLO; + rst += hilo; + RDLO = BITS(rst, 0, 31); + RDHI = BITS(rst, 32, 63); + if (inst_cream->S) { + cpu->NFlag = BIT(RDHI, 31); + cpu->ZFlag = (RDHI == 0 && RDLO == 0); } - - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(smlalxy_inst)); - FETCH_INST; - GOTO_NEXT_INST; } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(umlal_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - SMLAW_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - smlad_inst* const inst_cream = (smlad_inst*)inst_base->component; +SMLALXY_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + smlalxy_inst* const inst_cream = (smlalxy_inst*)inst_base->component; + + u64 operand1 = RN; + u64 operand2 = RM; + + if (inst_cream->x != 0) + operand1 >>= 16; + if (inst_cream->y != 0) + operand2 >>= 16; + operand1 &= 0xFFFF; + if (operand1 & 0x8000) + operand1 -= 65536; + operand2 &= 0xFFFF; + if (operand2 & 0x8000) + operand2 -= 65536; + + u64 dest = ((u64)RDHI << 32 | RDLO) + (operand1 * operand2); + RDLO = (dest & 0xFFFFFFFF); + RDHI = ((dest >> 32) & 0xFFFFFFFF); + } + + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(smlalxy_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - const u32 rm_val = RM; - const u32 rn_val = RN; - const u32 ra_val = cpu->Reg[inst_cream->Ra]; - const bool high = (inst_cream->m == 1); +SMLAW_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + smlad_inst* const inst_cream = (smlad_inst*)inst_base->component; - const s16 operand2 = (high) ? ((rm_val >> 16) & 0xFFFF) : (rm_val & 0xFFFF); - const s64 result = (s64)(s32)rn_val * (s64)(s32)operand2 + ((s64)(s32)ra_val << 16); + const u32 rm_val = RM; + const u32 rn_val = RN; + const u32 ra_val = cpu->Reg[inst_cream->Ra]; + const bool high = (inst_cream->m == 1); - RD = BITS(result, 16, 47); + const s16 operand2 = (high) ? ((rm_val >> 16) & 0xFFFF) : (rm_val & 0xFFFF); + const s64 result = (s64)(s32)rn_val * (s64)(s32)operand2 + ((s64)(s32)ra_val << 16); - if ((result >> 16) != (s32)RD) - cpu->Cpsr |= (1 << 27); - } + RD = BITS(result, 16, 47); - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(smlad_inst)); - FETCH_INST; - GOTO_NEXT_INST; + if ((result >> 16) != (s32)RD) + cpu->Cpsr |= (1 << 27); } - SMLALD_INST: - SMLSLD_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - smlald_inst* const inst_cream = (smlald_inst*)inst_base->component; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(smlad_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - const bool do_swap = (inst_cream->swap == 1); - const u32 rdlo_val = RDLO; - const u32 rdhi_val = RDHI; - const u32 rn_val = RN; - u32 rm_val = RM; +SMLALD_INST: +SMLSLD_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + smlald_inst* const inst_cream = (smlald_inst*)inst_base->component; - if (do_swap) - rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16)); + const bool do_swap = (inst_cream->swap == 1); + const u32 rdlo_val = RDLO; + const u32 rdhi_val = RDHI; + const u32 rn_val = RN; + u32 rm_val = RM; - const s32 product1 = (s16)(rn_val & 0xFFFF) * (s16)(rm_val & 0xFFFF); - const s32 product2 = (s16)((rn_val >> 16) & 0xFFFF) * (s16)((rm_val >> 16) & 0xFFFF); - s64 result; + if (do_swap) + rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16)); - // SMLALD - if (BIT(inst_cream->op2, 1) == 0) { - result = (product1 + product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32)); - } - // SMLSLD - else { - result = (product1 - product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32)); - } + const s32 product1 = (s16)(rn_val & 0xFFFF) * (s16)(rm_val & 0xFFFF); + const s32 product2 = (s16)((rn_val >> 16) & 0xFFFF) * (s16)((rm_val >> 16) & 0xFFFF); + s64 result; - RDLO = (result & 0xFFFFFFFF); - RDHI = ((result >> 32) & 0xFFFFFFFF); + // SMLALD + if (BIT(inst_cream->op2, 1) == 0) { + result = (product1 + product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32)); + } + // SMLSLD + else { + result = (product1 - product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32)); } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(smlald_inst)); - FETCH_INST; - GOTO_NEXT_INST; + RDLO = (result & 0xFFFFFFFF); + RDHI = ((result >> 32) & 0xFFFFFFFF); } - SMMLA_INST: - SMMLS_INST: - SMMUL_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - smlad_inst* const inst_cream = (smlad_inst*)inst_base->component; - - const u32 rm_val = RM; - const u32 rn_val = RN; - const bool do_round = (inst_cream->m == 1); + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(smlald_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - // Assume SMMUL by default. - s64 result = (s64)(s32)rn_val * (s64)(s32)rm_val; +SMMLA_INST: +SMMLS_INST: +SMMUL_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + smlad_inst* const inst_cream = (smlad_inst*)inst_base->component; - if (inst_cream->Ra != 15) { - const u32 ra_val = cpu->Reg[inst_cream->Ra]; + const u32 rm_val = RM; + const u32 rn_val = RN; + const bool do_round = (inst_cream->m == 1); - // SMMLA, otherwise SMMLS - if (BIT(inst_cream->op2, 1) == 0) - result += ((s64)ra_val << 32); - else - result = ((s64)ra_val << 32) - result; - } + // Assume SMMUL by default. + s64 result = (s64)(s32)rn_val * (s64)(s32)rm_val; - if (do_round) - result += 0x80000000; + if (inst_cream->Ra != 15) { + const u32 ra_val = cpu->Reg[inst_cream->Ra]; - RD = ((result >> 32) & 0xFFFFFFFF); + // SMMLA, otherwise SMMLS + if (BIT(inst_cream->op2, 1) == 0) + result += ((s64)ra_val << 32); + else + result = ((s64)ra_val << 32) - result; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(smlad_inst)); - FETCH_INST; - GOTO_NEXT_INST; + if (do_round) + result += 0x80000000; + + RD = ((result >> 32) & 0xFFFFFFFF); } - SMUL_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - smul_inst* inst_cream = (smul_inst*)inst_base->component; - u32 operand1, operand2; - if (inst_cream->x == 0) - operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); - else - operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31); + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(smlad_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - if (inst_cream->y == 0) - operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15); - else - operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); - RD = operand1 * operand2; +SMUL_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + smul_inst* inst_cream = (smul_inst*)inst_base->component; + u32 operand1, operand2; + if (inst_cream->x == 0) + operand1 = (BIT(RM, 15)) ? (BITS(RM, 0, 15) | 0xffff0000) : BITS(RM, 0, 15); + else + operand1 = (BIT(RM, 31)) ? (BITS(RM, 16, 31) | 0xffff0000) : BITS(RM, 16, 31); + + if (inst_cream->y == 0) + operand2 = (BIT(RS, 15)) ? (BITS(RS, 0, 15) | 0xffff0000) : BITS(RS, 0, 15); + else + operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31); + RD = operand1 * operand2; + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(smul_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +SMULL_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + umull_inst* inst_cream = (umull_inst*)inst_base->component; + s64 rm = RM; + s64 rs = RS; + if (BIT(rm, 31)) { + rm |= 0xffffffff00000000LL; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(smul_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - SMULL_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - umull_inst* inst_cream = (umull_inst*)inst_base->component; - s64 rm = RM; - s64 rs = RS; - if (BIT(rm, 31)) { - rm |= 0xffffffff00000000LL; - } - if (BIT(rs, 31)) { - rs |= 0xffffffff00000000LL; - } - s64 rst = rm * rs; - RDHI = BITS(rst, 32, 63); - RDLO = BITS(rst, 0, 31); + if (BIT(rs, 31)) { + rs |= 0xffffffff00000000LL; + } + s64 rst = rm * rs; + RDHI = BITS(rst, 32, 63); + RDLO = BITS(rst, 0, 31); - if (inst_cream->S) { - cpu->NFlag = BIT(RDHI, 31); - cpu->ZFlag = (RDHI == 0 && RDLO == 0); - } + if (inst_cream->S) { + cpu->NFlag = BIT(RDHI, 31); + cpu->ZFlag = (RDHI == 0 && RDLO == 0); } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(umull_inst)); - FETCH_INST; - GOTO_NEXT_INST; } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(umull_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - SMULW_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - smlad_inst* const inst_cream = (smlad_inst*)inst_base->component; +SMULW_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + smlad_inst* const inst_cream = (smlad_inst*)inst_base->component; - s16 rm = (inst_cream->m == 1) ? ((RM >> 16) & 0xFFFF) : (RM & 0xFFFF); + s16 rm = (inst_cream->m == 1) ? ((RM >> 16) & 0xFFFF) : (RM & 0xFFFF); - s64 result = (s64)rm * (s64)(s32)RN; - RD = BITS(result, 16, 47); - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(smlad_inst)); - FETCH_INST; - GOTO_NEXT_INST; + s64 result = (s64)rm * (s64)(s32)RN; + RD = BITS(result, 16, 47); } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(smlad_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - SRS_INST: - { - // SRS is unconditional - ldst_inst* const inst_cream = (ldst_inst*)inst_base->component; +SRS_INST : { + // SRS is unconditional + ldst_inst* const inst_cream = (ldst_inst*)inst_base->component; - u32 address = 0; - inst_cream->get_addr(cpu, inst_cream->inst, address); + u32 address = 0; + inst_cream->get_addr(cpu, inst_cream->inst, address); - cpu->WriteMemory32(address + 0, cpu->Reg[14]); - cpu->WriteMemory32(address + 4, cpu->Spsr_copy); + cpu->WriteMemory32(address + 0, cpu->Reg[14]); + cpu->WriteMemory32(address + 4, cpu->Spsr_copy); - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - - SSAT_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - ssat_inst* const inst_cream = (ssat_inst*)inst_base->component; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - u8 shift_type = inst_cream->shift_type; - u8 shift_amount = inst_cream->imm5; - u32 rn_val = RN; +SSAT_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + ssat_inst* const inst_cream = (ssat_inst*)inst_base->component; - // 32-bit ASR is encoded as an amount of 0. - if (shift_type == 1 && shift_amount == 0) - shift_amount = 31; + u8 shift_type = inst_cream->shift_type; + u8 shift_amount = inst_cream->imm5; + u32 rn_val = RN; - if (shift_type == 0) - rn_val <<= shift_amount; - else if (shift_type == 1) - rn_val = ((s32)rn_val >> shift_amount); + // 32-bit ASR is encoded as an amount of 0. + if (shift_type == 1 && shift_amount == 0) + shift_amount = 31; - bool saturated = false; - rn_val = ARMul_SignedSatQ(rn_val, inst_cream->sat_imm, &saturated); + if (shift_type == 0) + rn_val <<= shift_amount; + else if (shift_type == 1) + rn_val = ((s32)rn_val >> shift_amount); - if (saturated) - cpu->Cpsr |= (1 << 27); + bool saturated = false; + rn_val = ARMul_SignedSatQ(rn_val, inst_cream->sat_imm, &saturated); - RD = rn_val; - } + if (saturated) + cpu->Cpsr |= (1 << 27); - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ssat_inst)); - FETCH_INST; - GOTO_NEXT_INST; + RD = rn_val; } - SSAT16_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - ssat_inst* const inst_cream = (ssat_inst*)inst_base->component; - const u8 saturate_to = inst_cream->sat_imm; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ssat_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - bool sat1 = false; - bool sat2 = false; +SSAT16_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + ssat_inst* const inst_cream = (ssat_inst*)inst_base->component; + const u8 saturate_to = inst_cream->sat_imm; - RD = (ARMul_SignedSatQ((s16)RN, saturate_to, &sat1) & 0xFFFF) | - ARMul_SignedSatQ((s32)RN >> 16, saturate_to, &sat2) << 16; + bool sat1 = false; + bool sat2 = false; - if (sat1 || sat2) - cpu->Cpsr |= (1 << 27); - } + RD = (ARMul_SignedSatQ((s16)RN, saturate_to, &sat1) & 0xFFFF) | + ARMul_SignedSatQ((s32)RN >> 16, saturate_to, &sat2) << 16; - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ssat_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - - STC_INST: - { - // Instruction not implemented - //LOG_CRITICAL(Core_ARM11, "unimplemented instruction"); - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(stc_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - STM_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - ldst_inst* inst_cream = (ldst_inst*)inst_base->component; - unsigned int inst = inst_cream->inst; - - unsigned int Rn = BITS(inst, 16, 19); - unsigned int old_RN = cpu->Reg[Rn]; - - inst_cream->get_addr(cpu, inst_cream->inst, addr); - if (BIT(inst_cream->inst, 22) == 1) { - for (int i = 0; i < 13; i++) { - if (BIT(inst_cream->inst, i)) { - cpu->WriteMemory32(addr, cpu->Reg[i]); - addr += 4; - } - } - if (BIT(inst_cream->inst, 13)) { - if (cpu->Mode == USER32MODE) - cpu->WriteMemory32(addr, cpu->Reg[13]); - else - cpu->WriteMemory32(addr, cpu->Reg_usr[0]); + if (sat1 || sat2) + cpu->Cpsr |= (1 << 27); + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ssat_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} + +STC_INST : { + // Instruction not implemented + // LOG_CRITICAL(Core_ARM11, "unimplemented instruction"); + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(stc_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +STM_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; + unsigned int inst = inst_cream->inst; + + unsigned int Rn = BITS(inst, 16, 19); + unsigned int old_RN = cpu->Reg[Rn]; + + inst_cream->get_addr(cpu, inst_cream->inst, addr); + if (BIT(inst_cream->inst, 22) == 1) { + for (int i = 0; i < 13; i++) { + if (BIT(inst_cream->inst, i)) { + cpu->WriteMemory32(addr, cpu->Reg[i]); addr += 4; } - if (BIT(inst_cream->inst, 14)) { - if (cpu->Mode == USER32MODE) - cpu->WriteMemory32(addr, cpu->Reg[14]); + } + if (BIT(inst_cream->inst, 13)) { + if (cpu->Mode == USER32MODE) + cpu->WriteMemory32(addr, cpu->Reg[13]); + else + cpu->WriteMemory32(addr, cpu->Reg_usr[0]); + + addr += 4; + } + if (BIT(inst_cream->inst, 14)) { + if (cpu->Mode == USER32MODE) + cpu->WriteMemory32(addr, cpu->Reg[14]); + else + cpu->WriteMemory32(addr, cpu->Reg_usr[1]); + + addr += 4; + } + if (BIT(inst_cream->inst, 15)) { + cpu->WriteMemory32(addr, cpu->Reg[15] + 8); + } + } else { + for (int i = 0; i < 15; i++) { + if (BIT(inst_cream->inst, i)) { + if (i == Rn) + cpu->WriteMemory32(addr, old_RN); else - cpu->WriteMemory32(addr, cpu->Reg_usr[1]); + cpu->WriteMemory32(addr, cpu->Reg[i]); addr += 4; } - if (BIT(inst_cream->inst, 15)) { - cpu->WriteMemory32(addr, cpu->Reg[15] + 8); - } - } else { - for (int i = 0; i < 15; i++) { - if (BIT(inst_cream->inst, i)) { - if (i == Rn) - cpu->WriteMemory32(addr, old_RN); - else - cpu->WriteMemory32(addr, cpu->Reg[i]); - - addr += 4; - } - } + } - // Check PC reg - if (BIT(inst_cream->inst, 15)) { - cpu->WriteMemory32(addr, cpu->Reg[15] + 8); - } + // Check PC reg + if (BIT(inst_cream->inst, 15)) { + cpu->WriteMemory32(addr, cpu->Reg[15] + 8); } } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; } - SXTB_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - sxtb_inst* inst_cream = (sxtb_inst*)inst_base->component; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +SXTB_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + sxtb_inst* inst_cream = (sxtb_inst*)inst_base->component; - unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate); - if (BIT(operand2, 7)) { - operand2 |= 0xffffff00; - } else { - operand2 &= 0xff; - } - RD = operand2; + unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate); + if (BIT(operand2, 7)) { + operand2 |= 0xffffff00; + } else { + operand2 &= 0xff; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(sxtb_inst)); - FETCH_INST; - GOTO_NEXT_INST; + RD = operand2; } - STR_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - ldst_inst* inst_cream = (ldst_inst*)inst_base->component; - inst_cream->get_addr(cpu, inst_cream->inst, addr); + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(sxtb_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +STR_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; + inst_cream->get_addr(cpu, inst_cream->inst, addr); - unsigned int reg = BITS(inst_cream->inst, 12, 15); - unsigned int value = cpu->Reg[reg]; + unsigned int reg = BITS(inst_cream->inst, 12, 15); + unsigned int value = cpu->Reg[reg]; - if (reg == 15) - value += 2 * cpu->GetInstructionSize(); + if (reg == 15) + value += 2 * cpu->GetInstructionSize(); - cpu->WriteMemory32(addr, value); - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - UXTB_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - uxtb_inst* inst_cream = (uxtb_inst*)inst_base->component; - RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff; - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(uxtb_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - UXTAB_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - uxtab_inst* inst_cream = (uxtab_inst*)inst_base->component; - - unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff; - RD = RN + operand2; - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(uxtab_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - STRB_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - ldst_inst* inst_cream = (ldst_inst*)inst_base->component; - inst_cream->get_addr(cpu, inst_cream->inst, addr); - unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; - cpu->WriteMemory8(addr, value); - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; + cpu->WriteMemory32(addr, value); } - STRBT_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - ldst_inst* inst_cream = (ldst_inst*)inst_base->component; - inst_cream->get_addr(cpu, inst_cream->inst, addr); + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +UXTB_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + uxtb_inst* inst_cream = (uxtb_inst*)inst_base->component; + RD = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff; + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(uxtb_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +UXTAB_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + uxtab_inst* inst_cream = (uxtab_inst*)inst_base->component; - const u32 previous_mode = cpu->Mode; - const u32 value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; + unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff; + RD = RN + operand2; + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(uxtab_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +STRB_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; + inst_cream->get_addr(cpu, inst_cream->inst, addr); + unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; + cpu->WriteMemory8(addr, value); + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +STRBT_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; + inst_cream->get_addr(cpu, inst_cream->inst, addr); - cpu->ChangePrivilegeMode(USER32MODE); - cpu->WriteMemory8(addr, value); - cpu->ChangePrivilegeMode(previous_mode); - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - STRD_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - ldst_inst* inst_cream = (ldst_inst*)inst_base->component; - inst_cream->get_addr(cpu, inst_cream->inst, addr); - - // The 3DS doesn't have the Large Physical Access Extension (LPAE) - // so STRD wouldn't store these as a single write. - cpu->WriteMemory32(addr + 0, cpu->Reg[BITS(inst_cream->inst, 12, 15)]); - cpu->WriteMemory32(addr + 4, cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]); - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - STREX_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; - unsigned int write_addr = cpu->Reg[inst_cream->Rn]; - - if (cpu->IsExclusiveMemoryAccess(write_addr)) { - cpu->UnsetExclusiveMemoryAddress(); - cpu->WriteMemory32(write_addr, RM); - RD = 0; - } else { - // Failed to write due to mutex access - RD = 1; - } - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(generic_arm_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - STREXB_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; - unsigned int write_addr = cpu->Reg[inst_cream->Rn]; - - if (cpu->IsExclusiveMemoryAccess(write_addr)) { - cpu->UnsetExclusiveMemoryAddress(); - cpu->WriteMemory8(write_addr, cpu->Reg[inst_cream->Rm]); - RD = 0; - } else { - // Failed to write due to mutex access - RD = 1; - } - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(generic_arm_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - STREXD_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; - unsigned int write_addr = cpu->Reg[inst_cream->Rn]; - - if (cpu->IsExclusiveMemoryAccess(write_addr)) { - cpu->UnsetExclusiveMemoryAddress(); - - const u32 rt = cpu->Reg[inst_cream->Rm + 0]; - const u32 rt2 = cpu->Reg[inst_cream->Rm + 1]; - u64 value; - - if (cpu->InBigEndianMode()) - value = (((u64)rt << 32) | rt2); - else - value = (((u64)rt2 << 32) | rt); + const u32 previous_mode = cpu->Mode; + const u32 value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xff; - cpu->WriteMemory64(write_addr, value); - RD = 0; - } - else { - // Failed to write due to mutex access - RD = 1; - } - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(generic_arm_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - STREXH_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; - unsigned int write_addr = cpu->Reg[inst_cream->Rn]; - - if (cpu->IsExclusiveMemoryAccess(write_addr)) { - cpu->UnsetExclusiveMemoryAddress(); - cpu->WriteMemory16(write_addr, RM); - RD = 0; - } else { - // Failed to write due to mutex access - RD = 1; - } + cpu->ChangePrivilegeMode(USER32MODE); + cpu->WriteMemory8(addr, value); + cpu->ChangePrivilegeMode(previous_mode); + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +STRD_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; + inst_cream->get_addr(cpu, inst_cream->inst, addr); + + // The 3DS doesn't have the Large Physical Access Extension (LPAE) + // so STRD wouldn't store these as a single write. + cpu->WriteMemory32(addr + 0, cpu->Reg[BITS(inst_cream->inst, 12, 15)]); + cpu->WriteMemory32(addr + 4, cpu->Reg[BITS(inst_cream->inst, 12, 15) + 1]); + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +STREX_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; + unsigned int write_addr = cpu->Reg[inst_cream->Rn]; + + if (cpu->IsExclusiveMemoryAccess(write_addr)) { + cpu->UnsetExclusiveMemoryAddress(); + cpu->WriteMemory32(write_addr, RM); + RD = 0; + } else { + // Failed to write due to mutex access + RD = 1; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(generic_arm_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - STRH_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - ldst_inst* inst_cream = (ldst_inst*)inst_base->component; - inst_cream->get_addr(cpu, inst_cream->inst, addr); - - unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff; - cpu->WriteMemory16(addr, value); + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +STREXB_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; + unsigned int write_addr = cpu->Reg[inst_cream->Rn]; + + if (cpu->IsExclusiveMemoryAccess(write_addr)) { + cpu->UnsetExclusiveMemoryAddress(); + cpu->WriteMemory8(write_addr, cpu->Reg[inst_cream->Rm]); + RD = 0; + } else { + // Failed to write due to mutex access + RD = 1; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; } - STRT_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - ldst_inst* inst_cream = (ldst_inst*)inst_base->component; - inst_cream->get_addr(cpu, inst_cream->inst, addr); + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +STREXD_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; + unsigned int write_addr = cpu->Reg[inst_cream->Rn]; - const u32 previous_mode = cpu->Mode; - const u32 rt_index = BITS(inst_cream->inst, 12, 15); + if (cpu->IsExclusiveMemoryAccess(write_addr)) { + cpu->UnsetExclusiveMemoryAddress(); - u32 value = cpu->Reg[rt_index]; - if (rt_index == 15) - value += 2 * cpu->GetInstructionSize(); + const u32 rt = cpu->Reg[inst_cream->Rm + 0]; + const u32 rt2 = cpu->Reg[inst_cream->Rm + 1]; + u64 value; - cpu->ChangePrivilegeMode(USER32MODE); - cpu->WriteMemory32(addr, value); - cpu->ChangePrivilegeMode(previous_mode); + if (cpu->InBigEndianMode()) + value = (((u64)rt << 32) | rt2); + else + value = (((u64)rt2 << 32) | rt); + + cpu->WriteMemory64(write_addr, value); + RD = 0; + } else { + // Failed to write due to mutex access + RD = 1; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ldst_inst)); - FETCH_INST; - GOTO_NEXT_INST; } - SUB_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - sub_inst* const inst_cream = (sub_inst*)inst_base->component; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +STREXH_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; + unsigned int write_addr = cpu->Reg[inst_cream->Rn]; + + if (cpu->IsExclusiveMemoryAccess(write_addr)) { + cpu->UnsetExclusiveMemoryAddress(); + cpu->WriteMemory16(write_addr, RM); + RD = 0; + } else { + // Failed to write due to mutex access + RD = 1; + } + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +STRH_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; + inst_cream->get_addr(cpu, inst_cream->inst, addr); - u32 rn_val = CHECK_READ_REG15_WA(cpu, inst_cream->Rn); + unsigned int value = cpu->Reg[BITS(inst_cream->inst, 12, 15)] & 0xffff; + cpu->WriteMemory16(addr, value); + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +STRT_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; + inst_cream->get_addr(cpu, inst_cream->inst, addr); - bool carry; - bool overflow; - RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow); + const u32 previous_mode = cpu->Mode; + const u32 rt_index = BITS(inst_cream->inst, 12, 15); - if (inst_cream->S && (inst_cream->Rd == 15)) { - if (CurrentModeHasSPSR) { - cpu->Cpsr = cpu->Spsr_copy; - cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); - LOAD_NZCVT; - } - } else if (inst_cream->S) { - UPDATE_NFLAG(RD); - UPDATE_ZFLAG(RD); - cpu->CFlag = carry; - cpu->VFlag = overflow; - } - if (inst_cream->Rd == 15) { - INC_PC(sizeof(sub_inst)); - goto DISPATCH; - } - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(sub_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - SWI_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - swi_inst* const inst_cream = (swi_inst*)inst_base->component; - SVC::CallSVC(inst_cream->num & 0xFFFF); - } + u32 value = cpu->Reg[rt_index]; + if (rt_index == 15) + value += 2 * cpu->GetInstructionSize(); - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(swi_inst)); - FETCH_INST; - GOTO_NEXT_INST; + cpu->ChangePrivilegeMode(USER32MODE); + cpu->WriteMemory32(addr, value); + cpu->ChangePrivilegeMode(previous_mode); } - SWP_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - swp_inst* inst_cream = (swp_inst*)inst_base->component; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ldst_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +SUB_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + sub_inst* const inst_cream = (sub_inst*)inst_base->component; - addr = RN; - unsigned int value = cpu->ReadMemory32(addr); - cpu->WriteMemory32(addr, RM); + u32 rn_val = CHECK_READ_REG15_WA(cpu, inst_cream->Rn); - RD = value; + bool carry; + bool overflow; + RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, 1, &carry, &overflow); + + if (inst_cream->S && (inst_cream->Rd == 15)) { + if (CurrentModeHasSPSR) { + cpu->Cpsr = cpu->Spsr_copy; + cpu->ChangePrivilegeMode(cpu->Spsr_copy & 0x1F); + LOAD_NZCVT; + } + } else if (inst_cream->S) { + UPDATE_NFLAG(RD); + UPDATE_ZFLAG(RD); + cpu->CFlag = carry; + cpu->VFlag = overflow; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(swp_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - SWPB_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - swp_inst* inst_cream = (swp_inst*)inst_base->component; - addr = RN; - unsigned int value = cpu->ReadMemory8(addr); - cpu->WriteMemory8(addr, (RM & 0xFF)); - RD = value; + if (inst_cream->Rd == 15) { + INC_PC(sizeof(sub_inst)); + goto DISPATCH; } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(swp_inst)); - FETCH_INST; - GOTO_NEXT_INST; } - SXTAB_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - sxtab_inst* inst_cream = (sxtab_inst*)inst_base->component; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(sub_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +SWI_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + swi_inst* const inst_cream = (swi_inst*)inst_base->component; + SVC::CallSVC(inst_cream->num & 0xFFFF); + } - unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(swi_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +SWP_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + swp_inst* inst_cream = (swp_inst*)inst_base->component; - // Sign extend for byte - operand2 = (0x80 & operand2)? (0xFFFFFF00 | operand2):operand2; - RD = RN + operand2; - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(uxtab_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - - SXTAB16_INST: - SXTB16_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - sxtab_inst* const inst_cream = (sxtab_inst*)inst_base->component; - - const u8 rotation = inst_cream->rotate * 8; - u32 rm_val = RM; - u32 rn_val = RN; - - if (rotation) - rm_val = ((rm_val << (32 - rotation)) | (rm_val >> rotation)); - - // SXTB16 - if (inst_cream->Rn == 15) { - u32 lo = (u32)(s8)rm_val; - u32 hi = (u32)(s8)(rm_val >> 16); - RD = (lo | (hi << 16)); - } - // SXTAB16 - else { - u32 lo = (rn_val & 0xFFFF) + (u32)(s8)(rm_val & 0xFF); - u32 hi = ((rn_val >> 16) & 0xFFFF) + (u32)(s8)((rm_val >> 16) & 0xFF); - RD = (lo | (hi << 16)); - } - } + addr = RN; + unsigned int value = cpu->ReadMemory32(addr); + cpu->WriteMemory32(addr, RM); - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(sxtab_inst)); - FETCH_INST; - GOTO_NEXT_INST; + RD = value; } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(swp_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +SWPB_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + swp_inst* inst_cream = (swp_inst*)inst_base->component; + addr = RN; + unsigned int value = cpu->ReadMemory8(addr); + cpu->WriteMemory8(addr, (RM & 0xFF)); + RD = value; + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(swp_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +SXTAB_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + sxtab_inst* inst_cream = (sxtab_inst*)inst_base->component; - SXTAH_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - sxtah_inst* inst_cream = (sxtah_inst*)inst_base->component; + unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xff; - unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff; - // Sign extend for half - operand2 = (0x8000 & operand2) ? (0xFFFF0000 | operand2) : operand2; - RD = RN + operand2; - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(sxtah_inst)); - FETCH_INST; - GOTO_NEXT_INST; + // Sign extend for byte + operand2 = (0x80 & operand2) ? (0xFFFFFF00 | operand2) : operand2; + RD = RN + operand2; } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(uxtab_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - TEQ_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - teq_inst* const inst_cream = (teq_inst*)inst_base->component; - - u32 lop = RN; - u32 rop = SHIFTER_OPERAND; +SXTAB16_INST: +SXTB16_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + sxtab_inst* const inst_cream = (sxtab_inst*)inst_base->component; - if (inst_cream->Rn == 15) - lop += cpu->GetInstructionSize() * 2; + const u8 rotation = inst_cream->rotate * 8; + u32 rm_val = RM; + u32 rn_val = RN; - u32 result = lop ^ rop; + if (rotation) + rm_val = ((rm_val << (32 - rotation)) | (rm_val >> rotation)); - UPDATE_NFLAG(result); - UPDATE_ZFLAG(result); - UPDATE_CFLAG_WITH_SC; + // SXTB16 + if (inst_cream->Rn == 15) { + u32 lo = (u32)(s8)rm_val; + u32 hi = (u32)(s8)(rm_val >> 16); + RD = (lo | (hi << 16)); + } + // SXTAB16 + else { + u32 lo = (rn_val & 0xFFFF) + (u32)(s8)(rm_val & 0xFF); + u32 hi = ((rn_val >> 16) & 0xFFFF) + (u32)(s8)((rm_val >> 16) & 0xFF); + RD = (lo | (hi << 16)); } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(teq_inst)); - FETCH_INST; - GOTO_NEXT_INST; } - TST_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - tst_inst* const inst_cream = (tst_inst*)inst_base->component; - u32 lop = RN; - u32 rop = SHIFTER_OPERAND; - - if (inst_cream->Rn == 15) - lop += cpu->GetInstructionSize() * 2; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(sxtab_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - u32 result = lop & rop; +SXTAH_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + sxtah_inst* inst_cream = (sxtah_inst*)inst_base->component; - UPDATE_NFLAG(result); - UPDATE_ZFLAG(result); - UPDATE_CFLAG_WITH_SC; - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(tst_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - - UADD8_INST: - UADD16_INST: - UADDSUBX_INST: - USUB8_INST: - USUB16_INST: - USUBADDX_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; - - const u8 op2 = inst_cream->op2; - const u32 rm_val = RM; - const u32 rn_val = RN; + unsigned int operand2 = ROTATE_RIGHT_32(RM, 8 * inst_cream->rotate) & 0xffff; + // Sign extend for half + operand2 = (0x8000 & operand2) ? (0xFFFF0000 | operand2) : operand2; + RD = RN + operand2; + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(sxtah_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - s32 lo_result = 0; - s32 hi_result = 0; +TEQ_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + teq_inst* const inst_cream = (teq_inst*)inst_base->component; - // UADD16 - if (op2 == 0x00) { - lo_result = (rn_val & 0xFFFF) + (rm_val & 0xFFFF); - hi_result = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); - - if (lo_result & 0xFFFF0000) { - cpu->Cpsr |= (1 << 16); - cpu->Cpsr |= (1 << 17); - } else { - cpu->Cpsr &= ~(1 << 16); - cpu->Cpsr &= ~(1 << 17); - } + u32 lop = RN; + u32 rop = SHIFTER_OPERAND; - if (hi_result & 0xFFFF0000) { - cpu->Cpsr |= (1 << 18); - cpu->Cpsr |= (1 << 19); - } else { - cpu->Cpsr &= ~(1 << 18); - cpu->Cpsr &= ~(1 << 19); - } - } - // UASX - else if (op2 == 0x01) { - lo_result = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); - hi_result = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF); - - if (lo_result >= 0) { - cpu->Cpsr |= (1 << 16); - cpu->Cpsr |= (1 << 17); - } else { - cpu->Cpsr &= ~(1 << 16); - cpu->Cpsr &= ~(1 << 17); - } + if (inst_cream->Rn == 15) + lop += cpu->GetInstructionSize() * 2; - if (hi_result >= 0x10000) { - cpu->Cpsr |= (1 << 18); - cpu->Cpsr |= (1 << 19); - } else { - cpu->Cpsr &= ~(1 << 18); - cpu->Cpsr &= ~(1 << 19); - } - } - // USAX - else if (op2 == 0x02) { - lo_result = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); - hi_result = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF); - - if (lo_result >= 0x10000) { - cpu->Cpsr |= (1 << 16); - cpu->Cpsr |= (1 << 17); - } else { - cpu->Cpsr &= ~(1 << 16); - cpu->Cpsr &= ~(1 << 17); - } + u32 result = lop ^ rop; - if (hi_result >= 0) { - cpu->Cpsr |= (1 << 18); - cpu->Cpsr |= (1 << 19); - } else { - cpu->Cpsr &= ~(1 << 18); - cpu->Cpsr &= ~(1 << 19); - } - } - // USUB16 - else if (op2 == 0x03) { - lo_result = (rn_val & 0xFFFF) - (rm_val & 0xFFFF); - hi_result = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); - - if ((lo_result & 0xFFFF0000) == 0) { - cpu->Cpsr |= (1 << 16); - cpu->Cpsr |= (1 << 17); - } else { - cpu->Cpsr &= ~(1 << 16); - cpu->Cpsr &= ~(1 << 17); - } + UPDATE_NFLAG(result); + UPDATE_ZFLAG(result); + UPDATE_CFLAG_WITH_SC; + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(teq_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +TST_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + tst_inst* const inst_cream = (tst_inst*)inst_base->component; - if ((hi_result & 0xFFFF0000) == 0) { - cpu->Cpsr |= (1 << 18); - cpu->Cpsr |= (1 << 19); - } else { - cpu->Cpsr &= ~(1 << 18); - cpu->Cpsr &= ~(1 << 19); - } - } - // UADD8 - else if (op2 == 0x04) { - s16 sum1 = (rn_val & 0xFF) + (rm_val & 0xFF); - s16 sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF); - s16 sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF); - s16 sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF); - - if (sum1 >= 0x100) - cpu->Cpsr |= (1 << 16); - else - cpu->Cpsr &= ~(1 << 16); + u32 lop = RN; + u32 rop = SHIFTER_OPERAND; - if (sum2 >= 0x100) - cpu->Cpsr |= (1 << 17); - else - cpu->Cpsr &= ~(1 << 17); + if (inst_cream->Rn == 15) + lop += cpu->GetInstructionSize() * 2; - if (sum3 >= 0x100) - cpu->Cpsr |= (1 << 18); - else - cpu->Cpsr &= ~(1 << 18); + u32 result = lop & rop; - if (sum4 >= 0x100) - cpu->Cpsr |= (1 << 19); - else - cpu->Cpsr &= ~(1 << 19); + UPDATE_NFLAG(result); + UPDATE_ZFLAG(result); + UPDATE_CFLAG_WITH_SC; + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(tst_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - lo_result = ((sum1 & 0xFF) | (sum2 & 0xFF) << 8); - hi_result = ((sum3 & 0xFF) | (sum4 & 0xFF) << 8); +UADD8_INST: +UADD16_INST: +UADDSUBX_INST: +USUB8_INST: +USUB16_INST: +USUBADDX_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; + + const u8 op2 = inst_cream->op2; + const u32 rm_val = RM; + const u32 rn_val = RN; + + s32 lo_result = 0; + s32 hi_result = 0; + + // UADD16 + if (op2 == 0x00) { + lo_result = (rn_val & 0xFFFF) + (rm_val & 0xFFFF); + hi_result = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); + + if (lo_result & 0xFFFF0000) { + cpu->Cpsr |= (1 << 16); + cpu->Cpsr |= (1 << 17); + } else { + cpu->Cpsr &= ~(1 << 16); + cpu->Cpsr &= ~(1 << 17); } - // USUB8 - else if (op2 == 0x07) { - s16 diff1 = (rn_val & 0xFF) - (rm_val & 0xFF); - s16 diff2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF); - s16 diff3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF); - s16 diff4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF); - - if (diff1 >= 0) - cpu->Cpsr |= (1 << 16); - else - cpu->Cpsr &= ~(1 << 16); - if (diff2 >= 0) - cpu->Cpsr |= (1 << 17); - else - cpu->Cpsr &= ~(1 << 17); - - if (diff3 >= 0) - cpu->Cpsr |= (1 << 18); - else - cpu->Cpsr &= ~(1 << 18); - - if (diff4 >= 0) - cpu->Cpsr |= (1 << 19); - else - cpu->Cpsr &= ~(1 << 19); - - lo_result = (diff1 & 0xFF) | ((diff2 & 0xFF) << 8); - hi_result = (diff3 & 0xFF) | ((diff4 & 0xFF) << 8); + if (hi_result & 0xFFFF0000) { + cpu->Cpsr |= (1 << 18); + cpu->Cpsr |= (1 << 19); + } else { + cpu->Cpsr &= ~(1 << 18); + cpu->Cpsr &= ~(1 << 19); } - - RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); } + // UASX + else if (op2 == 0x01) { + lo_result = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); + hi_result = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF); + + if (lo_result >= 0) { + cpu->Cpsr |= (1 << 16); + cpu->Cpsr |= (1 << 17); + } else { + cpu->Cpsr &= ~(1 << 16); + cpu->Cpsr &= ~(1 << 17); + } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(generic_arm_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - - UHADD8_INST: - UHADD16_INST: - UHADDSUBX_INST: - UHSUBADDX_INST: - UHSUB8_INST: - UHSUB16_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; - const u32 rm_val = RM; - const u32 rn_val = RN; - const u8 op2 = inst_cream->op2; - - if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) - { - u32 lo_val = 0; - u32 hi_val = 0; - - // UHADD16 - if (op2 == 0x00) { - lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF); - hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); - } - // UHASX - else if (op2 == 0x01) { - lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); - hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF); - } - // UHSAX - else if (op2 == 0x02) { - lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); - hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF); - } - // UHSUB16 - else if (op2 == 0x03) { - lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF); - hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); - } - - lo_val >>= 1; - hi_val >>= 1; - - RD = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16); + if (hi_result >= 0x10000) { + cpu->Cpsr |= (1 << 18); + cpu->Cpsr |= (1 << 19); + } else { + cpu->Cpsr &= ~(1 << 18); + cpu->Cpsr &= ~(1 << 19); + } + } + // USAX + else if (op2 == 0x02) { + lo_result = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); + hi_result = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF); + + if (lo_result >= 0x10000) { + cpu->Cpsr |= (1 << 16); + cpu->Cpsr |= (1 << 17); + } else { + cpu->Cpsr &= ~(1 << 16); + cpu->Cpsr &= ~(1 << 17); } - else if (op2 == 0x04 || op2 == 0x07) { - u32 sum1; - u32 sum2; - u32 sum3; - u32 sum4; - - // UHADD8 - if (op2 == 0x04) { - sum1 = (rn_val & 0xFF) + (rm_val & 0xFF); - sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF); - sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF); - sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF); - } - // UHSUB8 - else { - sum1 = (rn_val & 0xFF) - (rm_val & 0xFF); - sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF); - sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF); - sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF); - } - sum1 >>= 1; - sum2 >>= 1; - sum3 >>= 1; - sum4 >>= 1; + if (hi_result >= 0) { + cpu->Cpsr |= (1 << 18); + cpu->Cpsr |= (1 << 19); + } else { + cpu->Cpsr &= ~(1 << 18); + cpu->Cpsr &= ~(1 << 19); + } + } + // USUB16 + else if (op2 == 0x03) { + lo_result = (rn_val & 0xFFFF) - (rm_val & 0xFFFF); + hi_result = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); + + if ((lo_result & 0xFFFF0000) == 0) { + cpu->Cpsr |= (1 << 16); + cpu->Cpsr |= (1 << 17); + } else { + cpu->Cpsr &= ~(1 << 16); + cpu->Cpsr &= ~(1 << 17); + } - RD = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24); + if ((hi_result & 0xFFFF0000) == 0) { + cpu->Cpsr |= (1 << 18); + cpu->Cpsr |= (1 << 19); + } else { + cpu->Cpsr &= ~(1 << 18); + cpu->Cpsr &= ~(1 << 19); } } + // UADD8 + else if (op2 == 0x04) { + s16 sum1 = (rn_val & 0xFF) + (rm_val & 0xFF); + s16 sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF); + s16 sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF); + s16 sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF); + + if (sum1 >= 0x100) + cpu->Cpsr |= (1 << 16); + else + cpu->Cpsr &= ~(1 << 16); - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(generic_arm_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } + if (sum2 >= 0x100) + cpu->Cpsr |= (1 << 17); + else + cpu->Cpsr &= ~(1 << 17); - UMAAL_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - umaal_inst* const inst_cream = (umaal_inst*)inst_base->component; - const u64 rm = RM; - const u64 rn = RN; - const u64 rd_lo = RDLO; - const u64 rd_hi = RDHI; - const u64 result = (rm * rn) + rd_lo + rd_hi; + if (sum3 >= 0x100) + cpu->Cpsr |= (1 << 18); + else + cpu->Cpsr &= ~(1 << 18); - RDLO = (result & 0xFFFFFFFF); - RDHI = ((result >> 32) & 0xFFFFFFFF); - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(umaal_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - UMLAL_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - umlal_inst* inst_cream = (umlal_inst*)inst_base->component; - unsigned long long int rm = RM; - unsigned long long int rs = RS; - unsigned long long int rst = rm * rs; - unsigned long long int add = ((unsigned long long) RDHI)<<32; - add += RDLO; - rst += add; - RDLO = BITS(rst, 0, 31); - RDHI = BITS(rst, 32, 63); - - if (inst_cream->S) { - cpu->NFlag = BIT(RDHI, 31); - cpu->ZFlag = (RDHI == 0 && RDLO == 0); - } - } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(umlal_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - UMULL_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - umull_inst* inst_cream = (umull_inst*)inst_base->component; - unsigned long long int rm = RM; - unsigned long long int rs = RS; - unsigned long long int rst = rm * rs; - RDHI = BITS(rst, 32, 63); - RDLO = BITS(rst, 0, 31); - - if (inst_cream->S) { - cpu->NFlag = BIT(RDHI, 31); - cpu->ZFlag = (RDHI == 0 && RDLO == 0); - } + if (sum4 >= 0x100) + cpu->Cpsr |= (1 << 19); + else + cpu->Cpsr &= ~(1 << 19); + + lo_result = ((sum1 & 0xFF) | (sum2 & 0xFF) << 8); + hi_result = ((sum3 & 0xFF) | (sum4 & 0xFF) << 8); } - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(umull_inst)); - FETCH_INST; - GOTO_NEXT_INST; - } - B_2_THUMB: - { - b_2_thumb* inst_cream = (b_2_thumb*)inst_base->component; - cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; - INC_PC(sizeof(b_2_thumb)); - goto DISPATCH; - } - B_COND_THUMB: - { - b_cond_thumb* inst_cream = (b_cond_thumb*)inst_base->component; + // USUB8 + else if (op2 == 0x07) { + s16 diff1 = (rn_val & 0xFF) - (rm_val & 0xFF); + s16 diff2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF); + s16 diff3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF); + s16 diff4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF); + + if (diff1 >= 0) + cpu->Cpsr |= (1 << 16); + else + cpu->Cpsr &= ~(1 << 16); - if(CondPassed(cpu, inst_cream->cond)) - cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; - else - cpu->Reg[15] += 2; + if (diff2 >= 0) + cpu->Cpsr |= (1 << 17); + else + cpu->Cpsr &= ~(1 << 17); - INC_PC(sizeof(b_cond_thumb)); - goto DISPATCH; - } - BL_1_THUMB: - { - bl_1_thumb* inst_cream = (bl_1_thumb*)inst_base->component; - cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm; - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(bl_1_thumb)); - FETCH_INST; - GOTO_NEXT_INST; - } - BL_2_THUMB: - { - bl_2_thumb* inst_cream = (bl_2_thumb*)inst_base->component; - int tmp = ((cpu->Reg[15] + 2) | 1); - cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm); - cpu->Reg[14] = tmp; - INC_PC(sizeof(bl_2_thumb)); - goto DISPATCH; - } - BLX_1_THUMB: - { - // BLX 1 for armv5t and above - u32 tmp = cpu->Reg[15]; - blx_1_thumb* inst_cream = (blx_1_thumb*)inst_base->component; - cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC; - cpu->Reg[14] = ((tmp + 2) | 1); - cpu->TFlag = 0; - INC_PC(sizeof(blx_1_thumb)); - goto DISPATCH; - } + if (diff3 >= 0) + cpu->Cpsr |= (1 << 18); + else + cpu->Cpsr &= ~(1 << 18); - UQADD8_INST: - UQADD16_INST: - UQADDSUBX_INST: - UQSUB8_INST: - UQSUB16_INST: - UQSUBADDX_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; + if (diff4 >= 0) + cpu->Cpsr |= (1 << 19); + else + cpu->Cpsr &= ~(1 << 19); - const u8 op2 = inst_cream->op2; - const u32 rm_val = RM; - const u32 rn_val = RN; + lo_result = (diff1 & 0xFF) | ((diff2 & 0xFF) << 8); + hi_result = (diff3 & 0xFF) | ((diff4 & 0xFF) << 8); + } - u16 lo_val = 0; - u16 hi_val = 0; + RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16); + } - // UQADD16 + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} + +UHADD8_INST: +UHADD16_INST: +UHADDSUBX_INST: +UHSUBADDX_INST: +UHSUB8_INST: +UHSUB16_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; + const u32 rm_val = RM; + const u32 rn_val = RN; + const u8 op2 = inst_cream->op2; + + if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) { + u32 lo_val = 0; + u32 hi_val = 0; + + // UHADD16 if (op2 == 0x00) { - lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF); - hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF); + lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF); + hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); } - // UQASX + // UHASX else if (op2 == 0x01) { - lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF); - hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF); + lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); + hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF); } - // UQSAX + // UHSAX else if (op2 == 0x02) { - lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF); - hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF); + lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF); + hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF); } - // UQSUB16 + // UHSUB16 else if (op2 == 0x03) { - lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF); - hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF); + lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF); + hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF); } - // UQADD8 - else if (op2 == 0x04) { - lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) | - ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8; - hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) | - ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8; + + lo_val >>= 1; + hi_val >>= 1; + + RD = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16); + } else if (op2 == 0x04 || op2 == 0x07) { + u32 sum1; + u32 sum2; + u32 sum3; + u32 sum4; + + // UHADD8 + if (op2 == 0x04) { + sum1 = (rn_val & 0xFF) + (rm_val & 0xFF); + sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF); + sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF); + sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF); } - // UQSUB8 + // UHSUB8 else { - lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) | - ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8; - hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) | - ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8; + sum1 = (rn_val & 0xFF) - (rm_val & 0xFF); + sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF); + sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF); + sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF); } - RD = ((lo_val & 0xFFFF) | hi_val << 16); + sum1 >>= 1; + sum2 >>= 1; + sum3 >>= 1; + sum4 >>= 1; + + RD = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | + ((sum4 & 0xFF) << 24); } + } + + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(generic_arm_inst)); - FETCH_INST; - GOTO_NEXT_INST; +UMAAL_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + umaal_inst* const inst_cream = (umaal_inst*)inst_base->component; + const u64 rm = RM; + const u64 rn = RN; + const u64 rd_lo = RDLO; + const u64 rd_hi = RDHI; + const u64 result = (rm * rn) + rd_lo + rd_hi; + + RDLO = (result & 0xFFFFFFFF); + RDHI = ((result >> 32) & 0xFFFFFFFF); + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(umaal_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +UMLAL_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + umlal_inst* inst_cream = (umlal_inst*)inst_base->component; + unsigned long long int rm = RM; + unsigned long long int rs = RS; + unsigned long long int rst = rm * rs; + unsigned long long int add = ((unsigned long long)RDHI) << 32; + add += RDLO; + rst += add; + RDLO = BITS(rst, 0, 31); + RDHI = BITS(rst, 32, 63); + + if (inst_cream->S) { + cpu->NFlag = BIT(RDHI, 31); + cpu->ZFlag = (RDHI == 0 && RDLO == 0); + } + } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(umlal_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +UMULL_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + umull_inst* inst_cream = (umull_inst*)inst_base->component; + unsigned long long int rm = RM; + unsigned long long int rs = RS; + unsigned long long int rst = rm * rs; + RDHI = BITS(rst, 32, 63); + RDLO = BITS(rst, 0, 31); + + if (inst_cream->S) { + cpu->NFlag = BIT(RDHI, 31); + cpu->ZFlag = (RDHI == 0 && RDLO == 0); + } } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(umull_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} +B_2_THUMB : { + b_2_thumb* inst_cream = (b_2_thumb*)inst_base->component; + cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; + INC_PC(sizeof(b_2_thumb)); + goto DISPATCH; +} +B_COND_THUMB : { + b_cond_thumb* inst_cream = (b_cond_thumb*)inst_base->component; - USAD8_INST: - USADA8_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; + if (CondPassed(cpu, inst_cream->cond)) + cpu->Reg[15] = cpu->Reg[15] + 4 + inst_cream->imm; + else + cpu->Reg[15] += 2; - const u8 ra_idx = inst_cream->Ra; - const u32 rm_val = RM; - const u32 rn_val = RN; + INC_PC(sizeof(b_cond_thumb)); + goto DISPATCH; +} +BL_1_THUMB : { + bl_1_thumb* inst_cream = (bl_1_thumb*)inst_base->component; + cpu->Reg[14] = cpu->Reg[15] + 4 + inst_cream->imm; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(bl_1_thumb)); + FETCH_INST; + GOTO_NEXT_INST; +} +BL_2_THUMB : { + bl_2_thumb* inst_cream = (bl_2_thumb*)inst_base->component; + int tmp = ((cpu->Reg[15] + 2) | 1); + cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm); + cpu->Reg[14] = tmp; + INC_PC(sizeof(bl_2_thumb)); + goto DISPATCH; +} +BLX_1_THUMB : { + // BLX 1 for armv5t and above + u32 tmp = cpu->Reg[15]; + blx_1_thumb* inst_cream = (blx_1_thumb*)inst_base->component; + cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC; + cpu->Reg[14] = ((tmp + 2) | 1); + cpu->TFlag = 0; + INC_PC(sizeof(blx_1_thumb)); + goto DISPATCH; +} - const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF); - const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF); - const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF); - const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF); +UQADD8_INST: +UQADD16_INST: +UQADDSUBX_INST: +UQSUB8_INST: +UQSUB16_INST: +UQSUBADDX_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; + + const u8 op2 = inst_cream->op2; + const u32 rm_val = RM; + const u32 rn_val = RN; + + u16 lo_val = 0; + u16 hi_val = 0; + + // UQADD16 + if (op2 == 0x00) { + lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF); + hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF); + } + // UQASX + else if (op2 == 0x01) { + lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF); + hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF); + } + // UQSAX + else if (op2 == 0x02) { + lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF); + hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF); + } + // UQSUB16 + else if (op2 == 0x03) { + lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF); + hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF); + } + // UQADD8 + else if (op2 == 0x04) { + lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) | + ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8; + hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) | + ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8; + } + // UQSUB8 + else { + lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) | + ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8; + hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) | + ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8; + } + + RD = ((lo_val & 0xFFFF) | hi_val << 16); + } - u32 finalDif = (diff1 + diff2 + diff3 + diff4); + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - // Op is USADA8 if true. - if (ra_idx != 15) - finalDif += cpu->Reg[ra_idx]; +USAD8_INST: +USADA8_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; - RD = finalDif; - } + const u8 ra_idx = inst_cream->Ra; + const u32 rm_val = RM; + const u32 rn_val = RN; + + const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF); + const u8 diff2 = + ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF); + const u8 diff3 = + ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF); + const u8 diff4 = + ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF); - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(generic_arm_inst)); - FETCH_INST; - GOTO_NEXT_INST; + u32 finalDif = (diff1 + diff2 + diff3 + diff4); + + // Op is USADA8 if true. + if (ra_idx != 15) + finalDif += cpu->Reg[ra_idx]; + + RD = finalDif; } - USAT_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - ssat_inst* const inst_cream = (ssat_inst*)inst_base->component; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(generic_arm_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - u8 shift_type = inst_cream->shift_type; - u8 shift_amount = inst_cream->imm5; - u32 rn_val = RN; +USAT_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + ssat_inst* const inst_cream = (ssat_inst*)inst_base->component; - // 32-bit ASR is encoded as an amount of 0. - if (shift_type == 1 && shift_amount == 0) - shift_amount = 31; + u8 shift_type = inst_cream->shift_type; + u8 shift_amount = inst_cream->imm5; + u32 rn_val = RN; - if (shift_type == 0) - rn_val <<= shift_amount; - else if (shift_type == 1) - rn_val = ((s32)rn_val >> shift_amount); + // 32-bit ASR is encoded as an amount of 0. + if (shift_type == 1 && shift_amount == 0) + shift_amount = 31; - bool saturated = false; - rn_val = ARMul_UnsignedSatQ(rn_val, inst_cream->sat_imm, &saturated); + if (shift_type == 0) + rn_val <<= shift_amount; + else if (shift_type == 1) + rn_val = ((s32)rn_val >> shift_amount); - if (saturated) - cpu->Cpsr |= (1 << 27); + bool saturated = false; + rn_val = ARMul_UnsignedSatQ(rn_val, inst_cream->sat_imm, &saturated); - RD = rn_val; - } + if (saturated) + cpu->Cpsr |= (1 << 27); - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ssat_inst)); - FETCH_INST; - GOTO_NEXT_INST; + RD = rn_val; } - USAT16_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - ssat_inst* const inst_cream = (ssat_inst*)inst_base->component; - const u8 saturate_to = inst_cream->sat_imm; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ssat_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - bool sat1 = false; - bool sat2 = false; +USAT16_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + ssat_inst* const inst_cream = (ssat_inst*)inst_base->component; + const u8 saturate_to = inst_cream->sat_imm; - RD = (ARMul_UnsignedSatQ((s16)RN, saturate_to, &sat1) & 0xFFFF) | - ARMul_UnsignedSatQ((s32)RN >> 16, saturate_to, &sat2) << 16; + bool sat1 = false; + bool sat2 = false; - if (sat1 || sat2) - cpu->Cpsr |= (1 << 27); - } + RD = (ARMul_UnsignedSatQ((s16)RN, saturate_to, &sat1) & 0xFFFF) | + ARMul_UnsignedSatQ((s32)RN >> 16, saturate_to, &sat2) << 16; - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(ssat_inst)); - FETCH_INST; - GOTO_NEXT_INST; + if (sat1 || sat2) + cpu->Cpsr |= (1 << 27); } - UXTAB16_INST: - UXTB16_INST: - { - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component; + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(ssat_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - const u8 rn_idx = inst_cream->Rn; - const u32 rm_val = RM; - const u32 rotation = inst_cream->rotate * 8; - const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation)); +UXTAB16_INST: +UXTB16_INST : { + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component; - // UXTB16, otherwise UXTAB16 - if (rn_idx == 15) { - RD = rotated_rm & 0x00FF00FF; - } else { - const u32 rn_val = RN; - const u8 lo_rotated = (rotated_rm & 0xFF); - const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated; - const u8 hi_rotated = (rotated_rm >> 16) & 0xFF; - const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated; + const u8 rn_idx = inst_cream->Rn; + const u32 rm_val = RM; + const u32 rotation = inst_cream->rotate * 8; + const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation)); - RD = ((hi_result << 16) | (lo_result & 0xFFFF)); - } - } + // UXTB16, otherwise UXTAB16 + if (rn_idx == 15) { + RD = rotated_rm & 0x00FF00FF; + } else { + const u32 rn_val = RN; + const u8 lo_rotated = (rotated_rm & 0xFF); + const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated; + const u8 hi_rotated = (rotated_rm >> 16) & 0xFF; + const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated; - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC(sizeof(uxtab_inst)); - FETCH_INST; - GOTO_NEXT_INST; + RD = ((hi_result << 16) | (lo_result & 0xFFFF)); + } } - WFE_INST: - { - // Stubbed, as WFE is a hint instruction. - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - LOG_TRACE(Core_ARM11, "WFE executed."); - } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC(sizeof(uxtab_inst)); + FETCH_INST; + GOTO_NEXT_INST; +} - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC_STUB; - FETCH_INST; - GOTO_NEXT_INST; +WFE_INST : { + // Stubbed, as WFE is a hint instruction. + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + LOG_TRACE(Core_ARM11, "WFE executed."); } - WFI_INST: - { - // Stubbed, as WFI is a hint instruction. - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - LOG_TRACE(Core_ARM11, "WFI executed."); - } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC_STUB; + FETCH_INST; + GOTO_NEXT_INST; +} - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC_STUB; - FETCH_INST; - GOTO_NEXT_INST; +WFI_INST : { + // Stubbed, as WFI is a hint instruction. + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + LOG_TRACE(Core_ARM11, "WFI executed."); } - YIELD_INST: - { - // Stubbed, as YIELD is a hint instruction. - if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { - LOG_TRACE(Core_ARM11, "YIELD executed."); - } + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC_STUB; + FETCH_INST; + GOTO_NEXT_INST; +} - cpu->Reg[15] += cpu->GetInstructionSize(); - INC_PC_STUB; - FETCH_INST; - GOTO_NEXT_INST; +YIELD_INST : { + // Stubbed, as YIELD is a hint instruction. + if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { + LOG_TRACE(Core_ARM11, "YIELD executed."); } - #define VFP_INTERPRETER_IMPL - #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" - #undef VFP_INTERPRETER_IMPL + cpu->Reg[15] += cpu->GetInstructionSize(); + INC_PC_STUB; + FETCH_INST; + GOTO_NEXT_INST; +} - END: - { - SAVE_NZCVT; - cpu->NumInstrsToExecute = 0; - return num_instrs; - } - INIT_INST_LENGTH: - { - cpu->NumInstrsToExecute = 0; - return num_instrs; - } +#define VFP_INTERPRETER_IMPL +#include "core/arm/skyeye_common/vfp/vfpinstr.cpp" +#undef VFP_INTERPRETER_IMPL + +END : { + SAVE_NZCVT; + cpu->NumInstrsToExecute = 0; + return num_instrs; +} +INIT_INST_LENGTH : { + cpu->NumInstrsToExecute = 0; + return num_instrs; +} } diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.cpp b/src/core/arm/dyncom/arm_dyncom_thumb.cpp index 3576370d1..2a3dd0f53 100644 --- a/src/core/arm/dyncom/arm_dyncom_thumb.cpp +++ b/src/core/arm/dyncom/arm_dyncom_thumb.cpp @@ -21,50 +21,48 @@ ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u3 *ainstr = 0xDEADC0DE; // Debugging to catch non updates switch ((tinstr & 0xF800) >> 11) { - case 0: // LSL - case 1: // LSR - case 2: // ASR - *ainstr = 0xE1B00000 // base opcode - | ((tinstr & 0x1800) >> (11 - 5)) // shift type - |((tinstr & 0x07C0) << (7 - 6)) // imm5 - |((tinstr & 0x0038) >> 3) // Rs - |((tinstr & 0x0007) << 12); // Rd + case 0: // LSL + case 1: // LSR + case 2: // ASR + *ainstr = 0xE1B00000 // base opcode + | ((tinstr & 0x1800) >> (11 - 5)) // shift type + | ((tinstr & 0x07C0) << (7 - 6)) // imm5 + | ((tinstr & 0x0038) >> 3) // Rs + | ((tinstr & 0x0007) << 12); // Rd break; case 3: // ADD/SUB - { - static const u32 subset[4] = { - 0xE0900000, // ADDS Rd,Rs,Rn - 0xE0500000, // SUBS Rd,Rs,Rn - 0xE2900000, // ADDS Rd,Rs,#imm3 - 0xE2500000 // SUBS Rd,Rs,#imm3 - }; - // It is quicker indexing into a table, than performing switch or conditionals: - *ainstr = subset[(tinstr & 0x0600) >> 9] // base opcode - |((tinstr & 0x01C0) >> 6) // Rn or imm3 - |((tinstr & 0x0038) << (16 - 3)) // Rs - |((tinstr & 0x0007) << (12 - 0)); // Rd - } - break; + { + static const u32 subset[4] = { + 0xE0900000, // ADDS Rd,Rs,Rn + 0xE0500000, // SUBS Rd,Rs,Rn + 0xE2900000, // ADDS Rd,Rs,#imm3 + 0xE2500000 // SUBS Rd,Rs,#imm3 + }; + // It is quicker indexing into a table, than performing switch or conditionals: + *ainstr = subset[(tinstr & 0x0600) >> 9] // base opcode + | ((tinstr & 0x01C0) >> 6) // Rn or imm3 + | ((tinstr & 0x0038) << (16 - 3)) // Rs + | ((tinstr & 0x0007) << (12 - 0)); // Rd + } break; case 4: // MOV case 5: // CMP case 6: // ADD case 7: // SUB - { - static const u32 subset[4] = { - 0xE3B00000, // MOVS Rd,#imm8 - 0xE3500000, // CMP Rd,#imm8 - 0xE2900000, // ADDS Rd,Rd,#imm8 - 0xE2500000, // SUBS Rd,Rd,#imm8 - }; - - *ainstr = subset[(tinstr & 0x1800) >> 11] // base opcode - |((tinstr & 0x00FF) >> 0) // imm8 - |((tinstr & 0x0700) << (16 - 8)) // Rn - |((tinstr & 0x0700) << (12 - 8)); // Rd - } - break; + { + static const u32 subset[4] = { + 0xE3B00000, // MOVS Rd,#imm8 + 0xE3500000, // CMP Rd,#imm8 + 0xE2900000, // ADDS Rd,Rd,#imm8 + 0xE2500000, // SUBS Rd,Rd,#imm8 + }; + + *ainstr = subset[(tinstr & 0x1800) >> 11] // base opcode + | ((tinstr & 0x00FF) >> 0) // imm8 + | ((tinstr & 0x0700) << (16 - 8)) // Rn + | ((tinstr & 0x0700) << (12 - 8)); // Rd + } break; case 8: // Arithmetic and high register transfers @@ -73,56 +71,51 @@ ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u3 // large subset if ((tinstr & (1 << 10)) == 0) { - enum otype { - t_norm, - t_shift, - t_neg, - t_mul - }; + enum otype { t_norm, t_shift, t_neg, t_mul }; static const struct { u32 opcode; otype type; } subset[16] = { - { 0xE0100000, t_norm }, // ANDS Rd,Rd,Rs - { 0xE0300000, t_norm }, // EORS Rd,Rd,Rs - { 0xE1B00010, t_shift }, // MOVS Rd,Rd,LSL Rs - { 0xE1B00030, t_shift }, // MOVS Rd,Rd,LSR Rs - { 0xE1B00050, t_shift }, // MOVS Rd,Rd,ASR Rs - { 0xE0B00000, t_norm }, // ADCS Rd,Rd,Rs - { 0xE0D00000, t_norm }, // SBCS Rd,Rd,Rs - { 0xE1B00070, t_shift }, // MOVS Rd,Rd,ROR Rs - { 0xE1100000, t_norm }, // TST Rd,Rs - { 0xE2700000, t_neg }, // RSBS Rd,Rs,#0 - { 0xE1500000, t_norm }, // CMP Rd,Rs - { 0xE1700000, t_norm }, // CMN Rd,Rs - { 0xE1900000, t_norm }, // ORRS Rd,Rd,Rs - { 0xE0100090, t_mul }, // MULS Rd,Rd,Rs - { 0xE1D00000, t_norm }, // BICS Rd,Rd,Rs - { 0xE1F00000, t_norm } // MVNS Rd,Rs + {0xE0100000, t_norm}, // ANDS Rd,Rd,Rs + {0xE0300000, t_norm}, // EORS Rd,Rd,Rs + {0xE1B00010, t_shift}, // MOVS Rd,Rd,LSL Rs + {0xE1B00030, t_shift}, // MOVS Rd,Rd,LSR Rs + {0xE1B00050, t_shift}, // MOVS Rd,Rd,ASR Rs + {0xE0B00000, t_norm}, // ADCS Rd,Rd,Rs + {0xE0D00000, t_norm}, // SBCS Rd,Rd,Rs + {0xE1B00070, t_shift}, // MOVS Rd,Rd,ROR Rs + {0xE1100000, t_norm}, // TST Rd,Rs + {0xE2700000, t_neg}, // RSBS Rd,Rs,#0 + {0xE1500000, t_norm}, // CMP Rd,Rs + {0xE1700000, t_norm}, // CMN Rd,Rs + {0xE1900000, t_norm}, // ORRS Rd,Rd,Rs + {0xE0100090, t_mul}, // MULS Rd,Rd,Rs + {0xE1D00000, t_norm}, // BICS Rd,Rd,Rs + {0xE1F00000, t_norm} // MVNS Rd,Rs }; *ainstr = subset[(tinstr & 0x03C0) >> 6].opcode; // base switch (subset[(tinstr & 0x03C0) >> 6].type) { case t_norm: - *ainstr |= ((tinstr & 0x0007) << 16) // Rn - |((tinstr & 0x0007) << 12) // Rd - |((tinstr & 0x0038) >> 3); // Rs + *ainstr |= ((tinstr & 0x0007) << 16) // Rn + | ((tinstr & 0x0007) << 12) // Rd + | ((tinstr & 0x0038) >> 3); // Rs break; case t_shift: - *ainstr |= ((tinstr & 0x0007) << 12) // Rd - |((tinstr & 0x0007) >> 0) // Rm - |((tinstr & 0x0038) << (8 - 3)); // Rs + *ainstr |= ((tinstr & 0x0007) << 12) // Rd + | ((tinstr & 0x0007) >> 0) // Rm + | ((tinstr & 0x0038) << (8 - 3)); // Rs break; case t_neg: - *ainstr |= ((tinstr & 0x0007) << 12) // Rd - |((tinstr & 0x0038) << (16 - 3)); // Rn + *ainstr |= ((tinstr & 0x0007) << 12) // Rd + | ((tinstr & 0x0038) << (16 - 3)); // Rn break; case t_mul: - *ainstr |= ((tinstr & 0x0007) << 16) // Rd - |((tinstr & 0x0007) << 8) // Rs - |((tinstr & 0x0038) >> 3); // Rm + *ainstr |= ((tinstr & 0x0007) << 16) // Rd + | ((tinstr & 0x0007) << 8) // Rs + | ((tinstr & 0x0038) >> 3); // Rm break; } } else { @@ -133,109 +126,106 @@ ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u3 Rd += 8; switch ((tinstr & 0x03C0) >> 6) { - case 0x0: // ADD Rd,Rd,Rs - case 0x1: // ADD Rd,Rd,Hs - case 0x2: // ADD Hd,Hd,Rs - case 0x3: // ADD Hd,Hd,Hs - *ainstr = 0xE0800000 // base - | (Rd << 16) // Rn - |(Rd << 12) // Rd - |(Rs << 0); // Rm + case 0x0: // ADD Rd,Rd,Rs + case 0x1: // ADD Rd,Rd,Hs + case 0x2: // ADD Hd,Hd,Rs + case 0x3: // ADD Hd,Hd,Hs + *ainstr = 0xE0800000 // base + | (Rd << 16) // Rn + | (Rd << 12) // Rd + | (Rs << 0); // Rm break; - case 0x4: // CMP Rd,Rs - case 0x5: // CMP Rd,Hs - case 0x6: // CMP Hd,Rs - case 0x7: // CMP Hd,Hs - *ainstr = 0xE1500000 // base - | (Rd << 16) // Rn - |(Rs << 0); // Rm + case 0x4: // CMP Rd,Rs + case 0x5: // CMP Rd,Hs + case 0x6: // CMP Hd,Rs + case 0x7: // CMP Hd,Hs + *ainstr = 0xE1500000 // base + | (Rd << 16) // Rn + | (Rs << 0); // Rm break; - case 0x8: // MOV Rd,Rs - case 0x9: // MOV Rd,Hs - case 0xA: // MOV Hd,Rs - case 0xB: // MOV Hd,Hs - *ainstr = 0xE1A00000 // base - |(Rd << 12) // Rd - |(Rs << 0); // Rm + case 0x8: // MOV Rd,Rs + case 0x9: // MOV Rd,Hs + case 0xA: // MOV Hd,Rs + case 0xB: // MOV Hd,Hs + *ainstr = 0xE1A00000 // base + | (Rd << 12) // Rd + | (Rs << 0); // Rm break; - case 0xC: // BX Rs - case 0xD: // BX Hs - *ainstr = 0xE12FFF10 // base - | ((tinstr & 0x0078) >> 3); // Rd + case 0xC: // BX Rs + case 0xD: // BX Hs + *ainstr = 0xE12FFF10 // base + | ((tinstr & 0x0078) >> 3); // Rd break; - case 0xE: // BLX - case 0xF: // BLX - *ainstr = 0xE1200030 // base - | (Rs << 0); // Rm + case 0xE: // BLX + case 0xF: // BLX + *ainstr = 0xE1200030 // base + | (Rs << 0); // Rm break; } } break; - case 9: // LDR Rd,[PC,#imm8] - *ainstr = 0xE59F0000 // base - | ((tinstr & 0x0700) << (12 - 8)) // Rd - |((tinstr & 0x00FF) << (2 - 0)); // off8 + case 9: // LDR Rd,[PC,#imm8] + *ainstr = 0xE59F0000 // base + | ((tinstr & 0x0700) << (12 - 8)) // Rd + | ((tinstr & 0x00FF) << (2 - 0)); // off8 break; case 10: - case 11: - { - static const u32 subset[8] = { - 0xE7800000, // STR Rd,[Rb,Ro] - 0xE18000B0, // STRH Rd,[Rb,Ro] - 0xE7C00000, // STRB Rd,[Rb,Ro] - 0xE19000D0, // LDRSB Rd,[Rb,Ro] - 0xE7900000, // LDR Rd,[Rb,Ro] - 0xE19000B0, // LDRH Rd,[Rb,Ro] - 0xE7D00000, // LDRB Rd,[Rb,Ro] - 0xE19000F0 // LDRSH Rd,[Rb,Ro] - }; - - *ainstr = subset[(tinstr & 0xE00) >> 9] // base - |((tinstr & 0x0007) << (12 - 0)) // Rd - |((tinstr & 0x0038) << (16 - 3)) // Rb - |((tinstr & 0x01C0) >> 6); // Ro - } - break; + case 11: { + static const u32 subset[8] = { + 0xE7800000, // STR Rd,[Rb,Ro] + 0xE18000B0, // STRH Rd,[Rb,Ro] + 0xE7C00000, // STRB Rd,[Rb,Ro] + 0xE19000D0, // LDRSB Rd,[Rb,Ro] + 0xE7900000, // LDR Rd,[Rb,Ro] + 0xE19000B0, // LDRH Rd,[Rb,Ro] + 0xE7D00000, // LDRB Rd,[Rb,Ro] + 0xE19000F0 // LDRSH Rd,[Rb,Ro] + }; + + *ainstr = subset[(tinstr & 0xE00) >> 9] // base + | ((tinstr & 0x0007) << (12 - 0)) // Rd + | ((tinstr & 0x0038) << (16 - 3)) // Rb + | ((tinstr & 0x01C0) >> 6); // Ro + } break; case 12: // STR Rd,[Rb,#imm5] case 13: // LDR Rd,[Rb,#imm5] case 14: // STRB Rd,[Rb,#imm5] case 15: // LDRB Rd,[Rb,#imm5] - { - static const u32 subset[4] = { - 0xE5800000, // STR Rd,[Rb,#imm5] - 0xE5900000, // LDR Rd,[Rb,#imm5] - 0xE5C00000, // STRB Rd,[Rb,#imm5] - 0xE5D00000 // LDRB Rd,[Rb,#imm5] - }; - // The offset range defends on whether we are transferring a byte or word value: - *ainstr = subset[(tinstr & 0x1800) >> 11] // base - |((tinstr & 0x0007) << (12 - 0)) // Rd - |((tinstr & 0x0038) << (16 - 3)) // Rb - |((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); // off5 - } + { + static const u32 subset[4] = { + 0xE5800000, // STR Rd,[Rb,#imm5] + 0xE5900000, // LDR Rd,[Rb,#imm5] + 0xE5C00000, // STRB Rd,[Rb,#imm5] + 0xE5D00000 // LDRB Rd,[Rb,#imm5] + }; + // The offset range defends on whether we are transferring a byte or word value: + *ainstr = subset[(tinstr & 0x1800) >> 11] // base + | ((tinstr & 0x0007) << (12 - 0)) // Rd + | ((tinstr & 0x0038) << (16 - 3)) // Rb + | ((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2))); // off5 + } break; + + case 16: // STRH Rd,[Rb,#imm5] + case 17: // LDRH Rd,[Rb,#imm5] + *ainstr = ((tinstr & (1 << 11)) // base + ? 0xE1D000B0 // LDRH + : 0xE1C000B0) // STRH + | ((tinstr & 0x0007) << (12 - 0)) // Rd + | ((tinstr & 0x0038) << (16 - 3)) // Rb + | ((tinstr & 0x01C0) >> (6 - 1)) // off5, low nibble + | ((tinstr & 0x0600) >> (9 - 8)); // off5, high nibble break; - case 16: // STRH Rd,[Rb,#imm5] - case 17: // LDRH Rd,[Rb,#imm5] - *ainstr = ((tinstr & (1 << 11)) // base - ? 0xE1D000B0 // LDRH - : 0xE1C000B0) // STRH - |((tinstr & 0x0007) << (12 - 0)) // Rd - |((tinstr & 0x0038) << (16 - 3)) // Rb - |((tinstr & 0x01C0) >> (6 - 1)) // off5, low nibble - |((tinstr & 0x0600) >> (9 - 8)); // off5, high nibble - break; - - case 18: // STR Rd,[SP,#imm8] - case 19: // LDR Rd,[SP,#imm8] - *ainstr = ((tinstr & (1 << 11)) // base - ? 0xE59D0000 // LDR - : 0xE58D0000) // STR - |((tinstr & 0x0700) << (12 - 8)) // Rd - |((tinstr & 0x00FF) << 2); // off8 + case 18: // STR Rd,[SP,#imm8] + case 19: // LDR Rd,[SP,#imm8] + *ainstr = ((tinstr & (1 << 11)) // base + ? 0xE59D0000 // LDR + : 0xE58D0000) // STR + | ((tinstr & 0x0700) << (12 - 8)) // Rd + | ((tinstr & 0x00FF) << 2); // off8 break; case 20: // ADD Rd,PC,#imm8 @@ -246,14 +236,15 @@ ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u3 // NOTE: The PC value used here should by word aligned. We encode shift-left-by-2 in the // rotate immediate field, so no shift of off8 is needed. - *ainstr = 0xE28F0F00 // base - | ((tinstr & 0x0700) << (12 - 8)) // Rd - |(tinstr & 0x00FF); // off8 + *ainstr = 0xE28F0F00 // base + | ((tinstr & 0x0700) << (12 - 8)) // Rd + | (tinstr & 0x00FF); // off8 } else { - // We encode shift-left-by-2 in the rotate immediate field, so no shift of off8 is needed. - *ainstr = 0xE28D0F00 // base - | ((tinstr & 0x0700) << (12 - 8)) // Rd - |(tinstr & 0x00FF); // off8 + // We encode shift-left-by-2 in the rotate immediate field, so no shift of off8 is + // needed. + *ainstr = 0xE28D0F00 // base + | ((tinstr & 0x0700) << (12 - 8)) // Rd + | (tinstr & 0x00FF); // off8 } break; @@ -261,15 +252,15 @@ ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u3 case 23: if ((tinstr & 0x0F00) == 0x0000) { // NOTE: The instruction contains a shift left of 2 equivalent (implemented as ROR #30): - *ainstr = ((tinstr & (1 << 7)) // base - ? 0xE24DDF00 // SUB - : 0xE28DDF00) // ADD - |(tinstr & 0x007F); // off7 + *ainstr = ((tinstr & (1 << 7)) // base + ? 0xE24DDF00 // SUB + : 0xE28DDF00) // ADD + | (tinstr & 0x007F); // off7 } else if ((tinstr & 0x0F00) == 0x0e00) { // BKPT - *ainstr = 0xEF000000 // base - | BITS(tinstr, 0, 3) // imm4 field; - | (BITS(tinstr, 4, 7) << 8); // beginning 4 bits of imm12 + *ainstr = 0xEF000000 // base + | BITS(tinstr, 0, 3) // imm4 field; + | (BITS(tinstr, 4, 7) << 8); // beginning 4 bits of imm12 } else if ((tinstr & 0x0F00) == 0x0200) { static const u32 subset[4] = { 0xE6BF0070, // SXTH @@ -278,21 +269,21 @@ ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u3 0xE6EF0070, // UXTB }; - *ainstr = subset[BITS(tinstr, 6, 7)] // base - | (BITS(tinstr, 0, 2) << 12) // Rd - | BITS(tinstr, 3, 5); // Rm + *ainstr = subset[BITS(tinstr, 6, 7)] // base + | (BITS(tinstr, 0, 2) << 12) // Rd + | BITS(tinstr, 3, 5); // Rm } else if ((tinstr & 0x0F00) == 0x600) { if (BIT(tinstr, 5) == 0) { // SETEND - *ainstr = 0xF1010000 // base - | (BIT(tinstr, 3) << 9); // endian specifier + *ainstr = 0xF1010000 // base + | (BIT(tinstr, 3) << 9); // endian specifier } else { // CPS - *ainstr = 0xF1080000 // base - | (BIT(tinstr, 0) << 6) // fiq bit - | (BIT(tinstr, 1) << 7) // irq bit - | (BIT(tinstr, 2) << 8) // abort bit - | (BIT(tinstr, 4) << 18); // enable bit + *ainstr = 0xF1080000 // base + | (BIT(tinstr, 0) << 6) // fiq bit + | (BIT(tinstr, 1) << 7) // irq bit + | (BIT(tinstr, 2) << 8) // abort bit + | (BIT(tinstr, 4) << 18); // enable bit } } else if ((tinstr & 0x0F00) == 0x0a00) { static const u32 subset[4] = { @@ -307,9 +298,9 @@ ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u3 if (subset_index == 2) { valid = ThumbDecodeStatus::UNDEFINED; } else { - *ainstr = subset[subset_index] // base - | (BITS(tinstr, 0, 2) << 12) // Rd - | BITS(tinstr, 3, 5); // Rm + *ainstr = subset[subset_index] // base + | (BITS(tinstr, 0, 2) << 12) // Rd + | BITS(tinstr, 3, 5); // Rm } } else { static const u32 subset[4] = { @@ -319,14 +310,13 @@ ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u3 0xE8BD8000 // LDMIA sp!,{rlist,pc} }; *ainstr = subset[((tinstr & (1 << 11)) >> 10) | ((tinstr & (1 << 8)) >> 8)] // base - |(tinstr & 0x00FF); // mask8 + | (tinstr & 0x00FF); // mask8 } break; case 24: // STMIA case 25: // LDMIA - if (tinstr & (1 << 11)) - { + if (tinstr & (1 << 11)) { unsigned int base = 0xE8900000; unsigned int rn = BITS(tinstr, 8, 10); @@ -334,15 +324,13 @@ ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u3 if ((tinstr & (1 << rn)) == 0) base |= (1 << 21); - *ainstr = base // base (LDMIA) - | (rn << 16) // Rn - | (tinstr & 0x00FF); // Register list - } - else - { - *ainstr = 0xE8A00000 // base (STMIA) - | (BITS(tinstr, 8, 10) << 16) // Rn - | (tinstr & 0x00FF); // Register list + *ainstr = base // base (LDMIA) + | (rn << 16) // Rn + | (tinstr & 0x00FF); // Register list + } else { + *ainstr = 0xE8A00000 // base (STMIA) + | (BITS(tinstr, 8, 10) << 16) // Rn + | (tinstr & 0x00FF); // Register list } break; diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.h b/src/core/arm/dyncom/arm_dyncom_thumb.h index c1be3c735..231e48aa4 100644 --- a/src/core/arm/dyncom/arm_dyncom_thumb.h +++ b/src/core/arm/dyncom/arm_dyncom_thumb.h @@ -29,9 +29,9 @@ #include "common/common_types.h" enum class ThumbDecodeStatus { - UNDEFINED, // Undefined Thumb instruction - DECODED, // Instruction decoded to ARM equivalent - BRANCH, // Thumb branch (already processed) + UNDEFINED, // Undefined Thumb instruction + DECODED, // Instruction decoded to ARM equivalent + BRANCH, // Thumb branch (already processed) UNINITIALIZED, }; diff --git a/src/core/arm/dyncom/arm_dyncom_trans.cpp b/src/core/arm/dyncom/arm_dyncom_trans.cpp index 00b42c246..780638638 100644 --- a/src/core/arm/dyncom/arm_dyncom_trans.cpp +++ b/src/core/arm/dyncom/arm_dyncom_trans.cpp @@ -1,8 +1,6 @@ #include <cstdlib> - #include "common/assert.h" #include "common/common_types.h" - #include "core/arm/dyncom/arm_dyncom_interpreter.h" #include "core/arm/dyncom/arm_dyncom_trans.h" #include "core/arm/skyeye_common/armstate.h" @@ -19,24 +17,23 @@ static void* AllocBuffer(size_t size) { return static_cast<void*>(&trans_cache_buf[start]); } -#define glue(x, y) x ## y +#define glue(x, y) x##y #define INTERPRETER_TRANSLATE(s) glue(InterpreterTranslate_, s) shtop_fp_t GetShifterOp(unsigned int inst); get_addr_fp_t GetAddressingOp(unsigned int inst); get_addr_fp_t GetAddressingOpLoadStoreT(unsigned int inst); -static ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst)); - adc_inst *inst_cream = (adc_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst)); + adc_inst* inst_cream = (adc_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); inst_cream->Rn = BITS(inst, 16, 19); inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); @@ -47,17 +44,16 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index) return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst)); - add_inst *inst_cream = (add_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst)); + add_inst* inst_cream = (add_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); inst_cream->Rn = BITS(inst, 16, 19); inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); @@ -68,17 +64,16 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index) return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst)); - and_inst *inst_cream = (and_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst)); + and_inst* inst_cream = (and_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); inst_cream->Rn = BITS(inst, 16, 19); inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); @@ -89,37 +84,35 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index) return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(bbl)(unsigned int inst, int index) -{ - #define POSBRANCH ((inst & 0x7fffff) << 2) - #define NEGBRANCH ((0xff000000 |(inst & 0xffffff)) << 2) +static ARM_INST_PTR INTERPRETER_TRANSLATE(bbl)(unsigned int inst, int index) { +#define POSBRANCH ((inst & 0x7fffff) << 2) +#define NEGBRANCH ((0xff000000 | (inst & 0xffffff)) << 2) - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst)); - bbl_inst *inst_cream = (bbl_inst *)inst_base->component; + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst)); + bbl_inst* inst_cream = (bbl_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::DIRECT_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::DIRECT_BRANCH; if (BIT(inst, 24)) inst_base->br = TransExtData::CALL; - inst_cream->L = BIT(inst, 24); + inst_cream->L = BIT(inst, 24); inst_cream->signed_immed_24 = BIT(inst, 23) ? NEGBRANCH : POSBRANCH; return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst)); - bic_inst *inst_cream = (bic_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst)); + bic_inst* inst_cream = (bic_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); inst_cream->Rn = BITS(inst, 16, 19); inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); @@ -130,28 +123,26 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index) return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(bkpt)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(bkpt)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(bkpt_inst)); bkpt_inst* const inst_cream = (bkpt_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->imm = (BITS(inst, 8, 19) << 4) | BITS(inst, 0, 3); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(blx)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst)); - blx_inst *inst_cream = (blx_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(blx)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst)); + blx_inst* inst_cream = (blx_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::INDIRECT_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::INDIRECT_BRANCH; inst_cream->inst = inst; if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) { @@ -162,36 +153,34 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(blx)(unsigned int inst, int index) return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst)); - bx_inst *inst_cream = (bx_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst)); + bx_inst* inst_cream = (bx_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::INDIRECT_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::INDIRECT_BRANCH; - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rm = BITS(inst, 0, 3); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(bx)(inst, index); } static ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst)); - cdp_inst *inst_cream = (cdp_inst *)inst_base->component; + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst)); + cdp_inst* inst_cream = (cdp_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->CRm = BITS(inst, 0, 3); - inst_cream->CRd = BITS(inst, 12, 15); - inst_cream->CRn = BITS(inst, 16, 19); - inst_cream->cp_num = BITS(inst, 8, 11); + inst_cream->CRm = BITS(inst, 0, 3); + inst_cream->CRd = BITS(inst, 12, 15); + inst_cream->CRn = BITS(inst, 16, 19); + inst_cream->cp_num = BITS(inst, 8, 11); inst_cream->opcode_2 = BITS(inst, 5, 7); inst_cream->opcode_1 = BITS(inst, 20, 23); inst_cream->inst = inst; @@ -199,91 +188,85 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index) { LOG_TRACE(Core_ARM11, "inst %x index %x", inst, index); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(clrex)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst)); +static ARM_INST_PTR INTERPRETER_TRANSLATE(clrex)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst)); inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(clz)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst)); - clz_inst *inst_cream = (clz_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(clz)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst)); + clz_inst* inst_cream = (clz_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rm = BITS(inst, 0, 3); inst_cream->Rd = BITS(inst, 12, 15); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(cmn)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst)); - cmn_inst *inst_cream = (cmn_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(cmn)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst)); + cmn_inst* inst_cream = (cmn_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->I = BIT(inst, 25); + inst_cream->I = BIT(inst, 25); inst_cream->Rn = BITS(inst, 16, 19); inst_cream->shifter_operand = BITS(inst, 0, 11); inst_cream->shtop_func = GetShifterOp(inst); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(cmp)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst)); - cmp_inst *inst_cream = (cmp_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(cmp)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst)); + cmp_inst* inst_cream = (cmp_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->I = BIT(inst, 25); + inst_cream->I = BIT(inst, 25); inst_cream->Rn = BITS(inst, 16, 19); inst_cream->shifter_operand = BITS(inst, 0, 11); inst_cream->shtop_func = GetShifterOp(inst); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(cps)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst)); - cps_inst *inst_cream = (cps_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(cps)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst)); + cps_inst* inst_cream = (cps_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->imod0 = BIT(inst, 18); inst_cream->imod1 = BIT(inst, 19); - inst_cream->mmod = BIT(inst, 17); - inst_cream->A = BIT(inst, 8); - inst_cream->I = BIT(inst, 7); - inst_cream->F = BIT(inst, 6); - inst_cream->mode = BITS(inst, 0, 4); + inst_cream->mmod = BIT(inst, 17); + inst_cream->A = BIT(inst, 8); + inst_cream->I = BIT(inst, 7); + inst_cream->F = BIT(inst, 6); + inst_cream->mode = BITS(inst, 0, 4); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(cpy)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); - mov_inst *inst_cream = (mov_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(cpy)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); + mov_inst* inst_cream = (mov_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); inst_cream->shtop_func = GetShifterOp(inst); @@ -293,17 +276,16 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(cpy)(unsigned int inst, int index) } return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst)); - eor_inst *inst_cream = (eor_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst)); + eor_inst* inst_cream = (eor_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); inst_cream->Rn = BITS(inst, 16, 19); inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); @@ -314,23 +296,21 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index) return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ldc)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst)); +static ARM_INST_PTR INTERPRETER_TRANSLATE(ldc)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst)); inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ldm)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(ldm)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = GetAddressingOp(inst); @@ -340,29 +320,27 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(ldm)(unsigned int inst, int index) } return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(sxth)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); - sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(sxth)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); + sxtb_inst* inst_cream = (sxtb_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); inst_cream->rotate = BITS(inst, 10, 11); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ldr)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(ldr)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = GetAddressingOp(inst); @@ -373,14 +351,13 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(ldr)(unsigned int inst, int index) return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrcond)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrcond)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = GetAddressingOp(inst); @@ -391,155 +368,143 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrcond)(unsigned int inst, int index) return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uxth)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); - uxth_inst *inst_cream = (uxth_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(uxth)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); + uxth_inst* inst_cream = (uxth_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->rotate = BITS(inst, 10, 11); - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rm = BITS(inst, 0, 3); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtah)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst)); - uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtah)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst)); + uxtah_inst* inst_cream = (uxtah_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->rotate = BITS(inst, 10, 11); - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rm = BITS(inst, 0, 3); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = GetAddressingOp(inst); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index) { arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = GetAddressingOpLoadStoreT(inst); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = GetAddressingOp(inst); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); - generic_arm_inst *inst_cream = (generic_arm_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = (BITS(inst, 12, 15) == 15) ? TransExtData::INDIRECT_BRANCH : TransExtData::NON_BRANCH; // Branch if dest is R15 + inst_base->idx = index; + inst_base->br = (BITS(inst, 12, 15) == 15) ? TransExtData::INDIRECT_BRANCH + : TransExtData::NON_BRANCH; // Branch if dest is R15 inst_cream->Rn = BITS(inst, 16, 19); inst_cream->Rd = BITS(inst, 12, 15); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(ldrex)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexh)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexh)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(ldrex)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexd)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexd)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(ldrex)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = GetAddressingOp(inst); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = GetAddressingOp(inst); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = GetAddressingOp(inst); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index) { arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = GetAddressingOpLoadStoreT(inst); @@ -549,70 +514,66 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index) } return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(mcr)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst)); - mcr_inst *inst_cream = (mcr_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(mcr)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst)); + mcr_inst* inst_cream = (mcr_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->crn = BITS(inst, 16, 19); - inst_cream->crm = BITS(inst, 0, 3); + inst_cream->crn = BITS(inst, 16, 19); + inst_cream->crm = BITS(inst, 0, 3); inst_cream->opcode_1 = BITS(inst, 21, 23); - inst_cream->opcode_2 = BITS(inst, 5, 7); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->cp_num = BITS(inst, 8, 11); - inst_cream->inst = inst; + inst_cream->opcode_2 = BITS(inst, 5, 7); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->cp_num = BITS(inst, 8, 11); + inst_cream->inst = inst; return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(mcrr)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(mcrr)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mcrr_inst)); mcrr_inst* const inst_cream = (mcrr_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->crm = BITS(inst, 0, 3); + inst_cream->crm = BITS(inst, 0, 3); inst_cream->opcode_1 = BITS(inst, 4, 7); - inst_cream->cp_num = BITS(inst, 8, 11); - inst_cream->rt = BITS(inst, 12, 15); - inst_cream->rt2 = BITS(inst, 16, 19); + inst_cream->cp_num = BITS(inst, 8, 11); + inst_cream->rt = BITS(inst, 12, 15); + inst_cream->rt2 = BITS(inst, 16, 19); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(mla)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst)); - mla_inst *inst_cream = (mla_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(mla)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst)); + mla_inst* inst_cream = (mla_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->S = BIT(inst, 20); + inst_cream->S = BIT(inst, 20); inst_cream->Rn = BITS(inst, 12, 15); inst_cream->Rd = BITS(inst, 16, 19); - inst_cream->Rs = BITS(inst, 8, 11); - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rs = BITS(inst, 8, 11); + inst_cream->Rm = BITS(inst, 0, 3); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(mov)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); - mov_inst *inst_cream = (mov_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(mov)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst)); + mov_inst* inst_cream = (mov_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); inst_cream->shtop_func = GetShifterOp(inst); @@ -622,85 +583,79 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(mov)(unsigned int inst, int index) } return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(mrc)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst)); - mrc_inst *inst_cream = (mrc_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(mrc)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst)); + mrc_inst* inst_cream = (mrc_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->crn = BITS(inst, 16, 19); - inst_cream->crm = BITS(inst, 0, 3); + inst_cream->crn = BITS(inst, 16, 19); + inst_cream->crm = BITS(inst, 0, 3); inst_cream->opcode_1 = BITS(inst, 21, 23); - inst_cream->opcode_2 = BITS(inst, 5, 7); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->cp_num = BITS(inst, 8, 11); - inst_cream->inst = inst; + inst_cream->opcode_2 = BITS(inst, 5, 7); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->cp_num = BITS(inst, 8, 11); + inst_cream->inst = inst; return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(mrrc)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(mrrc)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(mcrr)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(mrs)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst)); - mrs_inst *inst_cream = (mrs_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(mrs)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst)); + mrs_inst* inst_cream = (mrs_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->R = BIT(inst, 22); + inst_cream->R = BIT(inst, 22); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(msr)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst)); - msr_inst *inst_cream = (msr_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(msr)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst)); + msr_inst* inst_cream = (msr_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->field_mask = BITS(inst, 16, 19); - inst_cream->R = BIT(inst, 22); - inst_cream->inst = inst; + inst_cream->R = BIT(inst, 22); + inst_cream->inst = inst; return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(mul)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst)); - mul_inst *inst_cream = (mul_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(mul)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst)); + mul_inst* inst_cream = (mul_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->S = BIT(inst, 20); + inst_cream->S = BIT(inst, 20); inst_cream->Rm = BITS(inst, 0, 3); inst_cream->Rs = BITS(inst, 8, 11); inst_cream->Rd = BITS(inst, 16, 19); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(mvn)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst)); - mvn_inst *inst_cream = (mvn_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(mvn)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst)); + mvn_inst* inst_cream = (mvn_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); inst_cream->shtop_func = GetShifterOp(inst); @@ -709,19 +664,17 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(mvn)(unsigned int inst, int index) inst_base->br = TransExtData::INDIRECT_BRANCH; } return inst_base; - } -static ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst)); - orr_inst *inst_cream = (orr_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst)); + orr_inst* inst_cream = (orr_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); inst_cream->Rd = BITS(inst, 12, 15); inst_cream->Rn = BITS(inst, 16, 19); inst_cream->shifter_operand = BITS(inst, 0, 11); @@ -734,150 +687,132 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index) } // NOP introduced in ARMv6K. -static ARM_INST_PTR INTERPRETER_TRANSLATE(nop)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(nop)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst)); inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pkh_inst)); - pkh_inst *inst_cream = (pkh_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(pkh_inst)); + pkh_inst* inst_cream = (pkh_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rm = BITS(inst, 0, 3); inst_cream->imm = BITS(inst, 7, 11); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(pkhbt)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst)); +static ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst)); inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->op1 = BITS(inst, 21, 22); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(qadd)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(qadd)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(qadd)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->op1 = BITS(inst, 20, 21); inst_cream->op2 = BITS(inst, 5, 7); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(qadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(qadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(qadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(qadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(qadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst)); rev_inst* const inst_cream = (rev_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->op1 = BITS(inst, 20, 22); inst_cream->op2 = BITS(inst, 5, 7); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(rev)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index) -{ - return INTERPRETER_TRANSLATE(rev)(inst, index); +static ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index) { + return INTERPRETER_TRANSLATE(rev)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); ldst_inst* const inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = AL; - inst_base->idx = index; - inst_base->br = TransExtData::INDIRECT_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::INDIRECT_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = GetAddressingOp(inst); @@ -885,17 +820,16 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index) return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst)); - rsb_inst *inst_cream = (rsb_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst)); + rsb_inst* inst_cream = (rsb_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); inst_cream->Rn = BITS(inst, 16, 19); inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); @@ -906,17 +840,16 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index) return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst)); - rsc_inst *inst_cream = (rsc_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst)); + rsc_inst* inst_cream = (rsc_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); inst_cream->Rn = BITS(inst, 16, 19); inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); @@ -927,55 +860,48 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index) return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->op1 = BITS(inst, 20, 21); inst_cream->op2 = BITS(inst, 5, 7); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(sadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(sadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(sadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(sadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(sadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst)); - sbc_inst *inst_cream = (sbc_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst)); + sbc_inst* inst_cream = (sbc_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); inst_cream->Rn = BITS(inst, 16, 19); inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); @@ -986,98 +912,88 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index) return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->op1 = BITS(inst, 20, 22); inst_cream->op2 = BITS(inst, 5, 7); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(setend_inst)); setend_inst* const inst_cream = (setend_inst*)inst_base->component; inst_base->cond = AL; - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->set_bigend = BIT(inst, 9); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(sev)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(sev)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst)); inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->op1 = BITS(inst, 20, 21); inst_cream->op2 = BITS(inst, 5, 7); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(shadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(shadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(shadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(shadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(shadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst)); - smla_inst *inst_cream = (smla_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst)); + smla_inst* inst_cream = (smla_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->x = BIT(inst, 5); - inst_cream->y = BIT(inst, 6); + inst_cream->x = BIT(inst, 5); + inst_cream->y = BIT(inst, 6); inst_cream->Rm = BITS(inst, 0, 3); inst_cream->Rs = BITS(inst, 8, 11); inst_cream->Rd = BITS(inst, 16, 19); @@ -1086,192 +1002,176 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index) return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); smlad_inst* const inst_cream = (smlad_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->m = BIT(inst, 5); - inst_cream->Rn = BITS(inst, 0, 3); - inst_cream->Rm = BITS(inst, 8, 11); - inst_cream->Rd = BITS(inst, 16, 19); - inst_cream->Ra = BITS(inst, 12, 15); + inst_cream->m = BIT(inst, 5); + inst_cream->Rn = BITS(inst, 0, 3); + inst_cream->Rm = BITS(inst, 8, 11); + inst_cream->Rd = BITS(inst, 16, 19); + inst_cream->Ra = BITS(inst, 12, 15); inst_cream->op1 = BITS(inst, 20, 22); inst_cream->op2 = BITS(inst, 5, 7); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(smlad)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(smlad)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(smlsd)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(smlsd)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(smlad)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); - umlal_inst *inst_cream = (umlal_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); + umlal_inst* inst_cream = (umlal_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->S = BIT(inst, 20); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rs = BITS(inst, 8, 11); + inst_cream->S = BIT(inst, 20); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rs = BITS(inst, 8, 11); inst_cream->RdHi = BITS(inst, 16, 19); inst_cream->RdLo = BITS(inst, 12, 15); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlalxy_inst)); smlalxy_inst* const inst_cream = (smlalxy_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->x = BIT(inst, 5); - inst_cream->y = BIT(inst, 6); + inst_cream->x = BIT(inst, 5); + inst_cream->y = BIT(inst, 6); inst_cream->RdLo = BITS(inst, 12, 15); inst_cream->RdHi = BITS(inst, 16, 19); - inst_cream->Rn = BITS(inst, 0, 4); - inst_cream->Rm = BITS(inst, 8, 11); + inst_cream->Rn = BITS(inst, 0, 4); + inst_cream->Rm = BITS(inst, 8, 11); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); smlad_inst* const inst_cream = (smlad_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->Ra = BITS(inst, 12, 15); inst_cream->Rm = BITS(inst, 8, 11); inst_cream->Rn = BITS(inst, 0, 3); inst_cream->Rd = BITS(inst, 16, 19); - inst_cream->m = BIT(inst, 6); + inst_cream->m = BIT(inst, 6); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlald_inst)); smlald_inst* const inst_cream = (smlald_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rm = BITS(inst, 8, 11); - inst_cream->Rn = BITS(inst, 0, 3); + inst_cream->Rm = BITS(inst, 8, 11); + inst_cream->Rn = BITS(inst, 0, 3); inst_cream->RdLo = BITS(inst, 12, 15); inst_cream->RdHi = BITS(inst, 16, 19); inst_cream->swap = BIT(inst, 5); - inst_cream->op1 = BITS(inst, 20, 22); - inst_cream->op2 = BITS(inst, 5, 7); + inst_cream->op1 = BITS(inst, 20, 22); + inst_cream->op2 = BITS(inst, 5, 7); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(smlsld)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(smlsld)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(smlald)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(smmla)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(smmla)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); smlad_inst* const inst_cream = (smlad_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->m = BIT(inst, 5); - inst_cream->Ra = BITS(inst, 12, 15); - inst_cream->Rm = BITS(inst, 8, 11); - inst_cream->Rn = BITS(inst, 0, 3); - inst_cream->Rd = BITS(inst, 16, 19); + inst_cream->m = BIT(inst, 5); + inst_cream->Ra = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 8, 11); + inst_cream->Rn = BITS(inst, 0, 3); + inst_cream->Rd = BITS(inst, 16, 19); inst_cream->op1 = BITS(inst, 20, 22); inst_cream->op2 = BITS(inst, 5, 7); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(smmls)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(smmls)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(smmla)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(smmla)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst)); - smul_inst *inst_cream = (smul_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst)); + smul_inst* inst_cream = (smul_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->Rd = BITS(inst, 16, 19); - inst_cream->Rs = BITS(inst, 8, 11); - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rs = BITS(inst, 8, 11); + inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->x = BIT(inst, 5); - inst_cream->y = BIT(inst, 6); + inst_cream->x = BIT(inst, 5); + inst_cream->y = BIT(inst, 6); return inst_base; - } -static ARM_INST_PTR INTERPRETER_TRANSLATE(smull)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst)); - umull_inst *inst_cream = (umull_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(smull)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst)); + umull_inst* inst_cream = (umull_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->S = BIT(inst, 20); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rs = BITS(inst, 8, 11); + inst_cream->S = BIT(inst, 20); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rs = BITS(inst, 8, 11); inst_cream->RdHi = BITS(inst, 16, 19); inst_cream->RdLo = BITS(inst, 12, 15); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); - smlad_inst *inst_cream = (smlad_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst)); + smlad_inst* inst_cream = (smlad_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->m = BIT(inst, 6); + inst_cream->m = BIT(inst, 6); inst_cream->Rm = BITS(inst, 8, 11); inst_cream->Rn = BITS(inst, 0, 3); inst_cream->Rd = BITS(inst, 16, 19); @@ -1279,29 +1179,27 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index) return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); ldst_inst* const inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = AL; - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->inst = inst; + inst_cream->inst = inst; inst_cream->get_addr = GetAddressingOp(inst); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ssat_inst)); ssat_inst* const inst_cream = (ssat_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->Rn = BITS(inst, 0, 3); inst_cream->Rd = BITS(inst, 12, 15); @@ -1311,211 +1209,195 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index) return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ssat_inst)); ssat_inst* const inst_cream = (ssat_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rn = BITS(inst, 0, 3); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rn = BITS(inst, 0, 3); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->sat_imm = BITS(inst, 16, 19); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst)); +static ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst)); inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(stm)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(stm)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = GetAddressingOp(inst); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); - sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst)); + sxtb_inst* inst_cream = (sxtb_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); inst_cream->rotate = BITS(inst, 10, 11); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(str)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(str)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = GetAddressingOp(inst); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); - uxth_inst *inst_cream = (uxth_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst)); + uxth_inst* inst_cream = (uxth_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->rotate = BITS(inst, 10, 11); - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rm = BITS(inst, 0, 3); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst)); - uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst)); + uxtab_inst* inst_cream = (uxtab_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->rotate = BITS(inst, 10, 11); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = GetAddressingOp(inst); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index) { arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = GetAddressingOpLoadStoreT(inst); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = GetAddressingOp(inst); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); - generic_arm_inst *inst_cream = (generic_arm_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); + generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(strex)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(strexh)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(strexh)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(strex)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(strexd)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(strexd)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(strex)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); - ldst_inst *inst_cream = (ldst_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); + ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = GetAddressingOp(inst); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index) { arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); ldst_inst* inst_cream = (ldst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->inst = inst; inst_cream->get_addr = GetAddressingOpLoadStoreT(inst); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst)); - sub_inst *inst_cream = (sub_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst)); + sub_inst* inst_cream = (sub_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); inst_cream->Rn = BITS(inst, 16, 19); inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); @@ -1526,71 +1408,68 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index) return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(swi)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swi_inst)); - swi_inst *inst_cream = (swi_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(swi)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(swi_inst)); + swi_inst* inst_cream = (swi_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->num = BITS(inst, 0, 23); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(swp)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst)); - swp_inst *inst_cream = (swp_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(swp)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst)); + swp_inst* inst_cream = (swp_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index){ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst)); - swp_inst *inst_cream = (swp_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst)); + swp_inst* inst_cream = (swp_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); - inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index){ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst)); - sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst)); + sxtab_inst* inst_cream = (sxtab_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->rotate = BITS(inst, 10, 11); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst)); sxtab_inst* const inst_cream = (sxtab_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->Rm = BITS(inst, 0, 3); inst_cream->Rn = BITS(inst, 16, 19); @@ -1599,54 +1478,51 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index) return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(sxtab16)(inst, index); } static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index) { - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst)); - sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component; + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst)); + sxtah_inst* inst_cream = (sxtah_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->rotate = BITS(inst, 10, 11); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst)); - teq_inst *inst_cream = (teq_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst)); + teq_inst* inst_cream = (teq_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->I = BIT(inst, 25); - inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->I = BIT(inst, 25); + inst_cream->Rn = BITS(inst, 16, 19); inst_cream->shifter_operand = BITS(inst, 0, 11); - inst_cream->shtop_func = GetShifterOp(inst); + inst_cream->shtop_func = GetShifterOp(inst); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(tst_inst)); - tst_inst *inst_cream = (tst_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(tst_inst)); + tst_inst* inst_cream = (tst_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->I = BIT(inst, 25); - inst_cream->S = BIT(inst, 20); + inst_cream->I = BIT(inst, 25); + inst_cream->S = BIT(inst, 20); inst_cream->Rn = BITS(inst, 16, 19); inst_cream->Rd = BITS(inst, 12, 15); inst_cream->shifter_operand = BITS(inst, 0, 11); @@ -1655,309 +1531,274 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index) return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->op1 = BITS(inst, 20, 21); inst_cream->op2 = BITS(inst, 5, 7); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(uadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(uadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(uadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(uadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(uadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->op1 = BITS(inst, 20, 21); inst_cream->op2 = BITS(inst, 5, 7); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(uhadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(uhadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(uhadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(uhadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(uhadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umaal_inst)); umaal_inst* const inst_cream = (umaal_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rm = BITS(inst, 8, 11); - inst_cream->Rn = BITS(inst, 0, 3); + inst_cream->Rm = BITS(inst, 8, 11); + inst_cream->Rn = BITS(inst, 0, 3); inst_cream->RdLo = BITS(inst, 12, 15); inst_cream->RdHi = BITS(inst, 16, 19); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(umlal)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); - umlal_inst *inst_cream = (umlal_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(umlal)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst)); + umlal_inst* inst_cream = (umlal_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->S = BIT(inst, 20); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rs = BITS(inst, 8, 11); + inst_cream->S = BIT(inst, 20); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rs = BITS(inst, 8, 11); inst_cream->RdHi = BITS(inst, 16, 19); inst_cream->RdLo = BITS(inst, 12, 15); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(umull)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst)); - umull_inst *inst_cream = (umull_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(umull)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst)); + umull_inst* inst_cream = (umull_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->S = BIT(inst, 20); - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rs = BITS(inst, 8, 11); + inst_cream->S = BIT(inst, 20); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rs = BITS(inst, 8, 11); inst_cream->RdHi = BITS(inst, 16, 19); inst_cream->RdLo = BITS(inst, 12, 15); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(b_2_thumb)(unsigned int tinst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb)); - b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(b_2_thumb)(unsigned int tinst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb)); + b_2_thumb* inst_cream = (b_2_thumb*)inst_base->component; inst_cream->imm = ((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0); inst_base->idx = index; - inst_base->br = TransExtData::DIRECT_BRANCH; + inst_base->br = TransExtData::DIRECT_BRANCH; return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(b_cond_thumb)(unsigned int tinst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb)); - b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(b_cond_thumb)(unsigned int tinst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb)); + b_cond_thumb* inst_cream = (b_cond_thumb*)inst_base->component; - inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0)); + inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0)); inst_cream->cond = ((tinst >> 8) & 0xf); - inst_base->idx = index; - inst_base->br = TransExtData::DIRECT_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::DIRECT_BRANCH; return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(bl_1_thumb)(unsigned int tinst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb)); - bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(bl_1_thumb)(unsigned int tinst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb)); + bl_1_thumb* inst_cream = (bl_1_thumb*)inst_base->component; inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0)); inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->br = TransExtData::NON_BRANCH; return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(bl_2_thumb)(unsigned int tinst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb)); - bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(bl_2_thumb)(unsigned int tinst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb)); + bl_2_thumb* inst_cream = (bl_2_thumb*)inst_base->component; inst_cream->imm = (tinst & 0x07FF) << 1; inst_base->idx = index; - inst_base->br = TransExtData::DIRECT_BRANCH; + inst_base->br = TransExtData::DIRECT_BRANCH; return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_1_thumb)); - blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(blx_1_thumb)); + blx_1_thumb* inst_cream = (blx_1_thumb*)inst_base->component; - inst_cream->imm = (tinst & 0x07FF) << 1; + inst_cream->imm = (tinst & 0x07FF) << 1; inst_cream->instr = tinst; - inst_base->idx = index; - inst_base->br = TransExtData::DIRECT_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::DIRECT_BRANCH; return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->op1 = BITS(inst, 20, 21); inst_cream->op2 = BITS(inst, 5, 7); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(uqadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(uqadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(uqadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(uqadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(uqadd8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->op1 = BITS(inst, 20, 24); inst_cream->op2 = BITS(inst, 5, 7); - inst_cream->Rd = BITS(inst, 16, 19); - inst_cream->Rm = BITS(inst, 8, 11); - inst_cream->Rn = BITS(inst, 0, 3); - inst_cream->Ra = BITS(inst, 12, 15); + inst_cream->Rd = BITS(inst, 16, 19); + inst_cream->Rm = BITS(inst, 8, 11); + inst_cream->Rn = BITS(inst, 0, 3); + inst_cream->Ra = BITS(inst, 12, 15); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(usada8)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(ssat)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(ssat16)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst)); uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->Rm = BITS(inst, 0, 3); - inst_cream->Rn = BITS(inst, 16, 19); - inst_cream->Rd = BITS(inst, 12, 15); + inst_cream->Rm = BITS(inst, 0, 3); + inst_cream->Rn = BITS(inst, 16, 19); + inst_cream->Rd = BITS(inst, 12, 15); inst_cream->rotate = BITS(inst, 10, 11); return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index) { return INTERPRETER_TRANSLATE(uxtab16)(inst, index); } -static ARM_INST_PTR INTERPRETER_TRANSLATE(wfe)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(wfe)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst)); inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(wfi)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(wfi)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst)); inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; return inst_base; } -static ARM_INST_PTR INTERPRETER_TRANSLATE(yield)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(yield)(unsigned int inst, int index) { arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst)); inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; return inst_base; } @@ -1968,211 +1809,79 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(yield)(unsigned int inst, int index) #undef VFP_INTERPRETER_TRANS const transop_fp_t arm_instruction_trans[] = { - INTERPRETER_TRANSLATE(vmla), - INTERPRETER_TRANSLATE(vmls), - INTERPRETER_TRANSLATE(vnmla), - INTERPRETER_TRANSLATE(vnmls), - INTERPRETER_TRANSLATE(vnmul), - INTERPRETER_TRANSLATE(vmul), - INTERPRETER_TRANSLATE(vadd), - INTERPRETER_TRANSLATE(vsub), - INTERPRETER_TRANSLATE(vdiv), - INTERPRETER_TRANSLATE(vmovi), - INTERPRETER_TRANSLATE(vmovr), - INTERPRETER_TRANSLATE(vabs), - INTERPRETER_TRANSLATE(vneg), - INTERPRETER_TRANSLATE(vsqrt), - INTERPRETER_TRANSLATE(vcmp), - INTERPRETER_TRANSLATE(vcmp2), - INTERPRETER_TRANSLATE(vcvtbds), - INTERPRETER_TRANSLATE(vcvtbff), - INTERPRETER_TRANSLATE(vcvtbfi), - INTERPRETER_TRANSLATE(vmovbrs), - INTERPRETER_TRANSLATE(vmsr), - INTERPRETER_TRANSLATE(vmovbrc), - INTERPRETER_TRANSLATE(vmrs), - INTERPRETER_TRANSLATE(vmovbcr), - INTERPRETER_TRANSLATE(vmovbrrss), - INTERPRETER_TRANSLATE(vmovbrrd), - INTERPRETER_TRANSLATE(vstr), - INTERPRETER_TRANSLATE(vpush), - INTERPRETER_TRANSLATE(vstm), - INTERPRETER_TRANSLATE(vpop), - INTERPRETER_TRANSLATE(vldr), - INTERPRETER_TRANSLATE(vldm), - - INTERPRETER_TRANSLATE(srs), - INTERPRETER_TRANSLATE(rfe), - INTERPRETER_TRANSLATE(bkpt), - INTERPRETER_TRANSLATE(blx), - INTERPRETER_TRANSLATE(cps), - INTERPRETER_TRANSLATE(pld), - INTERPRETER_TRANSLATE(setend), - INTERPRETER_TRANSLATE(clrex), - INTERPRETER_TRANSLATE(rev16), - INTERPRETER_TRANSLATE(usad8), - INTERPRETER_TRANSLATE(sxtb), - INTERPRETER_TRANSLATE(uxtb), - INTERPRETER_TRANSLATE(sxth), - INTERPRETER_TRANSLATE(sxtb16), - INTERPRETER_TRANSLATE(uxth), - INTERPRETER_TRANSLATE(uxtb16), - INTERPRETER_TRANSLATE(cpy), - INTERPRETER_TRANSLATE(uxtab), - INTERPRETER_TRANSLATE(ssub8), - INTERPRETER_TRANSLATE(shsub8), - INTERPRETER_TRANSLATE(ssubaddx), - INTERPRETER_TRANSLATE(strex), - INTERPRETER_TRANSLATE(strexb), - INTERPRETER_TRANSLATE(swp), - INTERPRETER_TRANSLATE(swpb), - INTERPRETER_TRANSLATE(ssub16), - INTERPRETER_TRANSLATE(ssat16), - INTERPRETER_TRANSLATE(shsubaddx), - INTERPRETER_TRANSLATE(qsubaddx), - INTERPRETER_TRANSLATE(shaddsubx), - INTERPRETER_TRANSLATE(shadd8), - INTERPRETER_TRANSLATE(shadd16), - INTERPRETER_TRANSLATE(sel), - INTERPRETER_TRANSLATE(saddsubx), - INTERPRETER_TRANSLATE(sadd8), - INTERPRETER_TRANSLATE(sadd16), - INTERPRETER_TRANSLATE(shsub16), - INTERPRETER_TRANSLATE(umaal), - INTERPRETER_TRANSLATE(uxtab16), - INTERPRETER_TRANSLATE(usubaddx), - INTERPRETER_TRANSLATE(usub8), - INTERPRETER_TRANSLATE(usub16), - INTERPRETER_TRANSLATE(usat16), - INTERPRETER_TRANSLATE(usada8), - INTERPRETER_TRANSLATE(uqsubaddx), - INTERPRETER_TRANSLATE(uqsub8), - INTERPRETER_TRANSLATE(uqsub16), - INTERPRETER_TRANSLATE(uqaddsubx), - INTERPRETER_TRANSLATE(uqadd8), - INTERPRETER_TRANSLATE(uqadd16), - INTERPRETER_TRANSLATE(sxtab), - INTERPRETER_TRANSLATE(uhsubaddx), - INTERPRETER_TRANSLATE(uhsub8), - INTERPRETER_TRANSLATE(uhsub16), - INTERPRETER_TRANSLATE(uhaddsubx), - INTERPRETER_TRANSLATE(uhadd8), - INTERPRETER_TRANSLATE(uhadd16), - INTERPRETER_TRANSLATE(uaddsubx), - INTERPRETER_TRANSLATE(uadd8), - INTERPRETER_TRANSLATE(uadd16), - INTERPRETER_TRANSLATE(sxtah), - INTERPRETER_TRANSLATE(sxtab16), - INTERPRETER_TRANSLATE(qadd8), - INTERPRETER_TRANSLATE(bxj), - INTERPRETER_TRANSLATE(clz), - INTERPRETER_TRANSLATE(uxtah), - INTERPRETER_TRANSLATE(bx), - INTERPRETER_TRANSLATE(rev), - INTERPRETER_TRANSLATE(blx), - INTERPRETER_TRANSLATE(revsh), - INTERPRETER_TRANSLATE(qadd), - INTERPRETER_TRANSLATE(qadd16), - INTERPRETER_TRANSLATE(qaddsubx), - INTERPRETER_TRANSLATE(ldrex), - INTERPRETER_TRANSLATE(qdadd), - INTERPRETER_TRANSLATE(qdsub), - INTERPRETER_TRANSLATE(qsub), - INTERPRETER_TRANSLATE(ldrexb), - INTERPRETER_TRANSLATE(qsub8), - INTERPRETER_TRANSLATE(qsub16), - INTERPRETER_TRANSLATE(smuad), - INTERPRETER_TRANSLATE(smmul), - INTERPRETER_TRANSLATE(smusd), - INTERPRETER_TRANSLATE(smlsd), - INTERPRETER_TRANSLATE(smlsld), - INTERPRETER_TRANSLATE(smmla), - INTERPRETER_TRANSLATE(smmls), - INTERPRETER_TRANSLATE(smlald), - INTERPRETER_TRANSLATE(smlad), - INTERPRETER_TRANSLATE(smlaw), - INTERPRETER_TRANSLATE(smulw), - INTERPRETER_TRANSLATE(pkhtb), - INTERPRETER_TRANSLATE(pkhbt), - INTERPRETER_TRANSLATE(smul), - INTERPRETER_TRANSLATE(smlalxy), - INTERPRETER_TRANSLATE(smla), - INTERPRETER_TRANSLATE(mcrr), - INTERPRETER_TRANSLATE(mrrc), - INTERPRETER_TRANSLATE(cmp), - INTERPRETER_TRANSLATE(tst), - INTERPRETER_TRANSLATE(teq), - INTERPRETER_TRANSLATE(cmn), - INTERPRETER_TRANSLATE(smull), - INTERPRETER_TRANSLATE(umull), - INTERPRETER_TRANSLATE(umlal), - INTERPRETER_TRANSLATE(smlal), - INTERPRETER_TRANSLATE(mul), - INTERPRETER_TRANSLATE(mla), - INTERPRETER_TRANSLATE(ssat), - INTERPRETER_TRANSLATE(usat), - INTERPRETER_TRANSLATE(mrs), - INTERPRETER_TRANSLATE(msr), - INTERPRETER_TRANSLATE(and), - INTERPRETER_TRANSLATE(bic), - INTERPRETER_TRANSLATE(ldm), - INTERPRETER_TRANSLATE(eor), - INTERPRETER_TRANSLATE(add), - INTERPRETER_TRANSLATE(rsb), - INTERPRETER_TRANSLATE(rsc), - INTERPRETER_TRANSLATE(sbc), - INTERPRETER_TRANSLATE(adc), - INTERPRETER_TRANSLATE(sub), - INTERPRETER_TRANSLATE(orr), - INTERPRETER_TRANSLATE(mvn), - INTERPRETER_TRANSLATE(mov), - INTERPRETER_TRANSLATE(stm), - INTERPRETER_TRANSLATE(ldm), - INTERPRETER_TRANSLATE(ldrsh), - INTERPRETER_TRANSLATE(stm), - INTERPRETER_TRANSLATE(ldm), - INTERPRETER_TRANSLATE(ldrsb), - INTERPRETER_TRANSLATE(strd), - INTERPRETER_TRANSLATE(ldrh), - INTERPRETER_TRANSLATE(strh), - INTERPRETER_TRANSLATE(ldrd), - INTERPRETER_TRANSLATE(strt), - INTERPRETER_TRANSLATE(strbt), - INTERPRETER_TRANSLATE(ldrbt), - INTERPRETER_TRANSLATE(ldrt), - INTERPRETER_TRANSLATE(mrc), - INTERPRETER_TRANSLATE(mcr), - INTERPRETER_TRANSLATE(msr), - INTERPRETER_TRANSLATE(msr), - INTERPRETER_TRANSLATE(msr), - INTERPRETER_TRANSLATE(msr), - INTERPRETER_TRANSLATE(msr), - INTERPRETER_TRANSLATE(ldrb), - INTERPRETER_TRANSLATE(strb), - INTERPRETER_TRANSLATE(ldr), - INTERPRETER_TRANSLATE(ldrcond), - INTERPRETER_TRANSLATE(str), - INTERPRETER_TRANSLATE(cdp), - INTERPRETER_TRANSLATE(stc), - INTERPRETER_TRANSLATE(ldc), - INTERPRETER_TRANSLATE(ldrexd), - INTERPRETER_TRANSLATE(strexd), - INTERPRETER_TRANSLATE(ldrexh), - INTERPRETER_TRANSLATE(strexh), - INTERPRETER_TRANSLATE(nop), - INTERPRETER_TRANSLATE(yield), - INTERPRETER_TRANSLATE(wfe), - INTERPRETER_TRANSLATE(wfi), - INTERPRETER_TRANSLATE(sev), - INTERPRETER_TRANSLATE(swi), + INTERPRETER_TRANSLATE(vmla), INTERPRETER_TRANSLATE(vmls), INTERPRETER_TRANSLATE(vnmla), + INTERPRETER_TRANSLATE(vnmls), INTERPRETER_TRANSLATE(vnmul), INTERPRETER_TRANSLATE(vmul), + INTERPRETER_TRANSLATE(vadd), INTERPRETER_TRANSLATE(vsub), INTERPRETER_TRANSLATE(vdiv), + INTERPRETER_TRANSLATE(vmovi), INTERPRETER_TRANSLATE(vmovr), INTERPRETER_TRANSLATE(vabs), + INTERPRETER_TRANSLATE(vneg), INTERPRETER_TRANSLATE(vsqrt), INTERPRETER_TRANSLATE(vcmp), + INTERPRETER_TRANSLATE(vcmp2), INTERPRETER_TRANSLATE(vcvtbds), INTERPRETER_TRANSLATE(vcvtbff), + INTERPRETER_TRANSLATE(vcvtbfi), INTERPRETER_TRANSLATE(vmovbrs), INTERPRETER_TRANSLATE(vmsr), + INTERPRETER_TRANSLATE(vmovbrc), INTERPRETER_TRANSLATE(vmrs), INTERPRETER_TRANSLATE(vmovbcr), + INTERPRETER_TRANSLATE(vmovbrrss), INTERPRETER_TRANSLATE(vmovbrrd), INTERPRETER_TRANSLATE(vstr), + INTERPRETER_TRANSLATE(vpush), INTERPRETER_TRANSLATE(vstm), INTERPRETER_TRANSLATE(vpop), + INTERPRETER_TRANSLATE(vldr), INTERPRETER_TRANSLATE(vldm), + + INTERPRETER_TRANSLATE(srs), INTERPRETER_TRANSLATE(rfe), INTERPRETER_TRANSLATE(bkpt), + INTERPRETER_TRANSLATE(blx), INTERPRETER_TRANSLATE(cps), INTERPRETER_TRANSLATE(pld), + INTERPRETER_TRANSLATE(setend), INTERPRETER_TRANSLATE(clrex), INTERPRETER_TRANSLATE(rev16), + INTERPRETER_TRANSLATE(usad8), INTERPRETER_TRANSLATE(sxtb), INTERPRETER_TRANSLATE(uxtb), + INTERPRETER_TRANSLATE(sxth), INTERPRETER_TRANSLATE(sxtb16), INTERPRETER_TRANSLATE(uxth), + INTERPRETER_TRANSLATE(uxtb16), INTERPRETER_TRANSLATE(cpy), INTERPRETER_TRANSLATE(uxtab), + INTERPRETER_TRANSLATE(ssub8), INTERPRETER_TRANSLATE(shsub8), INTERPRETER_TRANSLATE(ssubaddx), + INTERPRETER_TRANSLATE(strex), INTERPRETER_TRANSLATE(strexb), INTERPRETER_TRANSLATE(swp), + INTERPRETER_TRANSLATE(swpb), INTERPRETER_TRANSLATE(ssub16), INTERPRETER_TRANSLATE(ssat16), + INTERPRETER_TRANSLATE(shsubaddx), INTERPRETER_TRANSLATE(qsubaddx), + INTERPRETER_TRANSLATE(shaddsubx), INTERPRETER_TRANSLATE(shadd8), INTERPRETER_TRANSLATE(shadd16), + INTERPRETER_TRANSLATE(sel), INTERPRETER_TRANSLATE(saddsubx), INTERPRETER_TRANSLATE(sadd8), + INTERPRETER_TRANSLATE(sadd16), INTERPRETER_TRANSLATE(shsub16), INTERPRETER_TRANSLATE(umaal), + INTERPRETER_TRANSLATE(uxtab16), INTERPRETER_TRANSLATE(usubaddx), INTERPRETER_TRANSLATE(usub8), + INTERPRETER_TRANSLATE(usub16), INTERPRETER_TRANSLATE(usat16), INTERPRETER_TRANSLATE(usada8), + INTERPRETER_TRANSLATE(uqsubaddx), INTERPRETER_TRANSLATE(uqsub8), INTERPRETER_TRANSLATE(uqsub16), + INTERPRETER_TRANSLATE(uqaddsubx), INTERPRETER_TRANSLATE(uqadd8), INTERPRETER_TRANSLATE(uqadd16), + INTERPRETER_TRANSLATE(sxtab), INTERPRETER_TRANSLATE(uhsubaddx), INTERPRETER_TRANSLATE(uhsub8), + INTERPRETER_TRANSLATE(uhsub16), INTERPRETER_TRANSLATE(uhaddsubx), INTERPRETER_TRANSLATE(uhadd8), + INTERPRETER_TRANSLATE(uhadd16), INTERPRETER_TRANSLATE(uaddsubx), INTERPRETER_TRANSLATE(uadd8), + INTERPRETER_TRANSLATE(uadd16), INTERPRETER_TRANSLATE(sxtah), INTERPRETER_TRANSLATE(sxtab16), + INTERPRETER_TRANSLATE(qadd8), INTERPRETER_TRANSLATE(bxj), INTERPRETER_TRANSLATE(clz), + INTERPRETER_TRANSLATE(uxtah), INTERPRETER_TRANSLATE(bx), INTERPRETER_TRANSLATE(rev), + INTERPRETER_TRANSLATE(blx), INTERPRETER_TRANSLATE(revsh), INTERPRETER_TRANSLATE(qadd), + INTERPRETER_TRANSLATE(qadd16), INTERPRETER_TRANSLATE(qaddsubx), INTERPRETER_TRANSLATE(ldrex), + INTERPRETER_TRANSLATE(qdadd), INTERPRETER_TRANSLATE(qdsub), INTERPRETER_TRANSLATE(qsub), + INTERPRETER_TRANSLATE(ldrexb), INTERPRETER_TRANSLATE(qsub8), INTERPRETER_TRANSLATE(qsub16), + INTERPRETER_TRANSLATE(smuad), INTERPRETER_TRANSLATE(smmul), INTERPRETER_TRANSLATE(smusd), + INTERPRETER_TRANSLATE(smlsd), INTERPRETER_TRANSLATE(smlsld), INTERPRETER_TRANSLATE(smmla), + INTERPRETER_TRANSLATE(smmls), INTERPRETER_TRANSLATE(smlald), INTERPRETER_TRANSLATE(smlad), + INTERPRETER_TRANSLATE(smlaw), INTERPRETER_TRANSLATE(smulw), INTERPRETER_TRANSLATE(pkhtb), + INTERPRETER_TRANSLATE(pkhbt), INTERPRETER_TRANSLATE(smul), INTERPRETER_TRANSLATE(smlalxy), + INTERPRETER_TRANSLATE(smla), INTERPRETER_TRANSLATE(mcrr), INTERPRETER_TRANSLATE(mrrc), + INTERPRETER_TRANSLATE(cmp), INTERPRETER_TRANSLATE(tst), INTERPRETER_TRANSLATE(teq), + INTERPRETER_TRANSLATE(cmn), INTERPRETER_TRANSLATE(smull), INTERPRETER_TRANSLATE(umull), + INTERPRETER_TRANSLATE(umlal), INTERPRETER_TRANSLATE(smlal), INTERPRETER_TRANSLATE(mul), + INTERPRETER_TRANSLATE(mla), INTERPRETER_TRANSLATE(ssat), INTERPRETER_TRANSLATE(usat), + INTERPRETER_TRANSLATE(mrs), INTERPRETER_TRANSLATE(msr), INTERPRETER_TRANSLATE(and), + INTERPRETER_TRANSLATE(bic), INTERPRETER_TRANSLATE(ldm), INTERPRETER_TRANSLATE(eor), + INTERPRETER_TRANSLATE(add), INTERPRETER_TRANSLATE(rsb), INTERPRETER_TRANSLATE(rsc), + INTERPRETER_TRANSLATE(sbc), INTERPRETER_TRANSLATE(adc), INTERPRETER_TRANSLATE(sub), + INTERPRETER_TRANSLATE(orr), INTERPRETER_TRANSLATE(mvn), INTERPRETER_TRANSLATE(mov), + INTERPRETER_TRANSLATE(stm), INTERPRETER_TRANSLATE(ldm), INTERPRETER_TRANSLATE(ldrsh), + INTERPRETER_TRANSLATE(stm), INTERPRETER_TRANSLATE(ldm), INTERPRETER_TRANSLATE(ldrsb), + INTERPRETER_TRANSLATE(strd), INTERPRETER_TRANSLATE(ldrh), INTERPRETER_TRANSLATE(strh), + INTERPRETER_TRANSLATE(ldrd), INTERPRETER_TRANSLATE(strt), INTERPRETER_TRANSLATE(strbt), + INTERPRETER_TRANSLATE(ldrbt), INTERPRETER_TRANSLATE(ldrt), INTERPRETER_TRANSLATE(mrc), + INTERPRETER_TRANSLATE(mcr), INTERPRETER_TRANSLATE(msr), INTERPRETER_TRANSLATE(msr), + INTERPRETER_TRANSLATE(msr), INTERPRETER_TRANSLATE(msr), INTERPRETER_TRANSLATE(msr), + INTERPRETER_TRANSLATE(ldrb), INTERPRETER_TRANSLATE(strb), INTERPRETER_TRANSLATE(ldr), + INTERPRETER_TRANSLATE(ldrcond), INTERPRETER_TRANSLATE(str), INTERPRETER_TRANSLATE(cdp), + INTERPRETER_TRANSLATE(stc), INTERPRETER_TRANSLATE(ldc), INTERPRETER_TRANSLATE(ldrexd), + INTERPRETER_TRANSLATE(strexd), INTERPRETER_TRANSLATE(ldrexh), INTERPRETER_TRANSLATE(strexh), + INTERPRETER_TRANSLATE(nop), INTERPRETER_TRANSLATE(yield), INTERPRETER_TRANSLATE(wfe), + INTERPRETER_TRANSLATE(wfi), INTERPRETER_TRANSLATE(sev), INTERPRETER_TRANSLATE(swi), INTERPRETER_TRANSLATE(bbl), // All the thumb instructions should be placed the end of table - INTERPRETER_TRANSLATE(b_2_thumb), - INTERPRETER_TRANSLATE(b_cond_thumb), - INTERPRETER_TRANSLATE(bl_1_thumb), - INTERPRETER_TRANSLATE(bl_2_thumb), - INTERPRETER_TRANSLATE(blx_1_thumb) + INTERPRETER_TRANSLATE(b_2_thumb), INTERPRETER_TRANSLATE(b_cond_thumb), + INTERPRETER_TRANSLATE(bl_1_thumb), INTERPRETER_TRANSLATE(bl_2_thumb), + INTERPRETER_TRANSLATE(blx_1_thumb), }; const size_t arm_instruction_trans_len = sizeof(arm_instruction_trans) / sizeof(transop_fp_t); diff --git a/src/core/arm/dyncom/arm_dyncom_trans.h b/src/core/arm/dyncom/arm_dyncom_trans.h index 7af71f4e3..b1ec90662 100644 --- a/src/core/arm/dyncom/arm_dyncom_trans.h +++ b/src/core/arm/dyncom/arm_dyncom_trans.h @@ -1,16 +1,19 @@ +#include <cstddef> +#include "common/common_types.h" + struct ARMul_State; typedef unsigned int (*shtop_fp_t)(ARMul_State* cpu, unsigned int sht_oper); enum class TransExtData { - COND = (1 << 0), - NON_BRANCH = (1 << 1), - DIRECT_BRANCH = (1 << 2), + COND = (1 << 0), + NON_BRANCH = (1 << 1), + DIRECT_BRANCH = (1 << 2), INDIRECT_BRANCH = (1 << 3), - CALL = (1 << 4), - RET = (1 << 5), - END_OF_PAGE = (1 << 6), - THUMB = (1 << 7), - SINGLE_STEP = (1 << 8) + CALL = (1 << 4), + RET = (1 << 5), + END_OF_PAGE = (1 << 6), + THUMB = (1 << 7), + SINGLE_STEP = (1 << 8) }; struct arm_inst { @@ -106,8 +109,7 @@ struct cps_inst { unsigned int mode; }; -struct clrex_inst { -}; +struct clrex_inst {}; struct cpy_inst { unsigned int Rm; @@ -163,11 +165,9 @@ struct bkpt_inst { u32 imm; }; -struct stc_inst { -}; +struct stc_inst {}; -struct ldc_inst { -}; +struct ldc_inst {}; struct swi_inst { unsigned int num; @@ -369,8 +369,7 @@ struct msr_inst { unsigned int inst; }; -struct pld_inst { -}; +struct pld_inst {}; struct sxtb_inst { unsigned int Rd; @@ -475,7 +474,7 @@ struct pkh_inst { #include "core/arm/skyeye_common/vfp/vfpinstr.cpp" #undef VFP_INTERPRETER_STRUCT -typedef void (*get_addr_fp_t)(ARMul_State *cpu, unsigned int inst, unsigned int &virt_addr); +typedef void (*get_addr_fp_t)(ARMul_State* cpu, unsigned int inst, unsigned int& virt_addr); struct ldst_inst { unsigned int inst; diff --git a/src/core/arm/skyeye_common/arm_regformat.h b/src/core/arm/skyeye_common/arm_regformat.h index 38fa97ab9..706195a05 100644 --- a/src/core/arm/skyeye_common/arm_regformat.h +++ b/src/core/arm/skyeye_common/arm_regformat.h @@ -16,7 +16,7 @@ enum { R12, R13, LR, - R15, //PC, + R15, // PC, CPSR_REG, SPSR_REG, diff --git a/src/core/arm/skyeye_common/armstate.cpp b/src/core/arm/skyeye_common/armstate.cpp index 5550c112e..1465b074e 100644 --- a/src/core/arm/skyeye_common/armstate.cpp +++ b/src/core/arm/skyeye_common/armstate.cpp @@ -3,21 +3,19 @@ // Refer to the license.txt file included. #include <algorithm> -#include "common/swap.h" #include "common/logging/log.h" -#include "core/memory.h" +#include "common/swap.h" #include "core/arm/skyeye_common/armstate.h" #include "core/arm/skyeye_common/vfp/vfp.h" #include "core/gdbstub/gdbstub.h" +#include "core/memory.h" -ARMul_State::ARMul_State(PrivilegeMode initial_mode) -{ +ARMul_State::ARMul_State(PrivilegeMode initial_mode) { Reset(); ChangePrivilegeMode(initial_mode); } -void ARMul_State::ChangePrivilegeMode(u32 new_mode) -{ +void ARMul_State::ChangePrivilegeMode(u32 new_mode) { if (Mode == new_mode) return; @@ -103,8 +101,7 @@ void ARMul_State::ChangePrivilegeMode(u32 new_mode) } // Performs a reset -void ARMul_State::Reset() -{ +void ARMul_State::Reset() { VFPInit(this); // Set stack pointer to the top of the stack @@ -128,8 +125,7 @@ void ARMul_State::Reset() } // Resets certain MPCore CP15 values to their ARM-defined reset values. -void ARMul_State::ResetMPCoreCP15Registers() -{ +void ARMul_State::ResetMPCoreCP15Registers() { // c0 CP15[CP15_MAIN_ID] = 0x410FB024; CP15[CP15_TLB_TYPE] = 0x00000800; @@ -185,23 +181,20 @@ void ARMul_State::ResetMPCoreCP15Registers() CP15[CP15_TLB_DEBUG_CONTROL] = 0x00000000; } -static void CheckMemoryBreakpoint(u32 address, GDBStub::BreakpointType type) -{ +static void CheckMemoryBreakpoint(u32 address, GDBStub::BreakpointType type) { if (GDBStub::g_server_enabled && GDBStub::CheckBreakpoint(address, type)) { LOG_DEBUG(Debug, "Found memory breakpoint @ %08x", address); GDBStub::Break(true); } } -u8 ARMul_State::ReadMemory8(u32 address) const -{ +u8 ARMul_State::ReadMemory8(u32 address) const { CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); return Memory::Read8(address); } -u16 ARMul_State::ReadMemory16(u32 address) const -{ +u16 ARMul_State::ReadMemory16(u32 address) const { CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); u16 data = Memory::Read16(address); @@ -212,8 +205,7 @@ u16 ARMul_State::ReadMemory16(u32 address) const return data; } -u32 ARMul_State::ReadMemory32(u32 address) const -{ +u32 ARMul_State::ReadMemory32(u32 address) const { CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); u32 data = Memory::Read32(address); @@ -224,8 +216,7 @@ u32 ARMul_State::ReadMemory32(u32 address) const return data; } -u64 ARMul_State::ReadMemory64(u32 address) const -{ +u64 ARMul_State::ReadMemory64(u32 address) const { CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Read); u64 data = Memory::Read64(address); @@ -236,15 +227,13 @@ u64 ARMul_State::ReadMemory64(u32 address) const return data; } -void ARMul_State::WriteMemory8(u32 address, u8 data) -{ +void ARMul_State::WriteMemory8(u32 address, u8 data) { CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Write); Memory::Write8(address, data); } -void ARMul_State::WriteMemory16(u32 address, u16 data) -{ +void ARMul_State::WriteMemory16(u32 address, u16 data) { CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Write); if (InBigEndianMode()) @@ -253,8 +242,7 @@ void ARMul_State::WriteMemory16(u32 address, u16 data) Memory::Write16(address, data); } -void ARMul_State::WriteMemory32(u32 address, u32 data) -{ +void ARMul_State::WriteMemory32(u32 address, u32 data) { CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Write); if (InBigEndianMode()) @@ -263,8 +251,7 @@ void ARMul_State::WriteMemory32(u32 address, u32 data) Memory::Write32(address, data); } -void ARMul_State::WriteMemory64(u32 address, u64 data) -{ +void ARMul_State::WriteMemory64(u32 address, u64 data) { CheckMemoryBreakpoint(address, GDBStub::BreakpointType::Write); if (InBigEndianMode()) @@ -273,15 +260,12 @@ void ARMul_State::WriteMemory64(u32 address, u64 data) Memory::Write64(address, data); } - // Reads from the CP15 registers. Used with implementation of the MRC instruction. // Note that since the 3DS does not have the hypervisor extensions, these registers // are not implemented. -u32 ARMul_State::ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) const -{ +u32 ARMul_State::ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) const { // Unprivileged registers - if (crn == 13 && opcode_1 == 0 && crm == 0) - { + if (crn == 13 && opcode_1 == 0 && crm == 0) { if (opcode_2 == 2) return CP15[CP15_THREAD_UPRW]; @@ -289,12 +273,9 @@ u32 ARMul_State::ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) return CP15[CP15_THREAD_URO]; } - if (InAPrivilegedMode()) - { - if (crn == 0 && opcode_1 == 0) - { - if (crm == 0) - { + if (InAPrivilegedMode()) { + if (crn == 0 && opcode_1 == 0) { + if (crm == 0) { if (opcode_2 == 0) return CP15[CP15_MAIN_ID]; @@ -306,9 +287,7 @@ u32 ARMul_State::ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) if (opcode_2 == 5) return CP15[CP15_CPU_ID]; - } - else if (crm == 1) - { + } else if (crm == 1) { if (opcode_2 == 0) return CP15[CP15_PROCESSOR_FEATURE_0]; @@ -329,9 +308,7 @@ u32 ARMul_State::ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) if (opcode_2 == 7) return CP15[CP15_MEMORY_MODEL_FEATURE_3]; - } - else if (crm == 2) - { + } else if (crm == 2) { if (opcode_2 == 0) return CP15[CP15_ISA_FEATURE_0]; @@ -349,8 +326,7 @@ u32 ARMul_State::ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) } } - if (crn == 1 && opcode_1 == 0 && crm == 0) - { + if (crn == 1 && opcode_1 == 0 && crm == 0) { if (opcode_2 == 0) return CP15[CP15_CONTROL]; @@ -361,8 +337,7 @@ u32 ARMul_State::ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) return CP15[CP15_COPROCESSOR_ACCESS_CONTROL]; } - if (crn == 2 && opcode_1 == 0 && crm == 0) - { + if (crn == 2 && opcode_1 == 0 && crm == 0) { if (opcode_2 == 0) return CP15[CP15_TRANSLATION_BASE_TABLE_0]; @@ -376,8 +351,7 @@ u32 ARMul_State::ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0) return CP15[CP15_DOMAIN_ACCESS_CONTROL]; - if (crn == 5 && opcode_1 == 0 && crm == 0) - { + if (crn == 5 && opcode_1 == 0 && crm == 0) { if (opcode_2 == 0) return CP15[CP15_FAULT_STATUS]; @@ -385,8 +359,7 @@ u32 ARMul_State::ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) return CP15[CP15_INSTR_FAULT_STATUS]; } - if (crn == 6 && opcode_1 == 0 && crm == 0) - { + if (crn == 6 && opcode_1 == 0 && crm == 0) { if (opcode_2 == 0) return CP15[CP15_FAULT_ADDRESS]; @@ -400,13 +373,11 @@ u32 ARMul_State::ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0) return CP15[CP15_DATA_CACHE_LOCKDOWN]; - if (crn == 10 && opcode_1 == 0) - { + if (crn == 10 && opcode_1 == 0) { if (crm == 0 && opcode_2 == 0) return CP15[CP15_TLB_LOCKDOWN]; - if (crm == 2) - { + if (crm == 2) { if (opcode_2 == 0) return CP15[CP15_PRIMARY_REGION_REMAP]; @@ -415,8 +386,7 @@ u32 ARMul_State::ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) } } - if (crn == 13 && crm == 0) - { + if (crn == 13 && crm == 0) { if (opcode_2 == 0) return CP15[CP15_PID]; @@ -427,10 +397,8 @@ u32 ARMul_State::ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) return CP15[CP15_THREAD_PRW]; } - if (crn == 15) - { - if (opcode_1 == 0 && crm == 12) - { + if (crn == 15) { + if (opcode_1 == 0 && crm == 12) { if (opcode_2 == 0) return CP15[CP15_PERFORMANCE_MONITOR_CONTROL]; @@ -444,8 +412,7 @@ u32 ARMul_State::ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) return CP15[CP15_COUNT_1]; } - if (opcode_1 == 5 && opcode_2 == 2) - { + if (opcode_1 == 5 && opcode_2 == 2) { if (crm == 5) return CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS]; @@ -461,66 +428,49 @@ u32 ARMul_State::ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) } } - LOG_ERROR(Core_ARM11, "MRC CRn=%u, CRm=%u, OP1=%u OP2=%u is not implemented. Returning zero.", crn, crm, opcode_1, opcode_2); + LOG_ERROR(Core_ARM11, "MRC CRn=%u, CRm=%u, OP1=%u OP2=%u is not implemented. Returning zero.", + crn, crm, opcode_1, opcode_2); return 0; } // Write to the CP15 registers. Used with implementation of the MCR instruction. // Note that since the 3DS does not have the hypervisor extensions, these registers // are not implemented. -void ARMul_State::WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) -{ - if (InAPrivilegedMode()) - { - if (crn == 1 && opcode_1 == 0 && crm == 0) - { +void ARMul_State::WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) { + if (InAPrivilegedMode()) { + if (crn == 1 && opcode_1 == 0 && crm == 0) { if (opcode_2 == 0) CP15[CP15_CONTROL] = value; else if (opcode_2 == 1) CP15[CP15_AUXILIARY_CONTROL] = value; else if (opcode_2 == 2) CP15[CP15_COPROCESSOR_ACCESS_CONTROL] = value; - } - else if (crn == 2 && opcode_1 == 0 && crm == 0) - { + } else if (crn == 2 && opcode_1 == 0 && crm == 0) { if (opcode_2 == 0) CP15[CP15_TRANSLATION_BASE_TABLE_0] = value; else if (opcode_2 == 1) CP15[CP15_TRANSLATION_BASE_TABLE_1] = value; else if (opcode_2 == 2) CP15[CP15_TRANSLATION_BASE_CONTROL] = value; - } - else if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0) - { + } else if (crn == 3 && opcode_1 == 0 && crm == 0 && opcode_2 == 0) { CP15[CP15_DOMAIN_ACCESS_CONTROL] = value; - } - else if (crn == 5 && opcode_1 == 0 && crm == 0) - { + } else if (crn == 5 && opcode_1 == 0 && crm == 0) { if (opcode_2 == 0) CP15[CP15_FAULT_STATUS] = value; else if (opcode_2 == 1) CP15[CP15_INSTR_FAULT_STATUS] = value; - } - else if (crn == 6 && opcode_1 == 0 && crm == 0) - { + } else if (crn == 6 && opcode_1 == 0 && crm == 0) { if (opcode_2 == 0) CP15[CP15_FAULT_ADDRESS] = value; else if (opcode_2 == 1) CP15[CP15_WFAR] = value; - } - else if (crn == 7 && opcode_1 == 0) - { - if (crm == 0 && opcode_2 == 4) - { + } else if (crn == 7 && opcode_1 == 0) { + if (crm == 0 && opcode_2 == 4) { CP15[CP15_WAIT_FOR_INTERRUPT] = value; - } - else if (crm == 4 && opcode_2 == 0) - { + } else if (crm == 4 && opcode_2 == 0) { // NOTE: Not entirely accurate. This should do permission checks. CP15[CP15_PHYS_ADDRESS] = Memory::VirtualToPhysicalAddress(value); - } - else if (crm == 5) - { + } else if (crm == 5) { if (opcode_2 == 0) CP15[CP15_INVALIDATE_INSTR_CACHE] = value; else if (opcode_2 == 1) @@ -531,31 +481,23 @@ void ARMul_State::WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u CP15[CP15_FLUSH_BRANCH_TARGET_CACHE] = value; else if (opcode_2 == 7) CP15[CP15_FLUSH_BRANCH_TARGET_CACHE_ENTRY] = value; - } - else if (crm == 6) - { + } else if (crm == 6) { if (opcode_2 == 0) CP15[CP15_INVALIDATE_DATA_CACHE] = value; else if (opcode_2 == 1) CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_MVA] = value; else if (opcode_2 == 2) CP15[CP15_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value; - } - else if (crm == 7 && opcode_2 == 0) - { + } else if (crm == 7 && opcode_2 == 0) { CP15[CP15_INVALIDATE_DATA_AND_INSTR_CACHE] = value; - } - else if (crm == 10) - { + } else if (crm == 10) { if (opcode_2 == 0) CP15[CP15_CLEAN_DATA_CACHE] = value; else if (opcode_2 == 1) CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_MVA] = value; else if (opcode_2 == 2) CP15[CP15_CLEAN_DATA_CACHE_LINE_USING_INDEX] = value; - } - else if (crm == 14) - { + } else if (crm == 14) { if (opcode_2 == 0) CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE] = value; else if (opcode_2 == 1) @@ -563,11 +505,8 @@ void ARMul_State::WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u else if (opcode_2 == 2) CP15[CP15_CLEAN_AND_INVALIDATE_DATA_CACHE_LINE_USING_INDEX] = value; } - } - else if (crn == 8 && opcode_1 == 0) - { - if (crm == 5) - { + } else if (crn == 8 && opcode_1 == 0) { + if (crm == 5) { if (opcode_2 == 0) CP15[CP15_INVALIDATE_ITLB] = value; else if (opcode_2 == 1) @@ -576,9 +515,7 @@ void ARMul_State::WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_ASID_MATCH] = value; else if (opcode_2 == 3) CP15[CP15_INVALIDATE_ITLB_ENTRY_ON_MVA] = value; - } - else if (crm == 6) - { + } else if (crm == 6) { if (opcode_2 == 0) CP15[CP15_INVALIDATE_DTLB] = value; else if (opcode_2 == 1) @@ -587,9 +524,7 @@ void ARMul_State::WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_ASID_MATCH] = value; else if (opcode_2 == 3) CP15[CP15_INVALIDATE_DTLB_ENTRY_ON_MVA] = value; - } - else if (crm == 7) - { + } else if (crm == 7) { if (opcode_2 == 0) CP15[CP15_INVALIDATE_UTLB] = value; else if (opcode_2 == 1) @@ -599,27 +534,18 @@ void ARMul_State::WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u else if (opcode_2 == 3) CP15[CP15_INVALIDATE_UTLB_ENTRY_ON_MVA] = value; } - } - else if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0) - { + } else if (crn == 9 && opcode_1 == 0 && crm == 0 && opcode_2 == 0) { CP15[CP15_DATA_CACHE_LOCKDOWN] = value; - } - else if (crn == 10 && opcode_1 == 0) - { - if (crm == 0 && opcode_2 == 0) - { + } else if (crn == 10 && opcode_1 == 0) { + if (crm == 0 && opcode_2 == 0) { CP15[CP15_TLB_LOCKDOWN] = value; - } - else if (crm == 2) - { + } else if (crm == 2) { if (opcode_2 == 0) CP15[CP15_PRIMARY_REGION_REMAP] = value; else if (opcode_2 == 1) CP15[CP15_NORMAL_REGION_REMAP] = value; } - } - else if (crn == 13 && opcode_1 == 0 && crm == 0) - { + } else if (crn == 13 && opcode_1 == 0 && crm == 0) { if (opcode_2 == 0) CP15[CP15_PID] = value; else if (opcode_2 == 1) @@ -628,11 +554,8 @@ void ARMul_State::WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u CP15[CP15_THREAD_URO] = value; else if (opcode_2 == 4) CP15[CP15_THREAD_PRW] = value; - } - else if (crn == 15) - { - if (opcode_1 == 0 && crm == 12) - { + } else if (crn == 15) { + if (opcode_1 == 0 && crm == 12) { if (opcode_2 == 0) CP15[CP15_PERFORMANCE_MONITOR_CONTROL] = value; else if (opcode_2 == 1) @@ -641,50 +564,34 @@ void ARMul_State::WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u CP15[CP15_COUNT_0] = value; else if (opcode_2 == 3) CP15[CP15_COUNT_1] = value; - } - else if (opcode_1 == 5) - { - if (crm == 4) - { + } else if (opcode_1 == 5) { + if (crm == 4) { if (opcode_2 == 2) CP15[CP15_READ_MAIN_TLB_LOCKDOWN_ENTRY] = value; else if (opcode_2 == 4) CP15[CP15_WRITE_MAIN_TLB_LOCKDOWN_ENTRY] = value; - } - else if (crm == 5 && opcode_2 == 2) - { + } else if (crm == 5 && opcode_2 == 2) { CP15[CP15_MAIN_TLB_LOCKDOWN_VIRT_ADDRESS] = value; - } - else if (crm == 6 && opcode_2 == 2) - { + } else if (crm == 6 && opcode_2 == 2) { CP15[CP15_MAIN_TLB_LOCKDOWN_PHYS_ADDRESS] = value; - } - else if (crm == 7 && opcode_2 == 2) - { + } else if (crm == 7 && opcode_2 == 2) { CP15[CP15_MAIN_TLB_LOCKDOWN_ATTRIBUTE] = value; } - } - else if (opcode_1 == 7 && crm == 1 && opcode_2 == 0) - { + } else if (opcode_1 == 7 && crm == 1 && opcode_2 == 0) { CP15[CP15_TLB_DEBUG_CONTROL] = value; } } } // Unprivileged registers - if (crn == 7 && opcode_1 == 0 && crm == 5 && opcode_2 == 4) - { + if (crn == 7 && opcode_1 == 0 && crm == 5 && opcode_2 == 4) { CP15[CP15_FLUSH_PREFETCH_BUFFER] = value; - } - else if (crn == 7 && opcode_1 == 0 && crm == 10) - { + } else if (crn == 7 && opcode_1 == 0 && crm == 10) { if (opcode_2 == 4) CP15[CP15_DATA_SYNC_BARRIER] = value; else if (opcode_2 == 5) CP15[CP15_DATA_MEMORY_BARRIER] = value; - } - else if (crn == 13 && opcode_1 == 0 && crm == 0 && opcode_2 == 2) - { + } else if (crn == 13 && opcode_1 == 0 && crm == 0 && opcode_2 == 2) { CP15[CP15_THREAD_UPRW] = value; } } diff --git a/src/core/arm/skyeye_common/armstate.h b/src/core/arm/skyeye_common/armstate.h index d42ff2669..1a707ff7e 100644 --- a/src/core/arm/skyeye_common/armstate.h +++ b/src/core/arm/skyeye_common/armstate.h @@ -19,80 +19,74 @@ #include <array> #include <unordered_map> - #include "common/common_types.h" #include "core/arm/skyeye_common/arm_regformat.h" // Signal levels -enum { - LOW = 0, - HIGH = 1, - LOWHIGH = 1, - HIGHLOW = 2 -}; +enum { LOW = 0, HIGH = 1, LOWHIGH = 1, HIGHLOW = 2 }; // Cache types enum { - NONCACHE = 0, + NONCACHE = 0, DATACACHE = 1, INSTCACHE = 2, }; // ARM privilege modes enum PrivilegeMode { - USER32MODE = 16, - FIQ32MODE = 17, - IRQ32MODE = 18, - SVC32MODE = 19, - ABORT32MODE = 23, - UNDEF32MODE = 27, + USER32MODE = 16, + FIQ32MODE = 17, + IRQ32MODE = 18, + SVC32MODE = 19, + ABORT32MODE = 23, + UNDEF32MODE = 27, SYSTEM32MODE = 31 }; // ARM privilege mode register banks enum { - USERBANK = 0, - FIQBANK = 1, - IRQBANK = 2, - SVCBANK = 3, - ABORTBANK = 4, - UNDEFBANK = 5, - DUMMYBANK = 6, + USERBANK = 0, + FIQBANK = 1, + IRQBANK = 2, + SVCBANK = 3, + ABORTBANK = 4, + UNDEFBANK = 5, + DUMMYBANK = 6, SYSTEMBANK = 7 }; // Hardware vector addresses enum { - ARMResetV = 0, + ARMResetV = 0, ARMUndefinedInstrV = 4, - ARMSWIV = 8, - ARMPrefetchAbortV = 12, - ARMDataAbortV = 16, - ARMAddrExceptnV = 20, - ARMIRQV = 24, - ARMFIQV = 28, - ARMErrorV = 32, // This is an offset, not an address! - - ARMul_ResetV = ARMResetV, + ARMSWIV = 8, + ARMPrefetchAbortV = 12, + ARMDataAbortV = 16, + ARMAddrExceptnV = 20, + ARMIRQV = 24, + ARMFIQV = 28, + ARMErrorV = 32, // This is an offset, not an address! + + ARMul_ResetV = ARMResetV, ARMul_UndefinedInstrV = ARMUndefinedInstrV, - ARMul_SWIV = ARMSWIV, - ARMul_PrefetchAbortV = ARMPrefetchAbortV, - ARMul_DataAbortV = ARMDataAbortV, - ARMul_AddrExceptnV = ARMAddrExceptnV, - ARMul_IRQV = ARMIRQV, - ARMul_FIQV = ARMFIQV + ARMul_SWIV = ARMSWIV, + ARMul_PrefetchAbortV = ARMPrefetchAbortV, + ARMul_DataAbortV = ARMDataAbortV, + ARMul_AddrExceptnV = ARMAddrExceptnV, + ARMul_IRQV = ARMIRQV, + ARMul_FIQV = ARMFIQV }; // Coprocessor status values enum { - ARMul_FIRST = 0, - ARMul_TRANSFER = 1, - ARMul_BUSY = 2, - ARMul_DATA = 3, + ARMul_FIRST = 0, + ARMul_TRANSFER = 1, + ARMul_BUSY = 2, + ARMul_DATA = 3, ARMul_INTERRUPT = 4, - ARMul_DONE = 0, - ARMul_CANT = 1, - ARMul_INC = 3 + ARMul_DONE = 0, + ARMul_CANT = 1, + ARMul_INC = 3 }; // Instruction condition codes @@ -136,15 +130,13 @@ enum : u32 { // Values for Emulate. enum { - STOP = 0, // Stop + STOP = 0, // Stop CHANGEMODE = 1, // Change mode - ONCE = 2, // Execute just one iteration - RUN = 3 // Continuous execution + ONCE = 2, // Execute just one iteration + RUN = 3 // Continuous execution }; - -struct ARMul_State final -{ +struct ARMul_State final { public: explicit ARMul_State(PrivilegeMode initial_mode); @@ -193,7 +185,7 @@ public: return TFlag ? 2 : 4; } - std::array<u32, 16> Reg{}; // The current register file + std::array<u32, 16> Reg{}; // The current register file std::array<u32, 2> Reg_usr{}; std::array<u32, 2> Reg_svc{}; // R13_SVC R14_SVC std::array<u32, 2> Reg_abort{}; // R13_ABORT R14_ABORT @@ -216,8 +208,8 @@ public: u32 Spsr_copy; u32 phys_pc; - u32 Mode; // The current mode - u32 Bank; // The current register bank + u32 Mode; // The current mode + u32 Bank; // The current register bank u32 NFlag, ZFlag, CFlag, VFlag, IFFlags; // Dummy flags for speed unsigned int shifter_carry_out; @@ -243,9 +235,9 @@ public: private: void ResetMPCoreCP15Registers(); - // Defines a reservation granule of 2 words, which protects the first 2 words starting at the tag. - // This is the smallest granule allowed by the v7 spec, and is coincidentally just large enough to - // support LDR/STREXD. + // Defines a reservation granule of 2 words, which protects the first 2 words starting at the + // tag. This is the smallest granule allowed by the v7 spec, and is coincidentally just large + // enough to support LDR/STREXD. static const u32 RESERVATION_GRANULE_MASK = 0xFFFFFFF8; u32 exclusive_tag; // The address for which the local monitor is in exclusive access mode diff --git a/src/core/arm/skyeye_common/armsupp.cpp b/src/core/arm/skyeye_common/armsupp.cpp index 883713e86..06aa1b075 100644 --- a/src/core/arm/skyeye_common/armsupp.cpp +++ b/src/core/arm/skyeye_common/armsupp.cpp @@ -16,14 +16,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "common/logging/log.h" - #include "core/arm/skyeye_common/arm_regformat.h" #include "core/arm/skyeye_common/armstate.h" #include "core/arm/skyeye_common/armsupp.h" // Unsigned sum of absolute difference -u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right) -{ +u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right) { if (left > right) return left - right; @@ -31,8 +29,8 @@ u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right) } // Add with carry, indicates if a carry-out or signed overflow occurred. -u32 AddWithCarry(u32 left, u32 right, u32 carry_in, bool* carry_out_occurred, bool* overflow_occurred) -{ +u32 AddWithCarry(u32 left, u32 right, u32 carry_in, bool* carry_out_occurred, + bool* overflow_occurred) { u64 unsigned_sum = (u64)left + (u64)right + (u64)carry_in; s64 signed_sum = (s64)(s32)left + (s64)(s32)right + (s64)carry_in; u64 result = (unsigned_sum & 0xFFFFFFFF); @@ -47,22 +45,17 @@ u32 AddWithCarry(u32 left, u32 right, u32 carry_in, bool* carry_out_occurred, bo } // Compute whether an addition of A and B, giving RESULT, overflowed. -bool AddOverflow(u32 a, u32 b, u32 result) -{ - return ((NEG(a) && NEG(b) && POS(result)) || - (POS(a) && POS(b) && NEG(result))); +bool AddOverflow(u32 a, u32 b, u32 result) { + return ((NEG(a) && NEG(b) && POS(result)) || (POS(a) && POS(b) && NEG(result))); } // Compute whether a subtraction of A and B, giving RESULT, overflowed. -bool SubOverflow(u32 a, u32 b, u32 result) -{ - return ((NEG(a) && POS(b) && POS(result)) || - (POS(a) && NEG(b) && NEG(result))); +bool SubOverflow(u32 a, u32 b, u32 result) { + return ((NEG(a) && POS(b) && POS(result)) || (POS(a) && NEG(b) && NEG(result))); } // Returns true if the Q flag should be set as a result of overflow. -bool ARMul_AddOverflowQ(u32 a, u32 b) -{ +bool ARMul_AddOverflowQ(u32 a, u32 b) { u32 result = a + b; if (((result ^ a) & (u32)0x80000000) && ((a ^ b) & (u32)0x80000000) == 0) return true; @@ -71,8 +64,7 @@ bool ARMul_AddOverflowQ(u32 a, u32 b) } // 8-bit signed saturated addition -u8 ARMul_SignedSaturatedAdd8(u8 left, u8 right) -{ +u8 ARMul_SignedSaturatedAdd8(u8 left, u8 right) { u8 result = left + right; if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) == 0) { @@ -86,8 +78,7 @@ u8 ARMul_SignedSaturatedAdd8(u8 left, u8 right) } // 8-bit signed saturated subtraction -u8 ARMul_SignedSaturatedSub8(u8 left, u8 right) -{ +u8 ARMul_SignedSaturatedSub8(u8 left, u8 right) { u8 result = left - right; if (((result ^ left) & 0x80) && ((left ^ right) & 0x80) != 0) { @@ -101,8 +92,7 @@ u8 ARMul_SignedSaturatedSub8(u8 left, u8 right) } // 16-bit signed saturated addition -u16 ARMul_SignedSaturatedAdd16(u16 left, u16 right) -{ +u16 ARMul_SignedSaturatedAdd16(u16 left, u16 right) { u16 result = left + right; if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) == 0) { @@ -116,8 +106,7 @@ u16 ARMul_SignedSaturatedAdd16(u16 left, u16 right) } // 16-bit signed saturated subtraction -u16 ARMul_SignedSaturatedSub16(u16 left, u16 right) -{ +u16 ARMul_SignedSaturatedSub16(u16 left, u16 right) { u16 result = left - right; if (((result ^ left) & 0x8000) && ((left ^ right) & 0x8000) != 0) { @@ -131,8 +120,7 @@ u16 ARMul_SignedSaturatedSub16(u16 left, u16 right) } // 8-bit unsigned saturated addition -u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right) -{ +u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right) { u8 result = left + right; if (result < left) @@ -142,8 +130,7 @@ u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right) } // 16-bit unsigned saturated addition -u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right) -{ +u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right) { u16 result = left + right; if (result < left) @@ -153,8 +140,7 @@ u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right) } // 8-bit unsigned saturated subtraction -u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right) -{ +u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right) { if (left <= right) return 0; @@ -162,8 +148,7 @@ u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right) } // 16-bit unsigned saturated subtraction -u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right) -{ +u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right) { if (left <= right) return 0; @@ -171,16 +156,14 @@ u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right) } // Signed saturation. -u32 ARMul_SignedSatQ(s32 value, u8 shift, bool* saturation_occurred) -{ +u32 ARMul_SignedSatQ(s32 value, u8 shift, bool* saturation_occurred) { const u32 max = (1 << shift) - 1; const s32 top = (value >> shift); if (top > 0) { *saturation_occurred = true; return max; - } - else if (top < -1) { + } else if (top < -1) { *saturation_occurred = true; return ~max; } @@ -190,8 +173,7 @@ u32 ARMul_SignedSatQ(s32 value, u8 shift, bool* saturation_occurred) } // Unsigned saturation -u32 ARMul_UnsignedSatQ(s32 value, u8 shift, bool* saturation_occurred) -{ +u32 ARMul_UnsignedSatQ(s32 value, u8 shift, bool* saturation_occurred) { const u32 max = (1 << shift) - 1; if (value < 0) { diff --git a/src/core/arm/skyeye_common/armsupp.h b/src/core/arm/skyeye_common/armsupp.h index 391309fa8..bf9299c07 100644 --- a/src/core/arm/skyeye_common/armsupp.h +++ b/src/core/arm/skyeye_common/armsupp.h @@ -9,8 +9,8 @@ #define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1)) #define BIT(s, n) ((s >> (n)) & 1) -#define POS(i) ( (~(i)) >> 31 ) -#define NEG(i) ( (i) >> 31 ) +#define POS(i) ((~(i)) >> 31) +#define NEG(i) ((i) >> 31) bool AddOverflow(u32, u32, u32); bool SubOverflow(u32, u32, u32); diff --git a/src/core/arm/skyeye_common/vfp/asm_vfp.h b/src/core/arm/skyeye_common/vfp/asm_vfp.h index 1187924f4..15b2394eb 100644 --- a/src/core/arm/skyeye_common/vfp/asm_vfp.h +++ b/src/core/arm/skyeye_common/vfp/asm_vfp.h @@ -10,74 +10,74 @@ // ARM11 MPCore FPSID Information // Note that these are used as values and not as flags. enum : u32 { - VFP_FPSID_IMPLMEN = 0x41, // Implementation code. Should be the same as cp15 0 c0 0 - VFP_FPSID_SW = 0, // Software emulation bit value - VFP_FPSID_SUBARCH = 0x1, // Subarchitecture version number - VFP_FPSID_PARTNUM = 0x20, // Part number - VFP_FPSID_VARIANT = 0xB, // Variant number - VFP_FPSID_REVISION = 0x4 // Revision number + VFP_FPSID_IMPLMEN = 0x41, // Implementation code. Should be the same as cp15 0 c0 0 + VFP_FPSID_SW = 0, // Software emulation bit value + VFP_FPSID_SUBARCH = 0x1, // Subarchitecture version number + VFP_FPSID_PARTNUM = 0x20, // Part number + VFP_FPSID_VARIANT = 0xB, // Variant number + VFP_FPSID_REVISION = 0x4 // Revision number }; // FPEXC bits enum : u32 { - FPEXC_EX = (1U << 31U), - FPEXC_EN = (1 << 30), - FPEXC_DEX = (1 << 29), - FPEXC_FP2V = (1 << 28), - FPEXC_VV = (1 << 27), - FPEXC_TFV = (1 << 26), - FPEXC_LENGTH_BIT = (8), + FPEXC_EX = (1U << 31U), + FPEXC_EN = (1 << 30), + FPEXC_DEX = (1 << 29), + FPEXC_FP2V = (1 << 28), + FPEXC_VV = (1 << 27), + FPEXC_TFV = (1 << 26), + FPEXC_LENGTH_BIT = (8), FPEXC_LENGTH_MASK = (7 << FPEXC_LENGTH_BIT), - FPEXC_IDF = (1 << 7), - FPEXC_IXF = (1 << 4), - FPEXC_UFF = (1 << 3), - FPEXC_OFF = (1 << 2), - FPEXC_DZF = (1 << 1), - FPEXC_IOF = (1 << 0), - FPEXC_TRAP_MASK = (FPEXC_IDF|FPEXC_IXF|FPEXC_UFF|FPEXC_OFF|FPEXC_DZF|FPEXC_IOF) + FPEXC_IDF = (1 << 7), + FPEXC_IXF = (1 << 4), + FPEXC_UFF = (1 << 3), + FPEXC_OFF = (1 << 2), + FPEXC_DZF = (1 << 1), + FPEXC_IOF = (1 << 0), + FPEXC_TRAP_MASK = (FPEXC_IDF | FPEXC_IXF | FPEXC_UFF | FPEXC_OFF | FPEXC_DZF | FPEXC_IOF) }; // FPSCR Flags enum : u32 { - FPSCR_NFLAG = (1U << 31U), // Negative condition flag - FPSCR_ZFLAG = (1 << 30), // Zero condition flag - FPSCR_CFLAG = (1 << 29), // Carry condition flag - FPSCR_VFLAG = (1 << 28), // Overflow condition flag + FPSCR_NFLAG = (1U << 31U), // Negative condition flag + FPSCR_ZFLAG = (1 << 30), // Zero condition flag + FPSCR_CFLAG = (1 << 29), // Carry condition flag + FPSCR_VFLAG = (1 << 28), // Overflow condition flag - FPSCR_QC = (1 << 27), // Cumulative saturation bit - FPSCR_AHP = (1 << 26), // Alternative half-precision control bit - FPSCR_DEFAULT_NAN = (1 << 25), // Default NaN mode control bit - FPSCR_FLUSH_TO_ZERO = (1 << 24), // Flush-to-zero mode control bit - FPSCR_RMODE_MASK = (3 << 22), // Rounding Mode bit mask - FPSCR_STRIDE_MASK = (3 << 20), // Vector stride bit mask - FPSCR_LENGTH_MASK = (7 << 16), // Vector length bit mask + FPSCR_QC = (1 << 27), // Cumulative saturation bit + FPSCR_AHP = (1 << 26), // Alternative half-precision control bit + FPSCR_DEFAULT_NAN = (1 << 25), // Default NaN mode control bit + FPSCR_FLUSH_TO_ZERO = (1 << 24), // Flush-to-zero mode control bit + FPSCR_RMODE_MASK = (3 << 22), // Rounding Mode bit mask + FPSCR_STRIDE_MASK = (3 << 20), // Vector stride bit mask + FPSCR_LENGTH_MASK = (7 << 16), // Vector length bit mask - FPSCR_IDE = (1 << 15), // Input Denormal exception trap enable. - FPSCR_IXE = (1 << 12), // Inexact exception trap enable - FPSCR_UFE = (1 << 11), // Undeflow exception trap enable - FPSCR_OFE = (1 << 10), // Overflow exception trap enable - FPSCR_DZE = (1 << 9), // Division by Zero exception trap enable - FPSCR_IOE = (1 << 8), // Invalid Operation exception trap enable + FPSCR_IDE = (1 << 15), // Input Denormal exception trap enable. + FPSCR_IXE = (1 << 12), // Inexact exception trap enable + FPSCR_UFE = (1 << 11), // Undeflow exception trap enable + FPSCR_OFE = (1 << 10), // Overflow exception trap enable + FPSCR_DZE = (1 << 9), // Division by Zero exception trap enable + FPSCR_IOE = (1 << 8), // Invalid Operation exception trap enable - FPSCR_IDC = (1 << 7), // Input Denormal cumulative exception bit - FPSCR_IXC = (1 << 4), // Inexact cumulative exception bit - FPSCR_UFC = (1 << 3), // Undeflow cumulative exception bit - FPSCR_OFC = (1 << 2), // Overflow cumulative exception bit - FPSCR_DZC = (1 << 1), // Division by Zero cumulative exception bit - FPSCR_IOC = (1 << 0), // Invalid Operation cumulative exception bit + FPSCR_IDC = (1 << 7), // Input Denormal cumulative exception bit + FPSCR_IXC = (1 << 4), // Inexact cumulative exception bit + FPSCR_UFC = (1 << 3), // Undeflow cumulative exception bit + FPSCR_OFC = (1 << 2), // Overflow cumulative exception bit + FPSCR_DZC = (1 << 1), // Division by Zero cumulative exception bit + FPSCR_IOC = (1 << 0), // Invalid Operation cumulative exception bit }; // FPSCR bit offsets enum : u32 { - FPSCR_RMODE_BIT = 22, + FPSCR_RMODE_BIT = 22, FPSCR_STRIDE_BIT = 20, FPSCR_LENGTH_BIT = 16, }; // FPSCR rounding modes enum : u32 { - FPSCR_ROUND_NEAREST = (0 << 22), - FPSCR_ROUND_PLUSINF = (1 << 22), + FPSCR_ROUND_NEAREST = (0 << 22), + FPSCR_ROUND_PLUSINF = (1 << 22), FPSCR_ROUND_MINUSINF = (2 << 22), - FPSCR_ROUND_TOZERO = (3 << 22) + FPSCR_ROUND_TOZERO = (3 << 22) }; diff --git a/src/core/arm/skyeye_common/vfp/vfp.cpp b/src/core/arm/skyeye_common/vfp/vfp.cpp index a27a7e194..f36c75a07 100644 --- a/src/core/arm/skyeye_common/vfp/vfp.cpp +++ b/src/core/arm/skyeye_common/vfp/vfp.cpp @@ -23,20 +23,18 @@ #include "common/common_funcs.h" #include "common/common_types.h" #include "common/logging/log.h" - #include "core/arm/skyeye_common/armstate.h" #include "core/arm/skyeye_common/vfp/asm_vfp.h" #include "core/arm/skyeye_common/vfp/vfp.h" -void VFPInit(ARMul_State* state) -{ - state->VFP[VFP_FPSID] = VFP_FPSID_IMPLMEN<<24 | VFP_FPSID_SW<<23 | VFP_FPSID_SUBARCH<<16 | - VFP_FPSID_PARTNUM<<8 | VFP_FPSID_VARIANT<<4 | VFP_FPSID_REVISION; +void VFPInit(ARMul_State* state) { + state->VFP[VFP_FPSID] = VFP_FPSID_IMPLMEN << 24 | VFP_FPSID_SW << 23 | VFP_FPSID_SUBARCH << 16 | + VFP_FPSID_PARTNUM << 8 | VFP_FPSID_VARIANT << 4 | VFP_FPSID_REVISION; state->VFP[VFP_FPEXC] = 0; state->VFP[VFP_FPSCR] = 0; // ARM11 MPCore instruction register reset values. - state->VFP[VFP_FPINST] = 0xEE000A00; + state->VFP[VFP_FPINST] = 0xEE000A00; state->VFP[VFP_FPINST2] = 0; // ARM11 MPCore feature register values. @@ -44,104 +42,80 @@ void VFPInit(ARMul_State* state) state->VFP[VFP_MVFR1] = 0; } -void VMOVBRS(ARMul_State* state, u32 to_arm, u32 t, u32 n, u32* value) -{ - if (to_arm) - { +void VMOVBRS(ARMul_State* state, u32 to_arm, u32 t, u32 n, u32* value) { + if (to_arm) { *value = state->ExtReg[n]; - } - else - { + } else { state->ExtReg[n] = *value; } } -void VMOVBRRD(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2) -{ - if (to_arm) - { - *value2 = state->ExtReg[n*2+1]; - *value1 = state->ExtReg[n*2]; - } - else - { - state->ExtReg[n*2+1] = *value2; - state->ExtReg[n*2] = *value1; +void VMOVBRRD(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2) { + if (to_arm) { + *value2 = state->ExtReg[n * 2 + 1]; + *value1 = state->ExtReg[n * 2]; + } else { + state->ExtReg[n * 2 + 1] = *value2; + state->ExtReg[n * 2] = *value1; } } -void VMOVBRRSS(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2) -{ - if (to_arm) - { - *value1 = state->ExtReg[n+0]; - *value2 = state->ExtReg[n+1]; - } - else - { - state->ExtReg[n+0] = *value1; - state->ExtReg[n+1] = *value2; +void VMOVBRRSS(ARMul_State* state, u32 to_arm, u32 t, u32 t2, u32 n, u32* value1, u32* value2) { + if (to_arm) { + *value1 = state->ExtReg[n + 0]; + *value2 = state->ExtReg[n + 1]; + } else { + state->ExtReg[n + 0] = *value1; + state->ExtReg[n + 1] = *value2; } } -void VMOVI(ARMul_State* state, u32 single, u32 d, u32 imm) -{ - if (single) - { +void VMOVI(ARMul_State* state, u32 single, u32 d, u32 imm) { + if (single) { state->ExtReg[d] = imm; - } - else - { + } else { /* Check endian please */ - state->ExtReg[d*2+1] = imm; - state->ExtReg[d*2] = 0; + state->ExtReg[d * 2 + 1] = imm; + state->ExtReg[d * 2] = 0; } } -void VMOVR(ARMul_State* state, u32 single, u32 d, u32 m) -{ - if (single) - { +void VMOVR(ARMul_State* state, u32 single, u32 d, u32 m) { + if (single) { state->ExtReg[d] = state->ExtReg[m]; - } - else - { + } else { /* Check endian please */ - state->ExtReg[d*2+1] = state->ExtReg[m*2+1]; - state->ExtReg[d*2] = state->ExtReg[m*2]; + state->ExtReg[d * 2 + 1] = state->ExtReg[m * 2 + 1]; + state->ExtReg[d * 2] = state->ExtReg[m * 2]; } } /* Miscellaneous functions */ -s32 vfp_get_float(ARMul_State* state, unsigned int reg) -{ +s32 vfp_get_float(ARMul_State* state, unsigned int reg) { LOG_TRACE(Core_ARM11, "VFP get float: s%d=[%08x]", reg, state->ExtReg[reg]); return state->ExtReg[reg]; } -void vfp_put_float(ARMul_State* state, s32 val, unsigned int reg) -{ +void vfp_put_float(ARMul_State* state, s32 val, unsigned int reg) { LOG_TRACE(Core_ARM11, "VFP put float: s%d <= [%08x]", reg, val); state->ExtReg[reg] = val; } -u64 vfp_get_double(ARMul_State* state, unsigned int reg) -{ - u64 result = ((u64) state->ExtReg[reg*2+1])<<32 | state->ExtReg[reg*2]; +u64 vfp_get_double(ARMul_State* state, unsigned int reg) { + u64 result = ((u64)state->ExtReg[reg * 2 + 1]) << 32 | state->ExtReg[reg * 2]; LOG_TRACE(Core_ARM11, "VFP get double: s[%d-%d]=[%016llx]", reg * 2 + 1, reg * 2, result); return result; } -void vfp_put_double(ARMul_State* state, u64 val, unsigned int reg) -{ - LOG_TRACE(Core_ARM11, "VFP put double: s[%d-%d] <= [%08x-%08x]", reg * 2 + 1, reg * 2, (u32)(val >> 32), (u32)(val & 0xffffffff)); - state->ExtReg[reg*2] = (u32) (val & 0xffffffff); - state->ExtReg[reg*2+1] = (u32) (val>>32); +void vfp_put_double(ARMul_State* state, u64 val, unsigned int reg) { + LOG_TRACE(Core_ARM11, "VFP put double: s[%d-%d] <= [%08x-%08x]", reg * 2 + 1, reg * 2, + (u32)(val >> 32), (u32)(val & 0xffffffff)); + state->ExtReg[reg * 2] = (u32)(val & 0xffffffff); + state->ExtReg[reg * 2 + 1] = (u32)(val >> 32); } /* * Process bitmask of exception conditions. (from vfpmodule.c) */ -void vfp_raise_exceptions(ARMul_State* state, u32 exceptions, u32 inst, u32 fpscr) -{ +void vfp_raise_exceptions(ARMul_State* state, u32 exceptions, u32 inst, u32 fpscr) { LOG_TRACE(Core_ARM11, "VFP: raising exceptions %08x", exceptions); if (exceptions == VFP_EXCEPTION_ERROR) { @@ -154,8 +128,8 @@ void vfp_raise_exceptions(ARMul_State* state, u32 exceptions, u32 inst, u32 fpsc * Comparison instructions always return at least one of * these flags set. */ - if (exceptions & (FPSCR_NFLAG|FPSCR_ZFLAG|FPSCR_CFLAG|FPSCR_VFLAG)) - fpscr &= ~(FPSCR_NFLAG|FPSCR_ZFLAG|FPSCR_CFLAG|FPSCR_VFLAG); + if (exceptions & (FPSCR_NFLAG | FPSCR_ZFLAG | FPSCR_CFLAG | FPSCR_VFLAG)) + fpscr &= ~(FPSCR_NFLAG | FPSCR_ZFLAG | FPSCR_CFLAG | FPSCR_VFLAG); fpscr |= exceptions; diff --git a/src/core/arm/skyeye_common/vfp/vfp_helper.h b/src/core/arm/skyeye_common/vfp/vfp_helper.h index 68714800c..5e14345ce 100644 --- a/src/core/arm/skyeye_common/vfp/vfp_helper.h +++ b/src/core/arm/skyeye_common/vfp/vfp_helper.h @@ -37,56 +37,56 @@ #include "core/arm/skyeye_common/armstate.h" #include "core/arm/skyeye_common/vfp/asm_vfp.h" -#define do_div(n, base) {n/=base;} +#define do_div(n, base) \ + { n /= base; } enum : u32 { - FOP_MASK = 0x00b00040, - FOP_FMAC = 0x00000000, + FOP_MASK = 0x00b00040, + FOP_FMAC = 0x00000000, FOP_FNMAC = 0x00000040, - FOP_FMSC = 0x00100000, + FOP_FMSC = 0x00100000, FOP_FNMSC = 0x00100040, - FOP_FMUL = 0x00200000, + FOP_FMUL = 0x00200000, FOP_FNMUL = 0x00200040, - FOP_FADD = 0x00300000, - FOP_FSUB = 0x00300040, - FOP_FDIV = 0x00800000, - FOP_EXT = 0x00b00040 + FOP_FADD = 0x00300000, + FOP_FSUB = 0x00300040, + FOP_FDIV = 0x00800000, + FOP_EXT = 0x00b00040 }; #define FOP_TO_IDX(inst) ((inst & 0x00b00000) >> 20 | (inst & (1 << 6)) >> 4) enum : u32 { - FEXT_MASK = 0x000f0080, - FEXT_FCPY = 0x00000000, - FEXT_FABS = 0x00000080, - FEXT_FNEG = 0x00010000, - FEXT_FSQRT = 0x00010080, - FEXT_FCMP = 0x00040000, - FEXT_FCMPE = 0x00040080, - FEXT_FCMPZ = 0x00050000, + FEXT_MASK = 0x000f0080, + FEXT_FCPY = 0x00000000, + FEXT_FABS = 0x00000080, + FEXT_FNEG = 0x00010000, + FEXT_FSQRT = 0x00010080, + FEXT_FCMP = 0x00040000, + FEXT_FCMPE = 0x00040080, + FEXT_FCMPZ = 0x00050000, FEXT_FCMPEZ = 0x00050080, - FEXT_FCVT = 0x00070080, - FEXT_FUITO = 0x00080000, - FEXT_FSITO = 0x00080080, - FEXT_FTOUI = 0x000c0000, + FEXT_FCVT = 0x00070080, + FEXT_FUITO = 0x00080000, + FEXT_FSITO = 0x00080080, + FEXT_FTOUI = 0x000c0000, FEXT_FTOUIZ = 0x000c0080, - FEXT_FTOSI = 0x000d0000, + FEXT_FTOSI = 0x000d0000, FEXT_FTOSIZ = 0x000d0080 }; #define FEXT_TO_IDX(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7) -#define vfp_get_sd(inst) ((inst & 0x0000f000) >> 11 | (inst & (1 << 22)) >> 22) -#define vfp_get_dd(inst) ((inst & 0x0000f000) >> 12 | (inst & (1 << 22)) >> 18) -#define vfp_get_sm(inst) ((inst & 0x0000000f) << 1 | (inst & (1 << 5)) >> 5) -#define vfp_get_dm(inst) ((inst & 0x0000000f) | (inst & (1 << 5)) >> 1) -#define vfp_get_sn(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7) -#define vfp_get_dn(inst) ((inst & 0x000f0000) >> 16 | (inst & (1 << 7)) >> 3) +#define vfp_get_sd(inst) ((inst & 0x0000f000) >> 11 | (inst & (1 << 22)) >> 22) +#define vfp_get_dd(inst) ((inst & 0x0000f000) >> 12 | (inst & (1 << 22)) >> 18) +#define vfp_get_sm(inst) ((inst & 0x0000000f) << 1 | (inst & (1 << 5)) >> 5) +#define vfp_get_dm(inst) ((inst & 0x0000000f) | (inst & (1 << 5)) >> 1) +#define vfp_get_sn(inst) ((inst & 0x000f0000) >> 15 | (inst & (1 << 7)) >> 7) +#define vfp_get_dn(inst) ((inst & 0x000f0000) >> 16 | (inst & (1 << 7)) >> 3) -#define vfp_single(inst) (((inst) & 0x0000f00) == 0xa00) +#define vfp_single(inst) (((inst)&0x0000f00) == 0xa00) -inline u32 vfp_shiftright32jamming(u32 val, unsigned int shift) -{ +inline u32 vfp_shiftright32jamming(u32 val, unsigned int shift) { if (shift) { if (shift < 32) val = val >> shift | ((val << (32 - shift)) != 0); @@ -96,8 +96,7 @@ inline u32 vfp_shiftright32jamming(u32 val, unsigned int shift) return val; } -inline u64 vfp_shiftright64jamming(u64 val, unsigned int shift) -{ +inline u64 vfp_shiftright64jamming(u64 val, unsigned int shift) { if (shift) { if (shift < 64) val = val >> shift | ((val << (64 - shift)) != 0); @@ -107,8 +106,7 @@ inline u64 vfp_shiftright64jamming(u64 val, unsigned int shift) return val; } -inline u32 vfp_hi64to32jamming(u64 val) -{ +inline u32 vfp_hi64to32jamming(u64 val) { u32 v; u32 highval = val >> 32; u32 lowval = val & 0xffffffff; @@ -121,24 +119,21 @@ inline u32 vfp_hi64to32jamming(u64 val) return v; } -inline void add128(u64* resh, u64* resl, u64 nh, u64 nl, u64 mh, u64 ml) -{ +inline void add128(u64* resh, u64* resl, u64 nh, u64 nl, u64 mh, u64 ml) { *resl = nl + ml; *resh = nh + mh; if (*resl < nl) *resh += 1; } -inline void sub128(u64* resh, u64* resl, u64 nh, u64 nl, u64 mh, u64 ml) -{ +inline void sub128(u64* resh, u64* resl, u64 nh, u64 nl, u64 mh, u64 ml) { *resl = nl - ml; *resh = nh - mh; if (*resl > nl) *resh -= 1; } -inline void mul64to128(u64* resh, u64* resl, u64 n, u64 m) -{ +inline void mul64to128(u64* resh, u64* resl, u64 n, u64 m) { u32 nh, nl, mh, ml; u64 rh, rma, rmb, rl; @@ -164,21 +159,18 @@ inline void mul64to128(u64* resh, u64* resl, u64 n, u64 m) *resh = rh; } -inline void shift64left(u64* resh, u64* resl, u64 n) -{ +inline void shift64left(u64* resh, u64* resl, u64 n) { *resh = n >> 63; *resl = n << 1; } -inline u64 vfp_hi64multiply64(u64 n, u64 m) -{ +inline u64 vfp_hi64multiply64(u64 n, u64 m) { u64 rh, rl; mul64to128(&rh, &rl, n, m); return rh | (rl != 0); } -inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m) -{ +inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m) { u64 mh, ml, remh, reml, termh, terml, z; if (nh >= m) @@ -213,9 +205,9 @@ inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m) // Single-precision struct vfp_single { - s16 exponent; - u16 sign; - u32 significand; + s16 exponent; + u16 sign; + u32 significand; }; // VFP_SINGLE_MANTISSA_BITS - number of bits in the mantissa @@ -224,33 +216,33 @@ struct vfp_single { // which are not propagated to the float upon packing. #define VFP_SINGLE_MANTISSA_BITS (23) #define VFP_SINGLE_EXPONENT_BITS (8) -#define VFP_SINGLE_LOW_BITS (32 - VFP_SINGLE_MANTISSA_BITS - 2) +#define VFP_SINGLE_LOW_BITS (32 - VFP_SINGLE_MANTISSA_BITS - 2) #define VFP_SINGLE_LOW_BITS_MASK ((1 << VFP_SINGLE_LOW_BITS) - 1) // The bit in an unpacked float which indicates that it is a quiet NaN -#define VFP_SINGLE_SIGNIFICAND_QNAN (1 << (VFP_SINGLE_MANTISSA_BITS - 1 + VFP_SINGLE_LOW_BITS)) +#define VFP_SINGLE_SIGNIFICAND_QNAN (1 << (VFP_SINGLE_MANTISSA_BITS - 1 + VFP_SINGLE_LOW_BITS)) // Operations on packed single-precision numbers -#define vfp_single_packed_sign(v) ((v) & 0x80000000) -#define vfp_single_packed_negate(v) ((v) ^ 0x80000000) -#define vfp_single_packed_abs(v) ((v) & ~0x80000000) -#define vfp_single_packed_exponent(v) (((v) >> VFP_SINGLE_MANTISSA_BITS) & ((1 << VFP_SINGLE_EXPONENT_BITS) - 1)) +#define vfp_single_packed_sign(v) ((v)&0x80000000) +#define vfp_single_packed_negate(v) ((v) ^ 0x80000000) +#define vfp_single_packed_abs(v) ((v) & ~0x80000000) +#define vfp_single_packed_exponent(v) \ + (((v) >> VFP_SINGLE_MANTISSA_BITS) & ((1 << VFP_SINGLE_EXPONENT_BITS) - 1)) #define vfp_single_packed_mantissa(v) ((v) & ((1 << VFP_SINGLE_MANTISSA_BITS) - 1)) enum : u32 { - VFP_NUMBER = (1 << 0), - VFP_ZERO = (1 << 1), - VFP_DENORMAL = (1 << 2), - VFP_INFINITY = (1 << 3), - VFP_NAN = (1 << 4), + VFP_NUMBER = (1 << 0), + VFP_ZERO = (1 << 1), + VFP_DENORMAL = (1 << 2), + VFP_INFINITY = (1 << 3), + VFP_NAN = (1 << 4), VFP_NAN_SIGNAL = (1 << 5), - VFP_QNAN = (VFP_NAN), - VFP_SNAN = (VFP_NAN|VFP_NAN_SIGNAL) + VFP_QNAN = (VFP_NAN), + VFP_SNAN = (VFP_NAN | VFP_NAN_SIGNAL) }; -inline int vfp_single_type(const vfp_single* s) -{ +inline int vfp_single_type(const vfp_single* s) { int type = VFP_NUMBER; if (s->exponent == 255) { if (s->significand == 0) @@ -271,11 +263,9 @@ inline int vfp_single_type(const vfp_single* s) // Unpack a single-precision float. Note that this returns the magnitude // of the single-precision float mantissa with the 1. if necessary, // aligned to bit 30. -inline u32 vfp_single_unpack(vfp_single* s, s32 val, u32 fpscr) -{ +inline u32 vfp_single_unpack(vfp_single* s, s32 val, u32 fpscr) { u32 exceptions = 0; - s->sign = vfp_single_packed_sign(val) >> 16, - s->exponent = vfp_single_packed_exponent(val); + s->sign = vfp_single_packed_sign(val) >> 16, s->exponent = vfp_single_packed_exponent(val); u32 significand = ((u32)val << (32 - VFP_SINGLE_MANTISSA_BITS)) >> 2; if (s->exponent && s->exponent != 255) @@ -295,22 +285,20 @@ inline u32 vfp_single_unpack(vfp_single* s, s32 val, u32 fpscr) // Re-pack a single-precision float. This assumes that the float is // already normalised such that the MSB is bit 30, _not_ bit 31. -inline s32 vfp_single_pack(const vfp_single* s) -{ - u32 val = (s->sign << 16) + - (s->exponent << VFP_SINGLE_MANTISSA_BITS) + +inline s32 vfp_single_pack(const vfp_single* s) { + u32 val = (s->sign << 16) + (s->exponent << VFP_SINGLE_MANTISSA_BITS) + (s->significand >> VFP_SINGLE_LOW_BITS); return (s32)val; } - -u32 vfp_single_normaliseround(ARMul_State* state, int sd, vfp_single* vs, u32 fpscr, const char* func); +u32 vfp_single_normaliseround(ARMul_State* state, int sd, vfp_single* vs, u32 fpscr, + const char* func); // Double-precision struct vfp_double { - s16 exponent; - u16 sign; - u64 significand; + s16 exponent; + u16 sign; + u64 significand; }; // VFP_REG_ZERO is a special register number for vfp_get_double @@ -324,21 +312,21 @@ struct vfp_double { #define VFP_DOUBLE_MANTISSA_BITS (52) #define VFP_DOUBLE_EXPONENT_BITS (11) -#define VFP_DOUBLE_LOW_BITS (64 - VFP_DOUBLE_MANTISSA_BITS - 2) +#define VFP_DOUBLE_LOW_BITS (64 - VFP_DOUBLE_MANTISSA_BITS - 2) #define VFP_DOUBLE_LOW_BITS_MASK ((1 << VFP_DOUBLE_LOW_BITS) - 1) // The bit in an unpacked double which indicates that it is a quiet NaN #define VFP_DOUBLE_SIGNIFICAND_QNAN (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1 + VFP_DOUBLE_LOW_BITS)) // Operations on packed single-precision numbers -#define vfp_double_packed_sign(v) ((v) & (1ULL << 63)) -#define vfp_double_packed_negate(v) ((v) ^ (1ULL << 63)) -#define vfp_double_packed_abs(v) ((v) & ~(1ULL << 63)) -#define vfp_double_packed_exponent(v) (((v) >> VFP_DOUBLE_MANTISSA_BITS) & ((1 << VFP_DOUBLE_EXPONENT_BITS) - 1)) +#define vfp_double_packed_sign(v) ((v) & (1ULL << 63)) +#define vfp_double_packed_negate(v) ((v) ^ (1ULL << 63)) +#define vfp_double_packed_abs(v) ((v) & ~(1ULL << 63)) +#define vfp_double_packed_exponent(v) \ + (((v) >> VFP_DOUBLE_MANTISSA_BITS) & ((1 << VFP_DOUBLE_EXPONENT_BITS) - 1)) #define vfp_double_packed_mantissa(v) ((v) & ((1ULL << VFP_DOUBLE_MANTISSA_BITS) - 1)) -inline int vfp_double_type(const vfp_double* s) -{ +inline int vfp_double_type(const vfp_double* s) { int type = VFP_NUMBER; if (s->exponent == 2047) { if (s->significand == 0) @@ -359,8 +347,7 @@ inline int vfp_double_type(const vfp_double* s) // Unpack a double-precision float. Note that this returns the magnitude // of the double-precision float mantissa with the 1. if necessary, // aligned to bit 62. -inline u32 vfp_double_unpack(vfp_double* s, s64 val, u32 fpscr) -{ +inline u32 vfp_double_unpack(vfp_double* s, s64 val, u32 fpscr) { u32 exceptions = 0; s->sign = vfp_double_packed_sign(val) >> 48; s->exponent = vfp_double_packed_exponent(val); @@ -383,10 +370,8 @@ inline u32 vfp_double_unpack(vfp_double* s, s64 val, u32 fpscr) // Re-pack a double-precision float. This assumes that the float is // already normalised such that the MSB is bit 30, _not_ bit 31. -inline s64 vfp_double_pack(const vfp_double* s) -{ - u64 val = ((u64)s->sign << 48) + - ((u64)s->exponent << VFP_DOUBLE_MANTISSA_BITS) + +inline s64 vfp_double_pack(const vfp_double* s) { + u64 val = ((u64)s->sign << 48) + ((u64)s->exponent << VFP_DOUBLE_MANTISSA_BITS) + (s->significand >> VFP_DOUBLE_LOW_BITS); return (s64)val; } @@ -407,20 +392,14 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand); // OP_SD - The instruction exceptionally writes to a single precision result. // OP_DD - The instruction exceptionally writes to a double precision result. // OP_SM - The instruction exceptionally reads from a single precision operand. -enum : u32 { - OP_SCALAR = (1 << 0), - OP_SD = (1 << 1), - OP_DD = (1 << 1), - OP_SM = (1 << 2) -}; +enum : u32 { OP_SCALAR = (1 << 0), OP_SD = (1 << 1), OP_DD = (1 << 1), OP_SM = (1 << 2) }; struct op { - u32 (* const fn)(ARMul_State* state, int dd, int dn, int dm, u32 fpscr); + u32 (*const fn)(ARMul_State* state, int dd, int dn, int dm, u32 fpscr); u32 flags; }; -inline u32 fls(u32 x) -{ +inline u32 fls(u32 x) { int r = 32; if (!x) @@ -446,9 +425,9 @@ inline u32 fls(u32 x) r -= 1; } return r; - } u32 vfp_double_multiply(vfp_double* vdd, vfp_double* vdn, vfp_double* vdm, u32 fpscr); -u32 vfp_double_add(vfp_double* vdd, vfp_double* vdn, vfp_double *vdm, u32 fpscr); -u32 vfp_double_normaliseround(ARMul_State* state, int dd, vfp_double* vd, u32 fpscr, const char* func); +u32 vfp_double_add(vfp_double* vdd, vfp_double* vdn, vfp_double* vdm, u32 fpscr); +u32 vfp_double_normaliseround(ARMul_State* state, int dd, vfp_double* vd, u32 fpscr, + const char* func); diff --git a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp index 1d5641810..2886f351f 100644 --- a/src/core/arm/skyeye_common/vfp/vfpdouble.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpdouble.cpp @@ -53,24 +53,20 @@ #include <algorithm> #include "common/logging/log.h" +#include "core/arm/skyeye_common/vfp/asm_vfp.h" #include "core/arm/skyeye_common/vfp/vfp.h" #include "core/arm/skyeye_common/vfp/vfp_helper.h" -#include "core/arm/skyeye_common/vfp/asm_vfp.h" static struct vfp_double vfp_double_default_qnan = { - 2047, - 0, - VFP_DOUBLE_SIGNIFICAND_QNAN, + 2047, 0, VFP_DOUBLE_SIGNIFICAND_QNAN, }; -static void vfp_double_dump(const char *str, struct vfp_double *d) -{ - LOG_TRACE(Core_ARM11, "VFP: %s: sign=%d exponent=%d significand=%016llx", - str, d->sign != 0, d->exponent, d->significand); +static void vfp_double_dump(const char* str, struct vfp_double* d) { + LOG_TRACE(Core_ARM11, "VFP: %s: sign=%d exponent=%d significand=%016llx", str, d->sign != 0, + d->exponent, d->significand); } -static void vfp_double_normalise_denormal(struct vfp_double *vd) -{ +static void vfp_double_normalise_denormal(struct vfp_double* vd) { int bits = 31 - fls((u32)(vd->significand >> 32)); if (bits == 31) bits = 63 - fls((u32)vd->significand); @@ -85,8 +81,8 @@ static void vfp_double_normalise_denormal(struct vfp_double *vd) vfp_double_dump("normalise_denormal: out", vd); } -u32 vfp_double_normaliseround(ARMul_State* state, int dd, struct vfp_double *vd, u32 fpscr, const char *func) -{ +u32 vfp_double_normaliseround(ARMul_State* state, int dd, struct vfp_double* vd, u32 fpscr, + const char* func) { u64 significand, incr; int exponent, shift, underflow; u32 rmode; @@ -193,7 +189,7 @@ u32 vfp_double_normaliseround(ARMul_State* state, int dd, struct vfp_double *vd, vd->exponent = 2045; vd->significand = 0x7fffffffffffffffULL; } else { - vd->exponent = 2047; /* infinity */ + vd->exponent = 2047; /* infinity */ vd->significand = 0; } } else { @@ -211,8 +207,7 @@ pack: vfp_double_dump("pack: final", vd); { s64 d = vfp_double_pack(vd); - LOG_TRACE(Core_ARM11, "VFP: %s: d(d%d)=%016llx exceptions=%08x", func, - dd, d, exceptions); + LOG_TRACE(Core_ARM11, "VFP: %s: d(d%d)=%016llx exceptions=%08x", func, dd, d, exceptions); vfp_put_double(state, d, dd); } return exceptions; @@ -222,11 +217,9 @@ pack: * Propagate the NaN, setting exceptions if it is signalling. * 'n' is always a NaN. 'm' may be a number, NaN or infinity. */ -static u32 -vfp_propagate_nan(struct vfp_double *vdd, struct vfp_double *vdn, - struct vfp_double *vdm, u32 fpscr) -{ - struct vfp_double *nan; +static u32 vfp_propagate_nan(struct vfp_double* vdd, struct vfp_double* vdn, struct vfp_double* vdm, + u32 fpscr) { + struct vfp_double* nan; int tn, tm = 0; tn = vfp_double_type(vdn); @@ -266,29 +259,25 @@ vfp_propagate_nan(struct vfp_double *vdd, struct vfp_double *vdn, /* * Extended operations */ -static u32 vfp_double_fabs(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) -{ +static u32 vfp_double_fabs(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { LOG_TRACE(Core_ARM11, "In %s", __FUNCTION__); vfp_put_double(state, vfp_double_packed_abs(vfp_get_double(state, dm)), dd); return 0; } -static u32 vfp_double_fcpy(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) -{ +static u32 vfp_double_fcpy(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { LOG_TRACE(Core_ARM11, "In %s", __FUNCTION__); vfp_put_double(state, vfp_get_double(state, dm), dd); return 0; } -static u32 vfp_double_fneg(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) -{ +static u32 vfp_double_fneg(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { LOG_TRACE(Core_ARM11, "In %s", __FUNCTION__); vfp_put_double(state, vfp_double_packed_negate(vfp_get_double(state, dm)), dd); return 0; } -static u32 vfp_double_fsqrt(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) -{ +static u32 vfp_double_fsqrt(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { LOG_TRACE(Core_ARM11, "In %s", __FUNCTION__); vfp_double vdm, vdd, *vdp; int ret, tm; @@ -297,17 +286,17 @@ static u32 vfp_double_fsqrt(ARMul_State* state, int dd, int unused, int dm, u32 exceptions |= vfp_double_unpack(&vdm, vfp_get_double(state, dm), fpscr); tm = vfp_double_type(&vdm); - if (tm & (VFP_NAN|VFP_INFINITY)) { + if (tm & (VFP_NAN | VFP_INFINITY)) { vdp = &vdd; if (tm & VFP_NAN) ret = vfp_propagate_nan(vdp, &vdm, nullptr, fpscr); else if (vdm.sign == 0) { -sqrt_copy: + sqrt_copy: vdp = &vdm; ret = 0; } else { -sqrt_invalid: + sqrt_invalid: vdp = &vfp_double_default_qnan; ret = FPSCR_IOC; } @@ -381,8 +370,7 @@ sqrt_invalid: * Greater than := C * Unordered := CV */ -static u32 vfp_compare(ARMul_State* state, int dd, int signal_on_qnan, int dm, u32 fpscr) -{ +static u32 vfp_compare(ARMul_State* state, int dd, int signal_on_qnan, int dm, u32 fpscr) { s64 d, m; u32 ret = 0; @@ -390,7 +378,8 @@ static u32 vfp_compare(ARMul_State* state, int dd, int signal_on_qnan, int dm, u m = vfp_get_double(state, dm); if (vfp_double_packed_exponent(m) == 2047 && vfp_double_packed_mantissa(m)) { ret |= FPSCR_CFLAG | FPSCR_VFLAG; - if (signal_on_qnan || !(vfp_double_packed_mantissa(m) & (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1)))) + if (signal_on_qnan || + !(vfp_double_packed_mantissa(m) & (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1)))) /* * Signalling NaN, or signalling on quiet NaN */ @@ -400,7 +389,8 @@ static u32 vfp_compare(ARMul_State* state, int dd, int signal_on_qnan, int dm, u d = vfp_get_double(state, dd); if (vfp_double_packed_exponent(d) == 2047 && vfp_double_packed_mantissa(d)) { ret |= FPSCR_CFLAG | FPSCR_VFLAG; - if (signal_on_qnan || !(vfp_double_packed_mantissa(d) & (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1)))) + if (signal_on_qnan || + !(vfp_double_packed_mantissa(d) & (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1)))) /* * Signalling NaN, or signalling on quiet NaN */ @@ -408,13 +398,13 @@ static u32 vfp_compare(ARMul_State* state, int dd, int signal_on_qnan, int dm, u } if (ret == 0) { - //printf("In %s, d=%lld, m =%lld\n ", __FUNCTION__, d, m); + // printf("In %s, d=%lld, m =%lld\n ", __FUNCTION__, d, m); if (d == m || vfp_double_packed_abs(d | m) == 0) { /* * equal */ ret |= FPSCR_ZFLAG | FPSCR_CFLAG; - //printf("In %s,1 ret=0x%x\n", __FUNCTION__, ret); + // printf("In %s,1 ret=0x%x\n", __FUNCTION__, ret); } else if (vfp_double_packed_sign(d ^ m)) { /* * different signs @@ -446,32 +436,27 @@ static u32 vfp_compare(ARMul_State* state, int dd, int signal_on_qnan, int dm, u return ret; } -static u32 vfp_double_fcmp(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) -{ +static u32 vfp_double_fcmp(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { LOG_TRACE(Core_ARM11, "In %s", __FUNCTION__); return vfp_compare(state, dd, 0, dm, fpscr); } -static u32 vfp_double_fcmpe(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) -{ +static u32 vfp_double_fcmpe(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { LOG_TRACE(Core_ARM11, "In %s", __FUNCTION__); return vfp_compare(state, dd, 1, dm, fpscr); } -static u32 vfp_double_fcmpz(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) -{ +static u32 vfp_double_fcmpz(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { LOG_TRACE(Core_ARM11, "In %s", __FUNCTION__); return vfp_compare(state, dd, 0, VFP_REG_ZERO, fpscr); } -static u32 vfp_double_fcmpez(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) -{ +static u32 vfp_double_fcmpez(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { LOG_TRACE(Core_ARM11, "In %s", __FUNCTION__); return vfp_compare(state, dd, 1, VFP_REG_ZERO, fpscr); } -static u32 vfp_double_fcvts(ARMul_State* state, int sd, int unused, int dm, u32 fpscr) -{ +static u32 vfp_double_fcvts(ARMul_State* state, int sd, int unused, int dm, u32 fpscr) { struct vfp_double vdm; struct vfp_single vsd; int tm; @@ -497,7 +482,7 @@ static u32 vfp_double_fcvts(ARMul_State* state, int sd, int unused, int dm, u32 /* * If we have an infinity or a NaN, the exponent must be 255 */ - if (tm & (VFP_INFINITY|VFP_NAN)) { + if (tm & (VFP_INFINITY | VFP_NAN)) { vsd.exponent = 255; if (tm == VFP_QNAN) vsd.significand |= VFP_SINGLE_SIGNIFICAND_QNAN; @@ -515,8 +500,7 @@ pack_nan: return exceptions; } -static u32 vfp_double_fuito(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) -{ +static u32 vfp_double_fuito(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { struct vfp_double vdm; u32 exceptions = 0; u32 m = vfp_get_float(state, dm); @@ -530,8 +514,7 @@ static u32 vfp_double_fuito(ARMul_State* state, int dd, int unused, int dm, u32 return exceptions; } -static u32 vfp_double_fsito(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) -{ +static u32 vfp_double_fsito(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { struct vfp_double vdm; u32 exceptions = 0; u32 m = vfp_get_float(state, dm); @@ -545,8 +528,7 @@ static u32 vfp_double_fsito(ARMul_State* state, int dd, int unused, int dm, u32 return exceptions; } -static u32 vfp_double_ftoui(ARMul_State* state, int sd, int unused, int dm, u32 fpscr) -{ +static u32 vfp_double_ftoui(ARMul_State* state, int sd, int unused, int dm, u32 fpscr) { struct vfp_double vdm; u32 d, exceptions = 0; int rmode = fpscr & FPSCR_RMODE_MASK; @@ -628,14 +610,13 @@ static u32 vfp_double_ftoui(ARMul_State* state, int sd, int unused, int dm, u32 return exceptions; } -static u32 vfp_double_ftouiz(ARMul_State* state, int sd, int unused, int dm, u32 fpscr) -{ +static u32 vfp_double_ftouiz(ARMul_State* state, int sd, int unused, int dm, u32 fpscr) { LOG_TRACE(Core_ARM11, "In %s", __FUNCTION__); - return vfp_double_ftoui(state, sd, unused, dm, (fpscr & ~FPSCR_RMODE_MASK) | FPSCR_ROUND_TOZERO); + return vfp_double_ftoui(state, sd, unused, dm, + (fpscr & ~FPSCR_RMODE_MASK) | FPSCR_ROUND_TOZERO); } -static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32 fpscr) -{ +static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32 fpscr) { struct vfp_double vdm; u32 d, exceptions = 0; int rmode = fpscr & FPSCR_RMODE_MASK; @@ -661,7 +642,7 @@ static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32 d = ~d; exceptions |= FPSCR_IOC; } else if (vdm.exponent >= 1023) { - int shift = 1023 + 63 - vdm.exponent; /* 58 */ + int shift = 1023 + 63 - vdm.exponent; /* 58 */ u64 rem, incr = 0; d = (u32)((vdm.significand << 1) >> shift); @@ -712,48 +693,46 @@ static u32 vfp_double_ftosi(ARMul_State* state, int sd, int unused, int dm, u32 return exceptions; } -static u32 vfp_double_ftosiz(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) -{ +static u32 vfp_double_ftosiz(ARMul_State* state, int dd, int unused, int dm, u32 fpscr) { LOG_TRACE(Core_ARM11, "In %s", __FUNCTION__); - return vfp_double_ftosi(state, dd, unused, dm, (fpscr & ~FPSCR_RMODE_MASK) | FPSCR_ROUND_TOZERO); + return vfp_double_ftosi(state, dd, unused, dm, + (fpscr & ~FPSCR_RMODE_MASK) | FPSCR_ROUND_TOZERO); } static struct op fops_ext[] = { - { vfp_double_fcpy, 0 }, //0x00000000 - FEXT_FCPY - { vfp_double_fabs, 0 }, //0x00000001 - FEXT_FABS - { vfp_double_fneg, 0 }, //0x00000002 - FEXT_FNEG - { vfp_double_fsqrt, 0 }, //0x00000003 - FEXT_FSQRT - { nullptr, 0 }, - { nullptr, 0 }, - { nullptr, 0 }, - { nullptr, 0 }, - { vfp_double_fcmp, OP_SCALAR }, //0x00000008 - FEXT_FCMP - { vfp_double_fcmpe, OP_SCALAR }, //0x00000009 - FEXT_FCMPE - { vfp_double_fcmpz, OP_SCALAR }, //0x0000000A - FEXT_FCMPZ - { vfp_double_fcmpez, OP_SCALAR }, //0x0000000B - FEXT_FCMPEZ - { nullptr, 0 }, - { nullptr, 0 }, - { nullptr, 0 }, - { vfp_double_fcvts, OP_SCALAR|OP_DD }, //0x0000000F - FEXT_FCVT - { vfp_double_fuito, OP_SCALAR|OP_SM }, //0x00000010 - FEXT_FUITO - { vfp_double_fsito, OP_SCALAR|OP_SM }, //0x00000011 - FEXT_FSITO - { nullptr, 0 }, - { nullptr, 0 }, - { nullptr, 0 }, - { nullptr, 0 }, - { nullptr, 0 }, - { nullptr, 0 }, - { vfp_double_ftoui, OP_SCALAR|OP_SD }, //0x00000018 - FEXT_FTOUI - { vfp_double_ftouiz, OP_SCALAR|OP_SD }, //0x00000019 - FEXT_FTOUIZ - { vfp_double_ftosi, OP_SCALAR|OP_SD }, //0x0000001A - FEXT_FTOSI - { vfp_double_ftosiz, OP_SCALAR|OP_SD }, //0x0000001B - FEXT_FTOSIZ + {vfp_double_fcpy, 0}, // 0x00000000 - FEXT_FCPY + {vfp_double_fabs, 0}, // 0x00000001 - FEXT_FABS + {vfp_double_fneg, 0}, // 0x00000002 - FEXT_FNEG + {vfp_double_fsqrt, 0}, // 0x00000003 - FEXT_FSQRT + {nullptr, 0}, + {nullptr, 0}, + {nullptr, 0}, + {nullptr, 0}, + {vfp_double_fcmp, OP_SCALAR}, // 0x00000008 - FEXT_FCMP + {vfp_double_fcmpe, OP_SCALAR}, // 0x00000009 - FEXT_FCMPE + {vfp_double_fcmpz, OP_SCALAR}, // 0x0000000A - FEXT_FCMPZ + {vfp_double_fcmpez, OP_SCALAR}, // 0x0000000B - FEXT_FCMPEZ + {nullptr, 0}, + {nullptr, 0}, + {nullptr, 0}, + {vfp_double_fcvts, OP_SCALAR | OP_DD}, // 0x0000000F - FEXT_FCVT + {vfp_double_fuito, OP_SCALAR | OP_SM}, // 0x00000010 - FEXT_FUITO + {vfp_double_fsito, OP_SCALAR | OP_SM}, // 0x00000011 - FEXT_FSITO + {nullptr, 0}, + {nullptr, 0}, + {nullptr, 0}, + {nullptr, 0}, + {nullptr, 0}, + {nullptr, 0}, + {vfp_double_ftoui, OP_SCALAR | OP_SD}, // 0x00000018 - FEXT_FTOUI + {vfp_double_ftouiz, OP_SCALAR | OP_SD}, // 0x00000019 - FEXT_FTOUIZ + {vfp_double_ftosi, OP_SCALAR | OP_SD}, // 0x0000001A - FEXT_FTOSI + {vfp_double_ftosiz, OP_SCALAR | OP_SD}, // 0x0000001B - FEXT_FTOSIZ }; -static u32 -vfp_double_fadd_nonnumber(struct vfp_double *vdd, struct vfp_double *vdn, - struct vfp_double *vdm, u32 fpscr) -{ - struct vfp_double *vdp; +static u32 vfp_double_fadd_nonnumber(struct vfp_double* vdd, struct vfp_double* vdn, + struct vfp_double* vdm, u32 fpscr) { + struct vfp_double* vdp; u32 exceptions = 0; int tn, tm; @@ -791,13 +770,12 @@ vfp_double_fadd_nonnumber(struct vfp_double *vdd, struct vfp_double *vdn, return exceptions; } -u32 vfp_double_add(struct vfp_double *vdd, struct vfp_double *vdn,struct vfp_double *vdm, u32 fpscr) -{ +u32 vfp_double_add(struct vfp_double* vdd, struct vfp_double* vdn, struct vfp_double* vdm, + u32 fpscr) { u32 exp_diff; u64 m_sig; - if (vdn->significand & (1ULL << 63) || - vdm->significand & (1ULL << 63)) { + if (vdn->significand & (1ULL << 63) || vdm->significand & (1ULL << 63)) { LOG_INFO(Core_ARM11, "VFP: bad FP values in %s", __func__); vfp_double_dump("VDN", vdn); vfp_double_dump("VDM", vdm); @@ -841,8 +819,7 @@ u32 vfp_double_add(struct vfp_double *vdd, struct vfp_double *vdn,struct vfp_dou vdd->sign = vfp_sign_negate(vdd->sign); m_sig = (~m_sig + 1); } else if (m_sig == 0) { - vdd->sign = (fpscr & FPSCR_RMODE_MASK) == - FPSCR_ROUND_MINUSINF ? 0x8000 : 0; + vdd->sign = (fpscr & FPSCR_RMODE_MASK) == FPSCR_ROUND_MINUSINF ? 0x8000 : 0; } } else { m_sig += vdn->significand; @@ -852,10 +829,8 @@ u32 vfp_double_add(struct vfp_double *vdd, struct vfp_double *vdn,struct vfp_dou return 0; } -u32 -vfp_double_multiply(struct vfp_double *vdd, struct vfp_double *vdn, - struct vfp_double *vdm, u32 fpscr) -{ +u32 vfp_double_multiply(struct vfp_double* vdd, struct vfp_double* vdn, struct vfp_double* vdm, + u32 fpscr) { vfp_double_dump("VDN", vdn); vfp_double_dump("VDM", vdm); @@ -908,12 +883,11 @@ vfp_double_multiply(struct vfp_double *vdd, struct vfp_double *vdn, return 0; } -#define NEG_MULTIPLY (1 << 0) -#define NEG_SUBTRACT (1 << 1) +#define NEG_MULTIPLY (1 << 0) +#define NEG_SUBTRACT (1 << 1) -static u32 -vfp_double_multiply_accumulate(ARMul_State* state, int dd, int dn, int dm, u32 fpscr, u32 negate, const char *func) -{ +static u32 vfp_double_multiply_accumulate(ARMul_State* state, int dd, int dn, int dm, u32 fpscr, + u32 negate, const char* func) { struct vfp_double vdd, vdp, vdn, vdm; u32 exceptions = 0; @@ -949,8 +923,7 @@ vfp_double_multiply_accumulate(ARMul_State* state, int dd, int dn, int dm, u32 f /* * sd = sd + (sn * sm) */ -static u32 vfp_double_fmac(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) -{ +static u32 vfp_double_fmac(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) { LOG_TRACE(Core_ARM11, "In %s", __FUNCTION__); return vfp_double_multiply_accumulate(state, dd, dn, dm, fpscr, 0, "fmac"); } @@ -958,8 +931,7 @@ static u32 vfp_double_fmac(ARMul_State* state, int dd, int dn, int dm, u32 fpscr /* * sd = sd - (sn * sm) */ -static u32 vfp_double_fnmac(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) -{ +static u32 vfp_double_fnmac(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) { LOG_TRACE(Core_ARM11, "In %s", __FUNCTION__); return vfp_double_multiply_accumulate(state, dd, dn, dm, fpscr, NEG_MULTIPLY, "fnmac"); } @@ -967,8 +939,7 @@ static u32 vfp_double_fnmac(ARMul_State* state, int dd, int dn, int dm, u32 fpsc /* * sd = -sd + (sn * sm) */ -static u32 vfp_double_fmsc(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) -{ +static u32 vfp_double_fmsc(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) { LOG_TRACE(Core_ARM11, "In %s", __FUNCTION__); return vfp_double_multiply_accumulate(state, dd, dn, dm, fpscr, NEG_SUBTRACT, "fmsc"); } @@ -976,17 +947,16 @@ static u32 vfp_double_fmsc(ARMul_State* state, int dd, int dn, int dm, u32 fpscr /* * sd = -sd - (sn * sm) */ -static u32 vfp_double_fnmsc(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) -{ +static u32 vfp_double_fnmsc(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) { LOG_TRACE(Core_ARM11, "In %s", __FUNCTION__); - return vfp_double_multiply_accumulate(state, dd, dn, dm, fpscr, NEG_SUBTRACT | NEG_MULTIPLY, "fnmsc"); + return vfp_double_multiply_accumulate(state, dd, dn, dm, fpscr, NEG_SUBTRACT | NEG_MULTIPLY, + "fnmsc"); } /* * sd = sn * sm */ -static u32 vfp_double_fmul(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) -{ +static u32 vfp_double_fmul(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) { struct vfp_double vdd, vdn, vdm; u32 exceptions = 0; @@ -1008,8 +978,7 @@ static u32 vfp_double_fmul(ARMul_State* state, int dd, int dn, int dm, u32 fpscr /* * sd = -(sn * sm) */ -static u32 vfp_double_fnmul(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) -{ +static u32 vfp_double_fnmul(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) { struct vfp_double vdd, vdn, vdm; u32 exceptions = 0; @@ -1032,8 +1001,7 @@ static u32 vfp_double_fnmul(ARMul_State* state, int dd, int dn, int dm, u32 fpsc /* * sd = sn + sm */ -static u32 vfp_double_fadd(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) -{ +static u32 vfp_double_fadd(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) { struct vfp_double vdd, vdn, vdm; u32 exceptions = 0; @@ -1055,8 +1023,7 @@ static u32 vfp_double_fadd(ARMul_State* state, int dd, int dn, int dm, u32 fpscr /* * sd = sn - sm */ -static u32 vfp_double_fsub(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) -{ +static u32 vfp_double_fsub(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) { struct vfp_double vdd, vdn, vdm; u32 exceptions = 0; @@ -1083,8 +1050,7 @@ static u32 vfp_double_fsub(ARMul_State* state, int dd, int dn, int dm, u32 fpscr /* * sd = sn / sm */ -static u32 vfp_double_fdiv(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) -{ +static u32 vfp_double_fdiv(ARMul_State* state, int dd, int dn, int dm, u32 fpscr) { struct vfp_double vdd, vdn, vdm; u32 exceptions = 0; int tm, tn; @@ -1114,7 +1080,7 @@ static u32 vfp_double_fdiv(ARMul_State* state, int dd, int dn, int dm, u32 fpscr * If n and m are infinity, the result is invalid * If n and m are zero, the result is invalid */ - if (tm & tn & (VFP_INFINITY|VFP_ZERO)) + if (tm & tn & (VFP_INFINITY | VFP_ZERO)) goto invalid; /* @@ -1193,29 +1159,22 @@ invalid: } static struct op fops[] = { - { vfp_double_fmac, 0 }, - { vfp_double_fmsc, 0 }, - { vfp_double_fmul, 0 }, - { vfp_double_fadd, 0 }, - { vfp_double_fnmac, 0 }, - { vfp_double_fnmsc, 0 }, - { vfp_double_fnmul, 0 }, - { vfp_double_fsub, 0 }, - { vfp_double_fdiv, 0 }, + {vfp_double_fmac, 0}, {vfp_double_fmsc, 0}, {vfp_double_fmul, 0}, + {vfp_double_fadd, 0}, {vfp_double_fnmac, 0}, {vfp_double_fnmsc, 0}, + {vfp_double_fnmul, 0}, {vfp_double_fsub, 0}, {vfp_double_fdiv, 0}, }; -#define FREG_BANK(x) ((x) & 0x0c) -#define FREG_IDX(x) ((x) & 3) +#define FREG_BANK(x) ((x)&0x0c) +#define FREG_IDX(x) ((x)&3) -u32 vfp_double_cpdo(ARMul_State* state, u32 inst, u32 fpscr) -{ +u32 vfp_double_cpdo(ARMul_State* state, u32 inst, u32 fpscr) { u32 op = inst & FOP_MASK; u32 exceptions = 0; unsigned int dest; unsigned int dn = vfp_get_dn(inst); unsigned int dm; unsigned int vecitr, veclen, vecstride; - struct op *fop; + struct op* fop; LOG_TRACE(Core_ARM11, "In %s", __FUNCTION__); vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK)); @@ -1249,7 +1208,7 @@ u32 vfp_double_cpdo(ARMul_State* state, u32 inst, u32 fpscr) veclen = fpscr & FPSCR_LENGTH_MASK; LOG_TRACE(Core_ARM11, "VFP: vecstride=%u veclen=%u", vecstride, - (veclen >> FPSCR_LENGTH_BIT) + 1); + (veclen >> FPSCR_LENGTH_BIT) + 1); if (!fop->fn) { printf("VFP: could not find double op %d\n", FEXT_TO_IDX(inst)); @@ -1262,17 +1221,14 @@ u32 vfp_double_cpdo(ARMul_State* state, u32 inst, u32 fpscr) type = (fop->flags & OP_SD) ? 's' : 'd'; if (op == FOP_EXT) - LOG_TRACE(Core_ARM11, "VFP: itr%d (%c%u) = op[%u] (d%u)", - vecitr >> FPSCR_LENGTH_BIT, - type, dest, dn, dm); + LOG_TRACE(Core_ARM11, "VFP: itr%d (%c%u) = op[%u] (d%u)", vecitr >> FPSCR_LENGTH_BIT, + type, dest, dn, dm); else LOG_TRACE(Core_ARM11, "VFP: itr%d (%c%u) = (d%u) op[%u] (d%u)", - vecitr >> FPSCR_LENGTH_BIT, - type, dest, dn, FOP_TO_IDX(op), dm); + vecitr >> FPSCR_LENGTH_BIT, type, dest, dn, FOP_TO_IDX(op), dm); except = fop->fn(state, dest, dn, dm, fpscr); - LOG_TRACE(Core_ARM11, "VFP: itr%d: exceptions=%08x", - vecitr >> FPSCR_LENGTH_BIT, except); + LOG_TRACE(Core_ARM11, "VFP: itr%d: exceptions=%08x", vecitr >> FPSCR_LENGTH_BIT, except); exceptions |= except; diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp index 1a98d0114..a66dc1016 100644 --- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp @@ -19,14 +19,13 @@ struct vmla_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vmla)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmla_inst)); - vmla_inst *inst_cream = (vmla_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vmla)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vmla_inst)); + vmla_inst* inst_cream = (vmla_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->dp_operation = BIT(inst, 8); inst_cream->instr = inst; @@ -35,12 +34,11 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmla)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VMLA_INST: -{ +VMLA_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vmla_inst *inst_cream = (vmla_inst *)inst_base->component; + vmla_inst* inst_cream = (vmla_inst*)inst_base->component; int ret; @@ -68,14 +66,13 @@ struct vmls_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vmls)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmls_inst)); - vmls_inst *inst_cream = (vmls_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vmls)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vmls_inst)); + vmls_inst* inst_cream = (vmls_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->dp_operation = BIT(inst, 8); inst_cream->instr = inst; @@ -84,12 +81,11 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmls)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VMLS_INST: -{ +VMLS_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vmls_inst *inst_cream = (vmls_inst *)inst_base->component; + vmls_inst* inst_cream = (vmls_inst*)inst_base->component; int ret; @@ -117,14 +113,13 @@ struct vnmla_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vnmla)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmla_inst)); - vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vnmla)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vnmla_inst)); + vnmla_inst* inst_cream = (vnmla_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->dp_operation = BIT(inst, 8); inst_cream->instr = inst; @@ -133,12 +128,11 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vnmla)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VNMLA_INST: -{ +VNMLA_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component; + vnmla_inst* inst_cream = (vnmla_inst*)inst_base->component; int ret; @@ -167,14 +161,13 @@ struct vnmls_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vnmls)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmls_inst)); - vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vnmls)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vnmls_inst)); + vnmls_inst* inst_cream = (vnmls_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->dp_operation = BIT(inst, 8); inst_cream->instr = inst; @@ -183,12 +176,11 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vnmls)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VNMLS_INST: -{ +VNMLS_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component; + vnmls_inst* inst_cream = (vnmls_inst*)inst_base->component; int ret; @@ -216,14 +208,13 @@ struct vnmul_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vnmul)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmul_inst)); - vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vnmul)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vnmul_inst)); + vnmul_inst* inst_cream = (vnmul_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->dp_operation = BIT(inst, 8); inst_cream->instr = inst; @@ -232,12 +223,11 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vnmul)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VNMUL_INST: -{ +VNMUL_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component; + vnmul_inst* inst_cream = (vnmul_inst*)inst_base->component; int ret; @@ -265,14 +255,13 @@ struct vmul_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vmul)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmul_inst)); - vmul_inst *inst_cream = (vmul_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vmul)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vmul_inst)); + vmul_inst* inst_cream = (vmul_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->dp_operation = BIT(inst, 8); inst_cream->instr = inst; @@ -281,12 +270,11 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmul)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VMUL_INST: -{ +VMUL_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vmul_inst *inst_cream = (vmul_inst *)inst_base->component; + vmul_inst* inst_cream = (vmul_inst*)inst_base->component; int ret; @@ -314,14 +302,13 @@ struct vadd_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vadd)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vadd_inst)); - vadd_inst *inst_cream = (vadd_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vadd)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vadd_inst)); + vadd_inst* inst_cream = (vadd_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->dp_operation = BIT(inst, 8); inst_cream->instr = inst; @@ -330,12 +317,11 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vadd)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VADD_INST: -{ +VADD_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vadd_inst *inst_cream = (vadd_inst *)inst_base->component; + vadd_inst* inst_cream = (vadd_inst*)inst_base->component; int ret; @@ -363,14 +349,13 @@ struct vsub_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vsub)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsub_inst)); - vsub_inst *inst_cream = (vsub_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vsub)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vsub_inst)); + vsub_inst* inst_cream = (vsub_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->dp_operation = BIT(inst, 8); inst_cream->instr = inst; @@ -379,12 +364,11 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vsub)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VSUB_INST: -{ +VSUB_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vsub_inst *inst_cream = (vsub_inst *)inst_base->component; + vsub_inst* inst_cream = (vsub_inst*)inst_base->component; int ret; @@ -412,14 +396,13 @@ struct vdiv_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vdiv)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vdiv_inst)); - vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vdiv)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vdiv_inst)); + vdiv_inst* inst_cream = (vdiv_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->dp_operation = BIT(inst, 8); inst_cream->instr = inst; @@ -428,12 +411,11 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vdiv)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VDIV_INST: -{ +VDIV_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component; + vdiv_inst* inst_cream = (vdiv_inst*)inst_base->component; int ret; @@ -463,32 +445,33 @@ struct vmovi_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovi)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovi_inst)); - vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovi)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vmovi_inst)); + vmovi_inst* inst_cream = (vmovi_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->single = BIT(inst, 8) == 0; - inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4); + inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15) << 1 | BIT(inst, 22) + : BITS(inst, 12, 15) | BIT(inst, 22) << 4); unsigned int imm8 = BITS(inst, 16, 19) << 4 | BITS(inst, 0, 3); if (inst_cream->single) - inst_cream->imm = BIT(imm8, 7)<<31 | (BIT(imm8, 6)==0)<<30 | (BIT(imm8, 6) ? 0x1f : 0)<<25 | BITS(imm8, 0, 5)<<19; + inst_cream->imm = BIT(imm8, 7) << 31 | (BIT(imm8, 6) == 0) << 30 | + (BIT(imm8, 6) ? 0x1f : 0) << 25 | BITS(imm8, 0, 5) << 19; else - inst_cream->imm = BIT(imm8, 7)<<31 | (BIT(imm8, 6)==0)<<30 | (BIT(imm8, 6) ? 0xff : 0)<<22 | BITS(imm8, 0, 5)<<16; + inst_cream->imm = BIT(imm8, 7) << 31 | (BIT(imm8, 6) == 0) << 30 | + (BIT(imm8, 6) ? 0xff : 0) << 22 | BITS(imm8, 0, 5) << 16; return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL -VMOVI_INST: -{ +VMOVI_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component; + vmovi_inst* inst_cream = (vmovi_inst*)inst_base->component; VMOVI(cpu, inst_cream->single, inst_cream->d, inst_cream->imm); } @@ -511,28 +494,28 @@ struct vmovr_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovr)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovr_inst)); - vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovr)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vmovr_inst)); + vmovr_inst* inst_cream = (vmovr_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->single = BIT(inst, 8) == 0; - inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4); - inst_cream->m = (inst_cream->single ? BITS(inst, 0, 3)<<1 | BIT(inst, 5) : BITS(inst, 0, 3) | BIT(inst, 5)<<4); + inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15) << 1 | BIT(inst, 22) + : BITS(inst, 12, 15) | BIT(inst, 22) << 4); + inst_cream->m = (inst_cream->single ? BITS(inst, 0, 3) << 1 | BIT(inst, 5) + : BITS(inst, 0, 3) | BIT(inst, 5) << 4); return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL -VMOVR_INST: -{ +VMOVR_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component; + vmovr_inst* inst_cream = (vmovr_inst*)inst_base->component; VMOVR(cpu, inst_cream->single, inst_cream->d, inst_cream->m); } @@ -553,14 +536,13 @@ typedef struct _vabs_inst { } vabs_inst; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vabs)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vabs_inst)); - vabs_inst *inst_cream = (vabs_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vabs)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vabs_inst)); + vabs_inst* inst_cream = (vabs_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->dp_operation = BIT(inst, 8); inst_cream->instr = inst; @@ -569,12 +551,11 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vabs)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VABS_INST: -{ +VABS_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vabs_inst *inst_cream = (vabs_inst *)inst_base->component; + vabs_inst* inst_cream = (vabs_inst*)inst_base->component; int ret; @@ -603,14 +584,13 @@ struct vneg_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vneg)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vneg_inst)); - vneg_inst *inst_cream = (vneg_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vneg)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vneg_inst)); + vneg_inst* inst_cream = (vneg_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->dp_operation = BIT(inst, 8); inst_cream->instr = inst; @@ -619,12 +599,11 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vneg)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VNEG_INST: -{ +VNEG_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vneg_inst *inst_cream = (vneg_inst *)inst_base->component; + vneg_inst* inst_cream = (vneg_inst*)inst_base->component; int ret; @@ -652,14 +631,13 @@ struct vsqrt_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vsqrt)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsqrt_inst)); - vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vsqrt)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vsqrt_inst)); + vsqrt_inst* inst_cream = (vsqrt_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->dp_operation = BIT(inst, 8); inst_cream->instr = inst; @@ -668,12 +646,11 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vsqrt)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VSQRT_INST: -{ +VSQRT_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component; + vsqrt_inst* inst_cream = (vsqrt_inst*)inst_base->component; int ret; @@ -701,14 +678,13 @@ struct vcmp_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp_inst)); - vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp_inst)); + vcmp_inst* inst_cream = (vcmp_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->dp_operation = BIT(inst, 8); inst_cream->instr = inst; @@ -717,12 +693,11 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VCMP_INST: -{ +VCMP_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component; + vcmp_inst* inst_cream = (vcmp_inst*)inst_base->component; int ret; @@ -750,14 +725,13 @@ struct vcmp2_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp2)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp2_inst)); - vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp2)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp2_inst)); + vcmp2_inst* inst_cream = (vcmp2_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->dp_operation = BIT(inst, 8); inst_cream->instr = inst; @@ -766,12 +740,11 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp2)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VCMP2_INST: -{ +VCMP2_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component; + vcmp2_inst* inst_cream = (vcmp2_inst*)inst_base->component; int ret; @@ -799,14 +772,13 @@ struct vcvtbds_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbds)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbds_inst)); - vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbds)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbds_inst)); + vcvtbds_inst* inst_cream = (vcvtbds_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->dp_operation = BIT(inst, 8); inst_cream->instr = inst; @@ -815,12 +787,11 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbds)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VCVTBDS_INST: -{ +VCVTBDS_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component; + vcvtbds_inst* inst_cream = (vcvtbds_inst*)inst_base->component; int ret; @@ -848,16 +819,15 @@ struct vcvtbff_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbff)(unsigned int inst, int index) -{ +static ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbff)(unsigned int inst, int index) { VFP_DEBUG_UNTESTED(VCVTBFF); - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbff_inst)); - vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component; + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbff_inst)); + vcvtbff_inst* inst_cream = (vcvtbff_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->dp_operation = BIT(inst, 8); inst_cream->instr = inst; @@ -866,12 +836,11 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbff)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VCVTBFF_INST: -{ +VCVTBFF_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component; + vcvtbff_inst* inst_cream = (vcvtbff_inst*)inst_base->component; int ret; @@ -899,14 +868,13 @@ struct vcvtbfi_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbfi)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbfi_inst)); - vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbfi)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbfi_inst)); + vcvtbfi_inst* inst_cream = (vcvtbfi_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->dp_operation = BIT(inst, 8); inst_cream->instr = inst; @@ -915,12 +883,11 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbfi)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VCVTBFI_INST: -{ +VCVTBFI_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component; + vcvtbfi_inst* inst_cream = (vcvtbfi_inst*)inst_base->component; int ret; @@ -955,29 +922,27 @@ struct vmovbrs_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrs)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrs_inst)); - vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrs)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrs_inst)); + vmovbrs_inst* inst_cream = (vmovbrs_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->to_arm = BIT(inst, 20) == 1; - inst_cream->t = BITS(inst, 12, 15); - inst_cream->n = BIT(inst, 7) | BITS(inst, 16, 19)<<1; + inst_cream->t = BITS(inst, 12, 15); + inst_cream->n = BIT(inst, 7) | BITS(inst, 16, 19) << 1; return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL -VMOVBRS_INST: -{ +VMOVBRS_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component; + vmovbrs_inst* inst_cream = (vmovbrs_inst*)inst_base->component; VMOVBRS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->n, &(cpu->Reg[inst_cream->t])); } @@ -999,24 +964,22 @@ struct vmsr_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vmsr)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmsr_inst)); - vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vmsr)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vmsr_inst)); + vmsr_inst* inst_cream = (vmsr_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->reg = BITS(inst, 16, 19); - inst_cream->Rt = BITS(inst, 12, 15); + inst_cream->Rt = BITS(inst, 12, 15); return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL -VMSR_INST: -{ +VMSR_INST : { if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled , and in privileged mode */ @@ -1026,14 +989,11 @@ VMSR_INST: vmsr_inst* const inst_cream = (vmsr_inst*)inst_base->component; unsigned int reg = inst_cream->reg; - unsigned int rt = inst_cream->Rt; + unsigned int rt = inst_cream->Rt; - if (reg == 1) - { + if (reg == 1) { cpu->VFP[VFP_FPSCR] = cpu->Reg[rt]; - } - else if (cpu->InAPrivilegedMode()) - { + } else if (cpu->InAPrivilegedMode()) { if (reg == 8) cpu->VFP[VFP_FPEXC] = cpu->Reg[rt]; else if (reg == 9) @@ -1062,17 +1022,16 @@ struct vmovbrc_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrc)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrc_inst)); - vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrc)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrc_inst)); + vmovbrc_inst* inst_cream = (vmovbrc_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4; - inst_cream->t = BITS(inst, 12, 15); + inst_cream->d = BITS(inst, 16, 19) | BIT(inst, 7) << 4; + inst_cream->t = BITS(inst, 12, 15); /* VFP variant of instruction */ inst_cream->esize = 32; inst_cream->index = BIT(inst, 21); @@ -1081,8 +1040,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrc)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VMOVBRC_INST: -{ +VMOVBRC_INST : { if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; @@ -1108,24 +1066,22 @@ struct vmrs_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vmrs)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmrs_inst)); - vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vmrs)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vmrs_inst)); + vmrs_inst* inst_cream = (vmrs_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->reg = BITS(inst, 16, 19); - inst_cream->Rt = BITS(inst, 12, 15); + inst_cream->Rt = BITS(inst, 12, 15); return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL -VMRS_INST: -{ +VMRS_INST : { if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled, and in privileged mode */ @@ -1135,36 +1091,25 @@ VMRS_INST: vmrs_inst* const inst_cream = (vmrs_inst*)inst_base->component; unsigned int reg = inst_cream->reg; - unsigned int rt = inst_cream->Rt; + unsigned int rt = inst_cream->Rt; if (reg == 1) // FPSCR { - if (rt != 15) - { + if (rt != 15) { cpu->Reg[rt] = cpu->VFP[VFP_FPSCR]; - } - else - { + } else { cpu->NFlag = (cpu->VFP[VFP_FPSCR] >> 31) & 1; cpu->ZFlag = (cpu->VFP[VFP_FPSCR] >> 30) & 1; cpu->CFlag = (cpu->VFP[VFP_FPSCR] >> 29) & 1; cpu->VFlag = (cpu->VFP[VFP_FPSCR] >> 28) & 1; } - } - else if (reg == 0) - { + } else if (reg == 0) { cpu->Reg[rt] = cpu->VFP[VFP_FPSID]; - } - else if (reg == 6) - { + } else if (reg == 6) { cpu->Reg[rt] = cpu->VFP[VFP_MVFR1]; - } - else if (reg == 7) - { + } else if (reg == 7) { cpu->Reg[rt] = cpu->VFP[VFP_MVFR0]; - } - else if (cpu->InAPrivilegedMode()) - { + } else if (cpu->InAPrivilegedMode()) { if (reg == 8) cpu->Reg[rt] = cpu->VFP[VFP_FPEXC]; else if (reg == 9) @@ -1193,17 +1138,16 @@ struct vmovbcr_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbcr)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbcr_inst)); - vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbcr)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbcr_inst)); + vmovbcr_inst* inst_cream = (vmovbcr_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4; - inst_cream->t = BITS(inst, 12, 15); + inst_cream->d = BITS(inst, 16, 19) | BIT(inst, 7) << 4; + inst_cream->t = BITS(inst, 12, 15); /* VFP variant of instruction */ inst_cream->esize = 32; inst_cream->index = BIT(inst, 21); @@ -1212,12 +1156,11 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbcr)(unsigned int inst, int index) } #endif #ifdef VFP_INTERPRETER_IMPL -VMOVBCR_INST: -{ +VMOVBCR_INST : { if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vmovbcr_inst* const inst_cream = (vmovbcr_inst*) inst_base->component; + vmovbcr_inst* const inst_cream = (vmovbcr_inst*)inst_base->component; cpu->Reg[inst_cream->t] = cpu->ExtReg[(2 * inst_cream->d) + inst_cream->index]; } @@ -1246,33 +1189,31 @@ struct vmovbrrss_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrss)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrss_inst)); - vmovbrrss_inst *inst_cream = (vmovbrrss_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrss)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrss_inst)); + vmovbrrss_inst* inst_cream = (vmovbrrss_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->to_arm = BIT(inst, 20) == 1; - inst_cream->t = BITS(inst, 12, 15); - inst_cream->t2 = BITS(inst, 16, 19); - inst_cream->m = BITS(inst, 0, 3)<<1|BIT(inst, 5); + inst_cream->t = BITS(inst, 12, 15); + inst_cream->t2 = BITS(inst, 16, 19); + inst_cream->m = BITS(inst, 0, 3) << 1 | BIT(inst, 5); return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL -VMOVBRRSS_INST: -{ +VMOVBRRSS_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; vmovbrrss_inst* const inst_cream = (vmovbrrss_inst*)inst_base->component; VMOVBRRSS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m, - &cpu->Reg[inst_cream->t], &cpu->Reg[inst_cream->t2]); + &cpu->Reg[inst_cream->t], &cpu->Reg[inst_cream->t2]); } cpu->Reg[15] += cpu->GetInstructionSize(); INC_PC(sizeof(vmovbrrss_inst)); @@ -1294,33 +1235,31 @@ struct vmovbrrd_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrd)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrd_inst)); - vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrd)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrd_inst)); + vmovbrrd_inst* inst_cream = (vmovbrrd_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->to_arm = BIT(inst, 20) == 1; - inst_cream->t = BITS(inst, 12, 15); - inst_cream->t2 = BITS(inst, 16, 19); - inst_cream->m = BIT(inst, 5)<<4 | BITS(inst, 0, 3); + inst_cream->t = BITS(inst, 12, 15); + inst_cream->t2 = BITS(inst, 16, 19); + inst_cream->m = BIT(inst, 5) << 4 | BITS(inst, 0, 3); return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL -VMOVBRRD_INST: -{ +VMOVBRRD_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component; + vmovbrrd_inst* inst_cream = (vmovbrrd_inst*)inst_base->component; VMOVBRRD(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m, - &(cpu->Reg[inst_cream->t]), &(cpu->Reg[inst_cream->t2])); + &(cpu->Reg[inst_cream->t]), &(cpu->Reg[inst_cream->t2])); } cpu->Reg[15] += cpu->GetInstructionSize(); INC_PC(sizeof(vmovbrrd_inst)); @@ -1347,43 +1286,40 @@ struct vstr_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vstr)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstr_inst)); - vstr_inst *inst_cream = (vstr_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vstr)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vstr_inst)); + vstr_inst* inst_cream = (vstr_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->single = BIT(inst, 8) == 0; - inst_cream->add = BIT(inst, 23); - inst_cream->imm32 = BITS(inst, 0,7) << 2; - inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); - inst_cream->n = BITS(inst, 16, 19); + inst_cream->add = BIT(inst, 23); + inst_cream->imm32 = BITS(inst, 0, 7) << 2; + inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15) << 1 | BIT(inst, 22) + : BITS(inst, 12, 15) | BIT(inst, 22) << 4); + inst_cream->n = BITS(inst, 16, 19); return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL -VSTR_INST: -{ +VSTR_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vstr_inst *inst_cream = (vstr_inst *)inst_base->component; + vstr_inst* inst_cream = (vstr_inst*)inst_base->component; - unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]); + unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 + : cpu->Reg[inst_cream->n]); addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32); - if (inst_cream->single) - { + if (inst_cream->single) { cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d]); - } - else - { - const u32 word1 = cpu->ExtReg[inst_cream->d*2+0]; - const u32 word2 = cpu->ExtReg[inst_cream->d*2+1]; + } else { + const u32 word1 = cpu->ExtReg[inst_cream->d * 2 + 0]; + const u32 word2 = cpu->ExtReg[inst_cream->d * 2 + 1]; if (cpu->InBigEndianMode()) { cpu->WriteMemory32(addr + 0, word2); @@ -1413,44 +1349,39 @@ struct vpush_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vpush)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpush_inst)); - vpush_inst *inst_cream = (vpush_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vpush)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vpush_inst)); + vpush_inst* inst_cream = (vpush_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->single = BIT(inst, 8) == 0; - inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); - inst_cream->imm32 = BITS(inst, 0, 7)<<2; - inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); + inst_cream->single = BIT(inst, 8) == 0; + inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15) << 1 | BIT(inst, 22) + : BITS(inst, 12, 15) | BIT(inst, 22) << 4); + inst_cream->imm32 = BITS(inst, 0, 7) << 2; + inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL -VPUSH_INST: -{ +VPUSH_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vpush_inst *inst_cream = (vpush_inst *)inst_base->component; + vpush_inst* inst_cream = (vpush_inst*)inst_base->component; addr = cpu->Reg[R13] - inst_cream->imm32; - for (unsigned int i = 0; i < inst_cream->regs; i++) - { - if (inst_cream->single) - { - cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d+i]); + for (unsigned int i = 0; i < inst_cream->regs; i++) { + if (inst_cream->single) { + cpu->WriteMemory32(addr, cpu->ExtReg[inst_cream->d + i]); addr += 4; - } - else - { - const u32 word1 = cpu->ExtReg[(inst_cream->d+i)*2+0]; - const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1]; + } else { + const u32 word1 = cpu->ExtReg[(inst_cream->d + i) * 2 + 0]; + const u32 word2 = cpu->ExtReg[(inst_cream->d + i) * 2 + 1]; if (cpu->InBigEndianMode()) { cpu->WriteMemory32(addr + 0, word2); @@ -1488,28 +1419,28 @@ struct vstm_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vstm)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstm_inst)); - vstm_inst *inst_cream = (vstm_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vstm)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vstm_inst)); + vstm_inst* inst_cream = (vstm_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->single = BIT(inst, 8) == 0; - inst_cream->add = BIT(inst, 23); - inst_cream->wback = BIT(inst, 21); - inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); - inst_cream->n = BITS(inst, 16, 19); - inst_cream->imm32 = BITS(inst, 0, 7)<<2; - inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); + inst_cream->add = BIT(inst, 23); + inst_cream->wback = BIT(inst, 21); + inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15) << 1 | BIT(inst, 22) + : BITS(inst, 12, 15) | BIT(inst, 22) << 4); + inst_cream->n = BITS(inst, 16, 19); + inst_cream->imm32 = BITS(inst, 0, 7) << 2; + inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL -VSTM_INST: /* encoding 1 */ +VSTM_INST : /* encoding 1 */ { if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; @@ -1525,17 +1456,13 @@ VSTM_INST: /* encoding 1 */ if (inst_cream->add == 0) address -= inst_cream->imm32; - for (unsigned int i = 0; i < inst_cream->regs; i++) - { - if (inst_cream->single) - { - cpu->WriteMemory32(address, cpu->ExtReg[inst_cream->d+i]); + for (unsigned int i = 0; i < inst_cream->regs; i++) { + if (inst_cream->single) { + cpu->WriteMemory32(address, cpu->ExtReg[inst_cream->d + i]); address += 4; - } - else - { - const u32 word1 = cpu->ExtReg[(inst_cream->d+i)*2+0]; - const u32 word2 = cpu->ExtReg[(inst_cream->d+i)*2+1]; + } else { + const u32 word1 = cpu->ExtReg[(inst_cream->d + i) * 2 + 0]; + const u32 word2 = cpu->ExtReg[(inst_cream->d + i) * 2 + 1]; if (cpu->InBigEndianMode()) { cpu->WriteMemory32(address + 0, word2); @@ -1549,8 +1476,9 @@ VSTM_INST: /* encoding 1 */ } } if (inst_cream->wback) { - cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : - cpu->Reg[inst_cream->n] - inst_cream->imm32); + cpu->Reg[inst_cream->n] = + (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 + : cpu->Reg[inst_cream->n] - inst_cream->imm32); } } cpu->Reg[15] += 4; @@ -1573,51 +1501,46 @@ struct vpop_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vpop)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpop_inst)); - vpop_inst *inst_cream = (vpop_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vpop)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vpop_inst)); + vpop_inst* inst_cream = (vpop_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; - inst_cream->single = BIT(inst, 8) == 0; - inst_cream->d = (inst_cream->single ? (BITS(inst, 12, 15)<<1)|BIT(inst, 22) : BITS(inst, 12, 15)|(BIT(inst, 22)<<4)); - inst_cream->imm32 = BITS(inst, 0, 7)<<2; - inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); + inst_cream->single = BIT(inst, 8) == 0; + inst_cream->d = (inst_cream->single ? (BITS(inst, 12, 15) << 1) | BIT(inst, 22) + : BITS(inst, 12, 15) | (BIT(inst, 22) << 4)); + inst_cream->imm32 = BITS(inst, 0, 7) << 2; + inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL -VPOP_INST: -{ +VPOP_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vpop_inst *inst_cream = (vpop_inst *)inst_base->component; + vpop_inst* inst_cream = (vpop_inst*)inst_base->component; addr = cpu->Reg[R13]; - for (unsigned int i = 0; i < inst_cream->regs; i++) - { - if (inst_cream->single) - { - cpu->ExtReg[inst_cream->d+i] = cpu->ReadMemory32(addr); + for (unsigned int i = 0; i < inst_cream->regs; i++) { + if (inst_cream->single) { + cpu->ExtReg[inst_cream->d + i] = cpu->ReadMemory32(addr); addr += 4; - } - else - { + } else { const u32 word1 = cpu->ReadMemory32(addr + 0); const u32 word2 = cpu->ReadMemory32(addr + 4); if (cpu->InBigEndianMode()) { - cpu->ExtReg[(inst_cream->d+i)*2+0] = word2; - cpu->ExtReg[(inst_cream->d+i)*2+1] = word1; + cpu->ExtReg[(inst_cream->d + i) * 2 + 0] = word2; + cpu->ExtReg[(inst_cream->d + i) * 2 + 1] = word1; } else { - cpu->ExtReg[(inst_cream->d+i)*2+0] = word1; - cpu->ExtReg[(inst_cream->d+i)*2+1] = word2; + cpu->ExtReg[(inst_cream->d + i) * 2 + 0] = word1; + cpu->ExtReg[(inst_cream->d + i) * 2 + 1] = word2; } addr += 8; @@ -1632,7 +1555,6 @@ VPOP_INST: } #endif - /* ----------------------------------------------------------------------- */ /* VLDR */ /* cond 1101 UD01 Rn-- Vd-- 101X imm8 imm8 */ @@ -1646,50 +1568,47 @@ struct vldr_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vldr)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldr_inst)); - vldr_inst *inst_cream = (vldr_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vldr)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vldr_inst)); + vldr_inst* inst_cream = (vldr_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->single = BIT(inst, 8) == 0; - inst_cream->add = BIT(inst, 23); - inst_cream->imm32 = BITS(inst, 0,7) << 2; - inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); - inst_cream->n = BITS(inst, 16, 19); + inst_cream->add = BIT(inst, 23); + inst_cream->imm32 = BITS(inst, 0, 7) << 2; + inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15) << 1 | BIT(inst, 22) + : BITS(inst, 12, 15) | BIT(inst, 22) << 4); + inst_cream->n = BITS(inst, 16, 19); return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL -VLDR_INST: -{ +VLDR_INST : { if ((inst_base->cond == ConditionCode::AL) || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; - vldr_inst *inst_cream = (vldr_inst *)inst_base->component; + vldr_inst* inst_cream = (vldr_inst*)inst_base->component; - unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]); + unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 + : cpu->Reg[inst_cream->n]); addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32); - if (inst_cream->single) - { + if (inst_cream->single) { cpu->ExtReg[inst_cream->d] = cpu->ReadMemory32(addr); - } - else - { + } else { const u32 word1 = cpu->ReadMemory32(addr + 0); const u32 word2 = cpu->ReadMemory32(addr + 4); if (cpu->InBigEndianMode()) { - cpu->ExtReg[inst_cream->d*2+0] = word2; - cpu->ExtReg[inst_cream->d*2+1] = word1; + cpu->ExtReg[inst_cream->d * 2 + 0] = word2; + cpu->ExtReg[inst_cream->d * 2 + 1] = word1; } else { - cpu->ExtReg[inst_cream->d*2+0] = word1; - cpu->ExtReg[inst_cream->d*2+1] = word2; + cpu->ExtReg[inst_cream->d * 2 + 0] = word1; + cpu->ExtReg[inst_cream->d * 2 + 1] = word2; } } } @@ -1715,29 +1634,28 @@ struct vldm_inst { }; #endif #ifdef VFP_INTERPRETER_TRANS -static ARM_INST_PTR INTERPRETER_TRANSLATE(vldm)(unsigned int inst, int index) -{ - arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldm_inst)); - vldm_inst *inst_cream = (vldm_inst *)inst_base->component; +static ARM_INST_PTR INTERPRETER_TRANSLATE(vldm)(unsigned int inst, int index) { + arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(vldm_inst)); + vldm_inst* inst_cream = (vldm_inst*)inst_base->component; inst_base->cond = BITS(inst, 28, 31); - inst_base->idx = index; - inst_base->br = TransExtData::NON_BRANCH; + inst_base->idx = index; + inst_base->br = TransExtData::NON_BRANCH; inst_cream->single = BIT(inst, 8) == 0; - inst_cream->add = BIT(inst, 23); - inst_cream->wback = BIT(inst, 21); - inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4); - inst_cream->n = BITS(inst, 16, 19); - inst_cream->imm32 = BITS(inst, 0, 7)<<2; - inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); + inst_cream->add = BIT(inst, 23); + inst_cream->wback = BIT(inst, 21); + inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15) << 1 | BIT(inst, 22) + : BITS(inst, 12, 15) | BIT(inst, 22) << 4); + inst_cream->n = BITS(inst, 16, 19); + inst_cream->imm32 = BITS(inst, 0, 7) << 2; + inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7)); return inst_base; } #endif #ifdef VFP_INTERPRETER_IMPL -VLDM_INST: -{ +VLDM_INST : { if (inst_base->cond == ConditionCode::AL || CondPassed(cpu, inst_base->cond)) { CHECK_VFP_ENABLED; @@ -1752,32 +1670,29 @@ VLDM_INST: if (inst_cream->add == 0) address -= inst_cream->imm32; - for (unsigned int i = 0; i < inst_cream->regs; i++) - { - if (inst_cream->single) - { - cpu->ExtReg[inst_cream->d+i] = cpu->ReadMemory32(address); + for (unsigned int i = 0; i < inst_cream->regs; i++) { + if (inst_cream->single) { + cpu->ExtReg[inst_cream->d + i] = cpu->ReadMemory32(address); address += 4; - } - else - { + } else { const u32 word1 = cpu->ReadMemory32(address + 0); const u32 word2 = cpu->ReadMemory32(address + 4); if (cpu->InBigEndianMode()) { - cpu->ExtReg[(inst_cream->d+i)*2+0] = word2; - cpu->ExtReg[(inst_cream->d+i)*2+1] = word1; + cpu->ExtReg[(inst_cream->d + i) * 2 + 0] = word2; + cpu->ExtReg[(inst_cream->d + i) * 2 + 1] = word1; } else { - cpu->ExtReg[(inst_cream->d+i)*2+0] = word1; - cpu->ExtReg[(inst_cream->d+i)*2+1] = word2; + cpu->ExtReg[(inst_cream->d + i) * 2 + 0] = word1; + cpu->ExtReg[(inst_cream->d + i) * 2 + 1] = word2; } address += 8; } } if (inst_cream->wback) { - cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 : - cpu->Reg[inst_cream->n] - inst_cream->imm32); + cpu->Reg[inst_cream->n] = + (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 + : cpu->Reg[inst_cream->n] - inst_cream->imm32); } } cpu->Reg[15] += cpu->GetInstructionSize(); diff --git a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp index 60264f9b3..1590d89a4 100644 --- a/src/core/arm/skyeye_common/vfp/vfpsingle.cpp +++ b/src/core/arm/skyeye_common/vfp/vfpsingle.cpp @@ -53,29 +53,23 @@ #include <algorithm> #include <cinttypes> - #include "common/common_funcs.h" #include "common/common_types.h" #include "common/logging/log.h" - -#include "core/arm/skyeye_common/vfp/vfp_helper.h" #include "core/arm/skyeye_common/vfp/asm_vfp.h" #include "core/arm/skyeye_common/vfp/vfp.h" +#include "core/arm/skyeye_common/vfp/vfp_helper.h" static struct vfp_single vfp_single_default_qnan = { - 255, - 0, - VFP_SINGLE_SIGNIFICAND_QNAN, + 255, 0, VFP_SINGLE_SIGNIFICAND_QNAN, }; -static void vfp_single_dump(const char *str, struct vfp_single *s) -{ - LOG_TRACE(Core_ARM11, "%s: sign=%d exponent=%d significand=%08x", - str, s->sign != 0, s->exponent, s->significand); +static void vfp_single_dump(const char* str, struct vfp_single* s) { + LOG_TRACE(Core_ARM11, "%s: sign=%d exponent=%d significand=%08x", str, s->sign != 0, + s->exponent, s->significand); } -static void vfp_single_normalise_denormal(struct vfp_single *vs) -{ +static void vfp_single_normalise_denormal(struct vfp_single* vs) { int bits = 31 - fls(vs->significand); vfp_single_dump("normalise_denormal: in", vs); @@ -88,9 +82,8 @@ static void vfp_single_normalise_denormal(struct vfp_single *vs) vfp_single_dump("normalise_denormal: out", vs); } - -u32 vfp_single_normaliseround(ARMul_State* state, int sd, struct vfp_single *vs, u32 fpscr, const char *func) -{ +u32 vfp_single_normaliseround(ARMul_State* state, int sd, struct vfp_single* vs, u32 fpscr, + const char* func) { u32 significand, incr, rmode; int exponent, shift, underflow; u32 exceptions = 0; @@ -199,7 +192,7 @@ u32 vfp_single_normaliseround(ARMul_State* state, int sd, struct vfp_single *vs, vs->exponent = 253; vs->significand = 0x7fffffff; } else { - vs->exponent = 255; /* infinity */ + vs->exponent = 255; /* infinity */ vs->significand = 0; } } else { @@ -217,8 +210,7 @@ pack: vfp_single_dump("pack: final", vs); { s32 d = vfp_single_pack(vs); - LOG_TRACE(Core_ARM11, "%s: d(s%d)=%08x exceptions=%08x", func, - sd, d, exceptions); + LOG_TRACE(Core_ARM11, "%s: d(s%d)=%08x exceptions=%08x", func, sd, d, exceptions); vfp_put_float(state, d, sd); } @@ -229,11 +221,9 @@ pack: * Propagate the NaN, setting exceptions if it is signalling. * 'n' is always a NaN. 'm' may be a number, NaN or infinity. */ -static u32 -vfp_propagate_nan(struct vfp_single *vsd, struct vfp_single *vsn, - struct vfp_single *vsm, u32 fpscr) -{ - struct vfp_single *nan; +static u32 vfp_propagate_nan(struct vfp_single* vsd, struct vfp_single* vsn, struct vfp_single* vsm, + u32 fpscr) { + struct vfp_single* nan; int tn, tm = 0; tn = vfp_single_type(vsn); @@ -270,40 +260,35 @@ vfp_propagate_nan(struct vfp_single *vsd, struct vfp_single *vsn, return tn == VFP_SNAN || tm == VFP_SNAN ? FPSCR_IOC : VFP_NAN_FLAG; } - /* * Extended operations */ -static u32 vfp_single_fabs(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) -{ +static u32 vfp_single_fabs(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) { vfp_put_float(state, vfp_single_packed_abs(m), sd); return 0; } -static u32 vfp_single_fcpy(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) -{ +static u32 vfp_single_fcpy(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) { vfp_put_float(state, m, sd); return 0; } -static u32 vfp_single_fneg(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) -{ +static u32 vfp_single_fneg(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) { vfp_put_float(state, vfp_single_packed_negate(m), sd); return 0; } static const u16 sqrt_oddadjust[] = { 0x0004, 0x0022, 0x005d, 0x00b1, 0x011d, 0x019f, 0x0236, 0x02e0, - 0x039c, 0x0468, 0x0545, 0x0631, 0x072b, 0x0832, 0x0946, 0x0a67 + 0x039c, 0x0468, 0x0545, 0x0631, 0x072b, 0x0832, 0x0946, 0x0a67, }; static const u16 sqrt_evenadjust[] = { 0x0a2d, 0x08af, 0x075a, 0x0629, 0x051a, 0x0429, 0x0356, 0x029e, - 0x0200, 0x0179, 0x0109, 0x00af, 0x0068, 0x0034, 0x0012, 0x0002 + 0x0200, 0x0179, 0x0109, 0x00af, 0x0068, 0x0034, 0x0012, 0x0002, }; -u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand) -{ +u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand) { int index; u32 z, a; @@ -331,25 +316,24 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand) } } -static u32 vfp_single_fsqrt(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) -{ +static u32 vfp_single_fsqrt(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) { struct vfp_single vsm, vsd, *vsp; int ret, tm; u32 exceptions = 0; exceptions |= vfp_single_unpack(&vsm, m, fpscr); tm = vfp_single_type(&vsm); - if (tm & (VFP_NAN|VFP_INFINITY)) { + if (tm & (VFP_NAN | VFP_INFINITY)) { vsp = &vsd; if (tm & VFP_NAN) ret = vfp_propagate_nan(vsp, &vsm, nullptr, fpscr); else if (vsm.sign == 0) { -sqrt_copy: + sqrt_copy: vsp = &vsm; ret = 0; } else { -sqrt_invalid: + sqrt_invalid: vsp = &vfp_single_default_qnan; ret = FPSCR_IOC; } @@ -420,15 +404,15 @@ sqrt_invalid: * Greater than := C * Unordered := CV */ -static u32 vfp_compare(ARMul_State* state, int sd, int signal_on_qnan, s32 m, u32 fpscr) -{ +static u32 vfp_compare(ARMul_State* state, int sd, int signal_on_qnan, s32 m, u32 fpscr) { s32 d; u32 ret = 0; d = vfp_get_float(state, sd); if (vfp_single_packed_exponent(m) == 255 && vfp_single_packed_mantissa(m)) { ret |= FPSCR_CFLAG | FPSCR_VFLAG; - if (signal_on_qnan || !(vfp_single_packed_mantissa(m) & (1 << (VFP_SINGLE_MANTISSA_BITS - 1)))) + if (signal_on_qnan || + !(vfp_single_packed_mantissa(m) & (1 << (VFP_SINGLE_MANTISSA_BITS - 1)))) /* * Signalling NaN, or signalling on quiet NaN */ @@ -437,7 +421,8 @@ static u32 vfp_compare(ARMul_State* state, int sd, int signal_on_qnan, s32 m, u3 if (vfp_single_packed_exponent(d) == 255 && vfp_single_packed_mantissa(d)) { ret |= FPSCR_CFLAG | FPSCR_VFLAG; - if (signal_on_qnan || !(vfp_single_packed_mantissa(d) & (1 << (VFP_SINGLE_MANTISSA_BITS - 1)))) + if (signal_on_qnan || + !(vfp_single_packed_mantissa(d) & (1 << (VFP_SINGLE_MANTISSA_BITS - 1)))) /* * Signalling NaN, or signalling on quiet NaN */ @@ -479,28 +464,23 @@ static u32 vfp_compare(ARMul_State* state, int sd, int signal_on_qnan, s32 m, u3 return ret; } -static u32 vfp_single_fcmp(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) -{ +static u32 vfp_single_fcmp(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) { return vfp_compare(state, sd, 0, m, fpscr); } -static u32 vfp_single_fcmpe(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) -{ +static u32 vfp_single_fcmpe(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) { return vfp_compare(state, sd, 1, m, fpscr); } -static u32 vfp_single_fcmpz(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) -{ +static u32 vfp_single_fcmpz(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) { return vfp_compare(state, sd, 0, 0, fpscr); } -static u32 vfp_single_fcmpez(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) -{ +static u32 vfp_single_fcmpez(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) { return vfp_compare(state, sd, 1, 0, fpscr); } -static u32 vfp_single_fcvtd(ARMul_State* state, int dd, int unused, s32 m, u32 fpscr) -{ +static u32 vfp_single_fcvtd(ARMul_State* state, int dd, int unused, s32 m, u32 fpscr) { struct vfp_single vsm; struct vfp_double vdd; int tm; @@ -525,7 +505,7 @@ static u32 vfp_single_fcvtd(ARMul_State* state, int dd, int unused, s32 m, u32 f /* * If we have an infinity or NaN, the exponent must be 2047. */ - if (tm & (VFP_INFINITY|VFP_NAN)) { + if (tm & (VFP_INFINITY | VFP_NAN)) { vdd.exponent = 2047; if (tm == VFP_QNAN) vdd.significand |= VFP_DOUBLE_SIGNIFICAND_QNAN; @@ -543,8 +523,7 @@ pack_nan: return exceptions; } -static u32 vfp_single_fuito(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) -{ +static u32 vfp_single_fuito(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) { struct vfp_single vs; u32 exceptions = 0; @@ -556,8 +535,7 @@ static u32 vfp_single_fuito(ARMul_State* state, int sd, int unused, s32 m, u32 f return exceptions; } -static u32 vfp_single_fsito(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) -{ +static u32 vfp_single_fsito(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) { struct vfp_single vs; u32 exceptions = 0; @@ -569,8 +547,7 @@ static u32 vfp_single_fsito(ARMul_State* state, int sd, int unused, s32 m, u32 f return exceptions; } -static u32 vfp_single_ftoui(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) -{ +static u32 vfp_single_ftoui(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) { struct vfp_single vsm; u32 d, exceptions = 0; int rmode = fpscr & FPSCR_RMODE_MASK; @@ -656,13 +633,11 @@ static u32 vfp_single_ftoui(ARMul_State* state, int sd, int unused, s32 m, u32 f return exceptions; } -static u32 vfp_single_ftouiz(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) -{ +static u32 vfp_single_ftouiz(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) { return vfp_single_ftoui(state, sd, unused, m, (fpscr & ~FPSCR_RMODE_MASK) | FPSCR_ROUND_TOZERO); } -static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) -{ +static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) { struct vfp_single vsm; u32 d, exceptions = 0; int rmode = fpscr & FPSCR_RMODE_MASK; @@ -739,51 +714,44 @@ static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 f return exceptions; } -static u32 vfp_single_ftosiz(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) -{ +static u32 vfp_single_ftosiz(ARMul_State* state, int sd, int unused, s32 m, u32 fpscr) { return vfp_single_ftosi(state, sd, unused, m, (fpscr & ~FPSCR_RMODE_MASK) | FPSCR_ROUND_TOZERO); } static struct op fops_ext[] = { - { vfp_single_fcpy, 0 }, //0x00000000 - FEXT_FCPY - { vfp_single_fabs, 0 }, //0x00000001 - FEXT_FABS - { vfp_single_fneg, 0 }, //0x00000002 - FEXT_FNEG - { vfp_single_fsqrt, 0 }, //0x00000003 - FEXT_FSQRT - { nullptr, 0 }, - { nullptr, 0 }, - { nullptr, 0 }, - { nullptr, 0 }, - { vfp_single_fcmp, OP_SCALAR }, //0x00000008 - FEXT_FCMP - { vfp_single_fcmpe, OP_SCALAR }, //0x00000009 - FEXT_FCMPE - { vfp_single_fcmpz, OP_SCALAR }, //0x0000000A - FEXT_FCMPZ - { vfp_single_fcmpez, OP_SCALAR }, //0x0000000B - FEXT_FCMPEZ - { nullptr, 0 }, - { nullptr, 0 }, - { nullptr, 0 }, - { vfp_single_fcvtd, OP_SCALAR|OP_DD }, //0x0000000F - FEXT_FCVT - { vfp_single_fuito, OP_SCALAR }, //0x00000010 - FEXT_FUITO - { vfp_single_fsito, OP_SCALAR }, //0x00000011 - FEXT_FSITO - { nullptr, 0 }, - { nullptr, 0 }, - { nullptr, 0 }, - { nullptr, 0 }, - { nullptr, 0 }, - { nullptr, 0 }, - { vfp_single_ftoui, OP_SCALAR }, //0x00000018 - FEXT_FTOUI - { vfp_single_ftouiz, OP_SCALAR }, //0x00000019 - FEXT_FTOUIZ - { vfp_single_ftosi, OP_SCALAR }, //0x0000001A - FEXT_FTOSI - { vfp_single_ftosiz, OP_SCALAR }, //0x0000001B - FEXT_FTOSIZ + {vfp_single_fcpy, 0}, // 0x00000000 - FEXT_FCPY + {vfp_single_fabs, 0}, // 0x00000001 - FEXT_FABS + {vfp_single_fneg, 0}, // 0x00000002 - FEXT_FNEG + {vfp_single_fsqrt, 0}, // 0x00000003 - FEXT_FSQRT + {nullptr, 0}, + {nullptr, 0}, + {nullptr, 0}, + {nullptr, 0}, + {vfp_single_fcmp, OP_SCALAR}, // 0x00000008 - FEXT_FCMP + {vfp_single_fcmpe, OP_SCALAR}, // 0x00000009 - FEXT_FCMPE + {vfp_single_fcmpz, OP_SCALAR}, // 0x0000000A - FEXT_FCMPZ + {vfp_single_fcmpez, OP_SCALAR}, // 0x0000000B - FEXT_FCMPEZ + {nullptr, 0}, + {nullptr, 0}, + {nullptr, 0}, + {vfp_single_fcvtd, OP_SCALAR | OP_DD}, // 0x0000000F - FEXT_FCVT + {vfp_single_fuito, OP_SCALAR}, // 0x00000010 - FEXT_FUITO + {vfp_single_fsito, OP_SCALAR}, // 0x00000011 - FEXT_FSITO + {nullptr, 0}, + {nullptr, 0}, + {nullptr, 0}, + {nullptr, 0}, + {nullptr, 0}, + {nullptr, 0}, + {vfp_single_ftoui, OP_SCALAR}, // 0x00000018 - FEXT_FTOUI + {vfp_single_ftouiz, OP_SCALAR}, // 0x00000019 - FEXT_FTOUIZ + {vfp_single_ftosi, OP_SCALAR}, // 0x0000001A - FEXT_FTOSI + {vfp_single_ftosiz, OP_SCALAR}, // 0x0000001B - FEXT_FTOSIZ }; - - - - -static u32 -vfp_single_fadd_nonnumber(struct vfp_single *vsd, struct vfp_single *vsn, - struct vfp_single *vsm, u32 fpscr) -{ - struct vfp_single *vsp; +static u32 vfp_single_fadd_nonnumber(struct vfp_single* vsd, struct vfp_single* vsn, + struct vfp_single* vsm, u32 fpscr) { + struct vfp_single* vsp; u32 exceptions = 0; int tn, tm; @@ -821,14 +789,11 @@ vfp_single_fadd_nonnumber(struct vfp_single *vsd, struct vfp_single *vsn, return exceptions; } -static u32 -vfp_single_add(struct vfp_single *vsd, struct vfp_single *vsn, - struct vfp_single *vsm, u32 fpscr) -{ +static u32 vfp_single_add(struct vfp_single* vsd, struct vfp_single* vsn, struct vfp_single* vsm, + u32 fpscr) { u32 exp_diff, m_sig; - if (vsn->significand & 0x80000000 || - vsm->significand & 0x80000000) { + if (vsn->significand & 0x80000000 || vsm->significand & 0x80000000) { LOG_WARNING(Core_ARM11, "bad FP values"); vfp_single_dump("VSN", vsn); vfp_single_dump("VSM", vsm); @@ -872,8 +837,7 @@ vfp_single_add(struct vfp_single *vsd, struct vfp_single *vsn, vsd->sign = vfp_sign_negate(vsd->sign); m_sig = (~m_sig + 1); } else if (m_sig == 0) { - vsd->sign = (fpscr & FPSCR_RMODE_MASK) == - FPSCR_ROUND_MINUSINF ? 0x8000 : 0; + vsd->sign = (fpscr & FPSCR_RMODE_MASK) == FPSCR_ROUND_MINUSINF ? 0x8000 : 0; } } else { m_sig = vsn->significand + m_sig; @@ -883,9 +847,8 @@ vfp_single_add(struct vfp_single *vsd, struct vfp_single *vsn, return 0; } -static u32 -vfp_single_multiply(struct vfp_single *vsd, struct vfp_single *vsn, struct vfp_single *vsm, u32 fpscr) -{ +static u32 vfp_single_multiply(struct vfp_single* vsd, struct vfp_single* vsn, + struct vfp_single* vsm, u32 fpscr) { vfp_single_dump("VSN", vsn); vfp_single_dump("VSM", vsm); @@ -938,12 +901,11 @@ vfp_single_multiply(struct vfp_single *vsd, struct vfp_single *vsn, struct vfp_s return 0; } -#define NEG_MULTIPLY (1 << 0) -#define NEG_SUBTRACT (1 << 1) +#define NEG_MULTIPLY (1 << 0) +#define NEG_SUBTRACT (1 << 1) -static u32 -vfp_single_multiply_accumulate(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr, u32 negate, const char *func) -{ +static u32 vfp_single_multiply_accumulate(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr, + u32 negate, const char* func) { vfp_single vsd, vsp, vsn, vsm; u32 exceptions = 0; s32 v; @@ -985,8 +947,7 @@ vfp_single_multiply_accumulate(ARMul_State* state, int sd, int sn, s32 m, u32 fp /* * sd = sd + (sn * sm) */ -static u32 vfp_single_fmac(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) -{ +static u32 vfp_single_fmac(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) { u32 exceptions = 0; LOG_TRACE(Core_ARM11, "s%u = %08x", sn, sd); exceptions |= vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, 0, "fmac"); @@ -996,8 +957,7 @@ static u32 vfp_single_fmac(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) /* * sd = sd - (sn * sm) */ -static u32 vfp_single_fnmac(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) -{ +static u32 vfp_single_fnmac(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) { // TODO: this one has its arguments inverted, investigate. LOG_TRACE(Core_ARM11, "s%u = %08x", sd, sn); return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, NEG_MULTIPLY, "fnmac"); @@ -1006,8 +966,7 @@ static u32 vfp_single_fnmac(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr /* * sd = -sd + (sn * sm) */ -static u32 vfp_single_fmsc(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) -{ +static u32 vfp_single_fmsc(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) { LOG_TRACE(Core_ARM11, "s%u = %08x", sn, sd); return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, NEG_SUBTRACT, "fmsc"); } @@ -1015,17 +974,16 @@ static u32 vfp_single_fmsc(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) /* * sd = -sd - (sn * sm) */ -static u32 vfp_single_fnmsc(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) -{ +static u32 vfp_single_fnmsc(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) { LOG_TRACE(Core_ARM11, "s%u = %08x", sn, sd); - return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, NEG_SUBTRACT | NEG_MULTIPLY, "fnmsc"); + return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, NEG_SUBTRACT | NEG_MULTIPLY, + "fnmsc"); } /* * sd = sn * sm */ -static u32 vfp_single_fmul(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) -{ +static u32 vfp_single_fmul(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) { struct vfp_single vsd, vsn, vsm; u32 exceptions = 0; s32 n = vfp_get_float(state, sn); @@ -1049,8 +1007,7 @@ static u32 vfp_single_fmul(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) /* * sd = -(sn * sm) */ -static u32 vfp_single_fnmul(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) -{ +static u32 vfp_single_fnmul(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) { struct vfp_single vsd, vsn, vsm; u32 exceptions = 0; s32 n = vfp_get_float(state, sn); @@ -1075,8 +1032,7 @@ static u32 vfp_single_fnmul(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr /* * sd = sn + sm */ -static u32 vfp_single_fadd(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) -{ +static u32 vfp_single_fadd(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) { struct vfp_single vsd, vsn, vsm; u32 exceptions = 0; s32 n = vfp_get_float(state, sn); @@ -1103,8 +1059,7 @@ static u32 vfp_single_fadd(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) /* * sd = sn - sm */ -static u32 vfp_single_fsub(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) -{ +static u32 vfp_single_fsub(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) { LOG_TRACE(Core_ARM11, "s%u = %08x", sn, sd); /* * Subtraction is addition with one sign inverted. @@ -1118,8 +1073,7 @@ static u32 vfp_single_fsub(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) /* * sd = sn / sm */ -static u32 vfp_single_fdiv(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) -{ +static u32 vfp_single_fdiv(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) { struct vfp_single vsd, vsn, vsm; u32 exceptions = 0; s32 n = vfp_get_float(state, sn); @@ -1151,7 +1105,7 @@ static u32 vfp_single_fdiv(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) * If n and m are infinity, the result is invalid * If n and m are zero, the result is invalid */ - if (tm & tn & (VFP_INFINITY|VFP_ZERO)) + if (tm & tn & (VFP_INFINITY | VFP_ZERO)) goto invalid; /* @@ -1226,29 +1180,22 @@ invalid: } static struct op fops[] = { - { vfp_single_fmac, 0 }, - { vfp_single_fmsc, 0 }, - { vfp_single_fmul, 0 }, - { vfp_single_fadd, 0 }, - { vfp_single_fnmac, 0 }, - { vfp_single_fnmsc, 0 }, - { vfp_single_fnmul, 0 }, - { vfp_single_fsub, 0 }, - { vfp_single_fdiv, 0 }, + {vfp_single_fmac, 0}, {vfp_single_fmsc, 0}, {vfp_single_fmul, 0}, + {vfp_single_fadd, 0}, {vfp_single_fnmac, 0}, {vfp_single_fnmsc, 0}, + {vfp_single_fnmul, 0}, {vfp_single_fsub, 0}, {vfp_single_fdiv, 0}, }; -#define FREG_BANK(x) ((x) & 0x18) -#define FREG_IDX(x) ((x) & 7) +#define FREG_BANK(x) ((x)&0x18) +#define FREG_IDX(x) ((x)&7) -u32 vfp_single_cpdo(ARMul_State* state, u32 inst, u32 fpscr) -{ +u32 vfp_single_cpdo(ARMul_State* state, u32 inst, u32 fpscr) { u32 op = inst & FOP_MASK; u32 exceptions = 0; unsigned int dest; unsigned int sn = vfp_get_sn(inst); unsigned int sm = vfp_get_sm(inst); unsigned int vecitr, veclen, vecstride; - struct op *fop; + struct op* fop; vecstride = 1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK); @@ -1274,11 +1221,11 @@ u32 vfp_single_cpdo(ARMul_State* state, u32 inst, u32 fpscr) else veclen = fpscr & FPSCR_LENGTH_MASK; - LOG_TRACE(Core_ARM11, "vecstride=%u veclen=%u", vecstride, - (veclen >> FPSCR_LENGTH_BIT) + 1); + LOG_TRACE(Core_ARM11, "vecstride=%u veclen=%u", vecstride, (veclen >> FPSCR_LENGTH_BIT) + 1); if (!fop->fn) { - LOG_CRITICAL(Core_ARM11, "could not find single op %d, inst=0x%x@0x%x", FEXT_TO_IDX(inst), inst, state->Reg[15]); + LOG_CRITICAL(Core_ARM11, "could not find single op %d, inst=0x%x@0x%x", FEXT_TO_IDX(inst), + inst, state->Reg[15]); Crash(); goto invalid; } @@ -1290,17 +1237,14 @@ u32 vfp_single_cpdo(ARMul_State* state, u32 inst, u32 fpscr) type = (fop->flags & OP_DD) ? 'd' : 's'; if (op == FOP_EXT) - LOG_TRACE(Core_ARM11, "itr%d (%c%u) = op[%u] (s%u=%08x)", - vecitr >> FPSCR_LENGTH_BIT, type, dest, sn, - sm, m); + LOG_TRACE(Core_ARM11, "itr%d (%c%u) = op[%u] (s%u=%08x)", vecitr >> FPSCR_LENGTH_BIT, + type, dest, sn, sm, m); else LOG_TRACE(Core_ARM11, "itr%d (%c%u) = (s%u) op[%u] (s%u=%08x)", - vecitr >> FPSCR_LENGTH_BIT, type, dest, sn, - FOP_TO_IDX(op), sm, m); + vecitr >> FPSCR_LENGTH_BIT, type, dest, sn, FOP_TO_IDX(op), sm, m); except = fop->fn(state, dest, sn, m, fpscr); - LOG_TRACE(Core_ARM11, "itr%d: exceptions=%08x", - vecitr >> FPSCR_LENGTH_BIT, except); + LOG_TRACE(Core_ARM11, "itr%d: exceptions=%08x", vecitr >> FPSCR_LENGTH_BIT, except); exceptions |= except; diff --git a/src/core/core.cpp b/src/core/core.cpp index a3834adae..49ac8be6e 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -3,9 +3,7 @@ // Refer to the license.txt file included. #include <memory> - #include "common/logging/log.h" - #include "core/arm/arm_interface.h" #include "core/arm/dynarmic/arm_dynarmic.h" #include "core/arm/dyncom/arm_dyncom.h" @@ -27,8 +25,8 @@ void RunLoop(int tight_loop) { if (GDBStub::g_server_enabled) { GDBStub::HandlePacket(); - // If the loop is halted and we want to step, use a tiny (1) number of instructions to execute. - // Otherwise get out of the loop function. + // If the loop is halted and we want to step, use a tiny (1) number of instructions to + // execute. Otherwise, get out of the loop function. if (GDBStub::GetCpuHaltFlag()) { if (GDBStub::GetCpuStepFlag()) { GDBStub::SetCpuStepFlag(false); @@ -62,7 +60,7 @@ void SingleStep() { } /// Halt the core -void Halt(const char *msg) { +void Halt(const char* msg) { // TODO(ShizZy): ImplementMe } diff --git a/src/core/core.h b/src/core/core.h index ad26dca3f..ffbfa91c3 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -40,13 +40,13 @@ void Start(); * is not guaranteed to run, as this will be interrupted preemptively if a hardware update is * requested (e.g. on a thread switch). */ -void RunLoop(int tight_loop=1000); +void RunLoop(int tight_loop = 1000); /// Step the CPU one instruction void SingleStep(); /// Halt the core -void Halt(const char *msg); +void Halt(const char* msg); /// Kill the core void Stop(); diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index aba22cdd1..5220b55ea 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -6,11 +6,9 @@ #include <cinttypes> #include <mutex> #include <vector> - #include "common/chunk_file.h" #include "common/logging/log.h" #include "common/string_util.h" - #include "core/arm/arm_interface.h" #include "core/core.h" #include "core/core_timing.h" @@ -21,14 +19,11 @@ int g_clock_rate_arm11 = 268123480; #define INITIAL_SLICE_LENGTH 20000 #define MAX_SLICE_LENGTH 100000000 -namespace CoreTiming -{ -struct EventType -{ +namespace CoreTiming { +struct EventType { EventType() {} - EventType(TimedCallback cb, const char* n) - : callback(cb), name(n) {} + EventType(TimedCallback cb, const char* n) : callback(cb), name(n) {} TimedCallback callback; const char* name; @@ -36,8 +31,7 @@ struct EventType static std::vector<EventType> event_types; -struct BaseEvent -{ +struct BaseEvent { s64 time; u64 userdata; int type; @@ -200,7 +194,6 @@ u64 GetIdleTicks() { return (u64)idled_cycles; } - // This is to be called when outside threads, such as the graphics thread, wants to // schedule things to be executed on the main thread. void ScheduleEvent_Threadsafe(s64 cycles_into_future, int event_type, u64 userdata) { @@ -222,12 +215,11 @@ void ScheduleEvent_Threadsafe(s64 cycles_into_future, int event_type, u64 userda // Same as ScheduleEvent_Threadsafe(0, ...) EXCEPT if we are already on the CPU thread // in which case the event will get handled immediately, before returning. void ScheduleEvent_Threadsafe_Immediate(int event_type, u64 userdata) { - if (false) //Core::IsCPUThread()) + if (false) // Core::IsCPUThread()) { std::lock_guard<std::recursive_mutex> lock(external_event_section); event_types[event_type].callback(userdata, 0); - } - else + } else ScheduleEvent_Threadsafe(0, event_type, userdata); } @@ -317,8 +309,7 @@ s64 UnscheduleThreadsafeEvent(int event_type, u64 userdata) { } } - if (!ts_first) - { + if (!ts_first) { ts_last = nullptr; return result; } @@ -369,7 +360,7 @@ void RemoveEvent(int event_type) { return; while (first) { if (first->type == event_type) { - Event *next = first->next; + Event* next = first->next; FreeEvent(first); first = next; } else { @@ -509,7 +500,8 @@ void Advance() { void LogPendingEvents() { Event* event = first; while (event) { - //LOG_TRACE(Core_Timing, "PENDING: Now: %lld Pending: %lld Type: %d", globalTimer, next->time, next->type); + // LOG_TRACE(Core_Timing, "PENDING: Now: %lld Pending: %lld Type: %d", globalTimer, + // next->time, next->type); event = event->next; } } @@ -531,7 +523,8 @@ void Idle(int max_idle) { } } - LOG_TRACE(Core_Timing, "Idle for %" PRId64 " cycles! (%f ms)", cycles_down, cycles_down / (float)(g_clock_rate_arm11 * 0.001f)); + LOG_TRACE(Core_Timing, "Idle for %" PRId64 " cycles! (%f ms)", cycles_down, + cycles_down / (float)(g_clock_rate_arm11 * 0.001f)); idled_cycles += cycles_down; Core::g_app_core->down_count -= cycles_down; @@ -551,7 +544,7 @@ std::string GetScheduledEventsSummary() { if (!name) name = "[unknown]"; text += Common::StringFromFormat("%s : %i %08x%08x\n", name, (int)event->time, - (u32)(event->userdata >> 32), (u32)(event->userdata)); + (u32)(event->userdata >> 32), (u32)(event->userdata)); event = event->next; } return text; diff --git a/src/core/core_timing.h b/src/core/core_timing.h index 3d8a7d0c0..b72a1b500 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h @@ -4,7 +4,9 @@ #pragma once +#include <functional> #include <string> +#include "common/common_types.h" // This is a system to schedule events into the emulated machine's future. Time is measured // in main CPU clock cycles. @@ -19,10 +21,6 @@ // inside callback: // ScheduleEvent(periodInCycles - cycles_late, callback, "whatever") -#include <functional> - -#include "common/common_types.h" - extern int g_clock_rate_arm11; inline s64 msToCycles(int ms) { @@ -61,12 +59,11 @@ inline u64 cyclesToMs(s64 cycles) { return cycles / (g_clock_rate_arm11 / 1000); } -namespace CoreTiming -{ +namespace CoreTiming { void Init(); void Shutdown(); -typedef void(*MHzChangeCallback)(); +typedef void (*MHzChangeCallback)(); typedef std::function<void(u64 userdata, int cycles_late)> TimedCallback; u64 GetTicks(); @@ -81,7 +78,7 @@ u64 GetGlobalTimeUs(); */ int RegisterEvent(const char* name, TimedCallback callback); /// For save states. -void RestoreRegisterEvent(int event_type, const char *name, TimedCallback callback); +void RestoreRegisterEvent(int event_type, const char* name, TimedCallback callback); void UnregisterAllEvents(); /// userdata MAY NOT CONTAIN POINTERS. userdata might get written and reloaded from disk, @@ -128,7 +125,7 @@ void ClearPendingEvents(); void LogPendingEvents(); /// Warning: not included in save states. -void RegisterAdvanceCallback(void(*callback)(int cycles_executed)); +void RegisterAdvanceCallback(void (*callback)(int cycles_executed)); void RegisterMHzChangeCallback(MHzChangeCallback callback); std::string GetScheduledEventsSummary(); diff --git a/src/core/file_sys/archive_backend.cpp b/src/core/file_sys/archive_backend.cpp index cc0aa7022..1fae0ede0 100644 --- a/src/core/file_sys/archive_backend.cpp +++ b/src/core/file_sys/archive_backend.cpp @@ -5,34 +5,28 @@ #include <cstddef> #include <iomanip> #include <sstream> - #include "common/logging/log.h" #include "common/string_util.h" - #include "core/file_sys/archive_backend.h" #include "core/memory.h" - namespace FileSys { Path::Path(LowPathType type, u32 size, u32 pointer) : type(type) { switch (type) { - case Binary: - { + case Binary: { binary.resize(size); Memory::ReadBlock(pointer, binary.data(), binary.size()); break; } - case Char: - { + case Char: { string.resize(size - 1); // Data is always null-terminated. Memory::ReadBlock(pointer, &string[0], string.size()); break; } - case Wchar: - { + case Wchar: { u16str.resize(size / 2 - 1); // Data is always null-terminated. Memory::ReadBlock(pointer, &u16str[0], u16str.size() * sizeof(char16_t)); break; @@ -50,8 +44,7 @@ std::string Path::DebugStr() const { return "[Invalid]"; case Empty: return "[Empty]"; - case Binary: - { + case Binary: { std::stringstream res; res << "[Binary: "; for (unsigned byte : binary) @@ -73,13 +66,13 @@ std::string Path::AsString() const { case Wchar: return Common::UTF16ToUTF8(u16str); case Empty: - return{}; + return {}; case Invalid: case Binary: default: // TODO(yuriks): Add assert LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!"); - return{}; + return {}; } } @@ -90,12 +83,12 @@ std::u16string Path::AsU16Str() const { case Wchar: return u16str; case Empty: - return{}; + return {}; case Invalid: case Binary: // TODO(yuriks): Add assert LOG_ERROR(Service_FS, "LowPathType cannot be converted to u16string!"); - return{}; + return {}; } } @@ -105,25 +98,23 @@ std::vector<u8> Path::AsBinary() const { return binary; case Char: return std::vector<u8>(string.begin(), string.end()); - case Wchar: - { + case Wchar: { // use two u8 for each character of u16str std::vector<u8> to_return(u16str.size() * 2); for (size_t i = 0; i < u16str.size(); ++i) { u16 tmp_char = u16str.at(i); - to_return[i*2] = (tmp_char & 0xFF00) >> 8; - to_return[i*2 + 1] = (tmp_char & 0x00FF); + to_return[i * 2] = (tmp_char & 0xFF00) >> 8; + to_return[i * 2 + 1] = (tmp_char & 0x00FF); } return to_return; } case Empty: - return{}; + return {}; case Invalid: default: // TODO(yuriks): Add assert LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!"); - return{}; + return {}; } } - } diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h index 5d91e47f3..d69c3c785 100644 --- a/src/core/file_sys/archive_backend.h +++ b/src/core/file_sys/archive_backend.h @@ -8,14 +8,11 @@ #include <string> #include <utility> #include <vector> - #include "common/bit_field.h" #include "common/common_types.h" #include "common/swap.h" - #include "core/hle/result.h" - namespace FileSys { class FileBackend; @@ -24,10 +21,10 @@ class DirectoryBackend; // Path string type enum LowPathType : u32 { Invalid = 0, - Empty = 1, - Binary = 2, - Char = 3, - Wchar = 4 + Empty = 1, + Binary = 2, + Char = 3, + Wchar = 4, }; union Mode { @@ -44,7 +41,9 @@ public: Path(std::vector<u8> binary_data) : type(Binary), binary(std::move(binary_data)) {} Path(LowPathType type, u32 size, u32 pointer); - LowPathType GetType() const { return type; } + LowPathType GetType() const { + return type; + } /** * Gets the string representation of the path for debugging @@ -63,18 +62,18 @@ private: std::u16string u16str; }; +/// Parameters of the archive, as specified in the Create or Format call. struct ArchiveFormatInfo { - u32_le total_size; ///< The pre-defined size of the archive, as specified in the Create or Format call - u32_le number_directories; ///< The pre-defined number of directories in the archive, as specified in the Create or Format call - u32_le number_files; ///< The pre-defined number of files in the archive, as specified in the Create or Format call - u8 duplicate_data; ///< Whether the archive should duplicate the data, as specified in the Create or Format call + u32_le total_size; ///< The pre-defined size of the archive. + u32_le number_directories; ///< The pre-defined number of directories in the archive. + u32_le number_files; ///< The pre-defined number of files in the archive. + u8 duplicate_data; ///< Whether the archive should duplicate the data. }; static_assert(std::is_pod<ArchiveFormatInfo>::value, "ArchiveFormatInfo is not POD"); class ArchiveBackend : NonCopyable { public: - virtual ~ArchiveBackend() { - } + virtual ~ArchiveBackend() {} /** * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.) @@ -87,7 +86,8 @@ public: * @param mode Mode to open the file with * @return Opened file, or error code */ - virtual ResultVal<std::unique_ptr<FileBackend>> OpenFile(const Path& path, const Mode mode) const = 0; + virtual ResultVal<std::unique_ptr<FileBackend>> OpenFile(const Path& path, + const Mode mode) const = 0; /** * Delete a file specified by its path @@ -150,8 +150,7 @@ public: class ArchiveFactory : NonCopyable { public: - virtual ~ArchiveFactory() { - } + virtual ~ArchiveFactory() {} /** * Get a descriptive name for the archive (e.g. "RomFS", "SaveData", etc.) diff --git a/src/core/file_sys/archive_extsavedata.cpp b/src/core/file_sys/archive_extsavedata.cpp index 1d9eaefcb..e1d29efd3 100644 --- a/src/core/file_sys/archive_extsavedata.cpp +++ b/src/core/file_sys/archive_extsavedata.cpp @@ -5,12 +5,10 @@ #include <algorithm> #include <memory> #include <vector> - #include "common/common_types.h" #include "common/file_util.h" #include "common/logging/log.h" #include "common/string_util.h" - #include "core/file_sys/archive_extsavedata.h" #include "core/file_sys/disk_archive.h" #include "core/hle/service/fs/archive.h" @@ -30,10 +28,11 @@ std::string GetExtSaveDataPath(const std::string& mount_point, const Path& path) std::string GetExtDataContainerPath(const std::string& mount_point, bool shared) { if (shared) - return Common::StringFromFormat("%sdata/%s/extdata/", mount_point.c_str(), SYSTEM_ID.c_str()); + return Common::StringFromFormat("%sdata/%s/extdata/", mount_point.c_str(), + SYSTEM_ID.c_str()); return Common::StringFromFormat("%sNintendo 3DS/%s/%s/extdata/", mount_point.c_str(), - SYSTEM_ID.c_str(), SDCARD_ID.c_str()); + SYSTEM_ID.c_str(), SDCARD_ID.c_str()); } Path ConstructExtDataBinaryPath(u32 media_type, u32 high, u32 low) { @@ -54,11 +53,12 @@ Path ConstructExtDataBinaryPath(u32 media_type, u32 high, u32 low) { for (unsigned i = 0; i < 4; ++i) binary_path.push_back((high >> (8 * i)) & 0xFF); - return { binary_path }; + return {binary_path}; } -ArchiveFactory_ExtSaveData::ArchiveFactory_ExtSaveData(const std::string& mount_location, bool shared) - : shared(shared), mount_point(GetExtDataContainerPath(mount_location, shared)) { +ArchiveFactory_ExtSaveData::ArchiveFactory_ExtSaveData(const std::string& mount_location, + bool shared) + : shared(shared), mount_point(GetExtDataContainerPath(mount_location, shared)) { LOG_INFO(Service_FS, "Directory %s set as base for ExtSaveData.", mount_point.c_str()); } @@ -88,7 +88,8 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_ExtSaveData::Open(cons return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); } -ResultCode ArchiveFactory_ExtSaveData::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { +ResultCode ArchiveFactory_ExtSaveData::Format(const Path& path, + const FileSys::ArchiveFormatInfo& format_info) { // These folders are always created with the ExtSaveData std::string user_path = GetExtSaveDataPath(mount_point, path) + "user/"; std::string boss_path = GetExtSaveDataPath(mount_point, path) + "boss/"; @@ -115,7 +116,8 @@ ResultVal<ArchiveFormatInfo> ArchiveFactory_ExtSaveData::GetFormatInfo(const Pat if (!file.IsOpen()) { LOG_ERROR(Service_FS, "Could not open metadata information for archive"); // TODO(Subv): Verify error code - return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, ErrorSummary::InvalidState, ErrorLevel::Status); + return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, + ErrorSummary::InvalidState, ErrorLevel::Status); } ArchiveFormatInfo info = {}; @@ -123,7 +125,8 @@ ResultVal<ArchiveFormatInfo> ArchiveFactory_ExtSaveData::GetFormatInfo(const Pat return MakeResult<ArchiveFormatInfo>(info); } -void ArchiveFactory_ExtSaveData::WriteIcon(const Path& path, const u8* icon_data, size_t icon_size) { +void ArchiveFactory_ExtSaveData::WriteIcon(const Path& path, const u8* icon_data, + size_t icon_size) { std::string game_path = FileSys::GetExtSaveDataPath(GetMountPoint(), path); FileUtil::IOFile icon_file(game_path + "icon", "wb"); icon_file.WriteBytes(icon_data, icon_size); diff --git a/src/core/file_sys/archive_extsavedata.h b/src/core/file_sys/archive_extsavedata.h index e9a72850d..6a3431e94 100644 --- a/src/core/file_sys/archive_extsavedata.h +++ b/src/core/file_sys/archive_extsavedata.h @@ -6,9 +6,7 @@ #include <memory> #include <string> - #include "common/common_types.h" - #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" @@ -28,13 +26,17 @@ public: */ bool Initialize(); - std::string GetName() const override { return "ExtSaveData"; } + std::string GetName() const override { + return "ExtSaveData"; + } ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; - const std::string& GetMountPoint() const { return mount_point; } + const std::string& GetMountPoint() const { + return mount_point; + } /** * Writes the SMDH icon of the ExtSaveData to file @@ -45,7 +47,8 @@ public: void WriteIcon(const Path& path, const u8* icon_data, size_t icon_size); private: - bool shared; ///< Whether this archive represents an ExtSaveData archive or a SharedExtSaveData archive + bool shared; ///< Whether this archive represents an ExtSaveData archive or a SharedExtSaveData + /// archive /** * This holds the full directory path for this archive, it is only set after a successful call @@ -65,7 +68,8 @@ private: std::string GetExtSaveDataPath(const std::string& mount_point, const Path& path); /** - * Constructs a path to the base folder to hold concrete ExtSaveData archives in the host file system. + * Constructs a path to the base folder to hold concrete ExtSaveData archives in the host file + * system. * @param mount_point The base folder where this folder resides, ie. SDMC or NAND. * @param shared Whether this ExtSaveData container is for SharedExtSaveDatas or not. * @returns The path to the base ExtSaveData archives' folder in the host file system diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp index 38828b546..6c99ca5b4 100644 --- a/src/core/file_sys/archive_romfs.cpp +++ b/src/core/file_sys/archive_romfs.cpp @@ -4,10 +4,8 @@ #include <algorithm> #include <memory> - #include "common/common_types.h" #include "common/logging/log.h" - #include "core/file_sys/archive_romfs.h" #include "core/file_sys/ivfc_archive.h" @@ -28,11 +26,12 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_RomFS::Open(const Path return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); } -ResultCode ArchiveFactory_RomFS::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { +ResultCode ArchiveFactory_RomFS::Format(const Path& path, + const FileSys::ArchiveFormatInfo& format_info) { LOG_ERROR(Service_FS, "Attempted to format a RomFS archive."); // TODO: Verify error code - return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, - ErrorSummary::NotSupported, ErrorLevel::Permanent); + return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, + ErrorLevel::Permanent); } ResultVal<ArchiveFormatInfo> ArchiveFactory_RomFS::GetFormatInfo(const Path& path) const { diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h index c5a329122..8a8082a05 100644 --- a/src/core/file_sys/archive_romfs.h +++ b/src/core/file_sys/archive_romfs.h @@ -7,9 +7,7 @@ #include <memory> #include <string> #include <vector> - #include "common/common_types.h" - #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" #include "core/loader/loader.h" @@ -24,7 +22,9 @@ class ArchiveFactory_RomFS final : public ArchiveFactory { public: ArchiveFactory_RomFS(Loader::AppLoader& app_loader); - std::string GetName() const override { return "RomFS"; } + std::string GetName() const override { + return "RomFS"; + } ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; diff --git a/src/core/file_sys/archive_savedata.cpp b/src/core/file_sys/archive_savedata.cpp index fd5711e14..6711035ec 100644 --- a/src/core/file_sys/archive_savedata.cpp +++ b/src/core/file_sys/archive_savedata.cpp @@ -4,12 +4,10 @@ #include <algorithm> #include <memory> - #include "common/common_types.h" #include "common/file_util.h" #include "common/logging/log.h" #include "common/string_util.h" - #include "core/file_sys/archive_savedata.h" #include "core/file_sys/disk_archive.h" #include "core/hle/kernel/process.h" @@ -22,48 +20,54 @@ namespace FileSys { static std::string GetSaveDataContainerPath(const std::string& sdmc_directory) { return Common::StringFromFormat("%sNintendo 3DS/%s/%s/title/", sdmc_directory.c_str(), - SYSTEM_ID.c_str(), SDCARD_ID.c_str()); + SYSTEM_ID.c_str(), SDCARD_ID.c_str()); } static std::string GetSaveDataPath(const std::string& mount_location, u64 program_id) { u32 high = (u32)(program_id >> 32); u32 low = (u32)(program_id & 0xFFFFFFFF); - return Common::StringFromFormat("%s%08x/%08x/data/00000001/", mount_location.c_str(), high, low); + return Common::StringFromFormat("%s%08x/%08x/data/00000001/", mount_location.c_str(), high, + low); } static std::string GetSaveDataMetadataPath(const std::string& mount_location, u64 program_id) { u32 high = (u32)(program_id >> 32); u32 low = (u32)(program_id & 0xFFFFFFFF); - return Common::StringFromFormat("%s%08x/%08x/data/00000001.metadata", mount_location.c_str(), high, low); + return Common::StringFromFormat("%s%08x/%08x/data/00000001.metadata", mount_location.c_str(), + high, low); } ArchiveFactory_SaveData::ArchiveFactory_SaveData(const std::string& sdmc_directory) - : mount_point(GetSaveDataContainerPath(sdmc_directory)) { + : mount_point(GetSaveDataContainerPath(sdmc_directory)) { LOG_INFO(Service_FS, "Directory %s set as SaveData.", this->mount_point.c_str()); } ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveData::Open(const Path& path) { - std::string concrete_mount_point = GetSaveDataPath(mount_point, Kernel::g_current_process->codeset->program_id); + std::string concrete_mount_point = + GetSaveDataPath(mount_point, Kernel::g_current_process->codeset->program_id); if (!FileUtil::Exists(concrete_mount_point)) { - // When a SaveData archive is created for the first time, it is not yet formatted - // and the save file/directory structure expected by the game has not yet been initialized. - // Returning the NotFormatted error code will signal the game to provision the SaveData archive - // with the files and folders that it expects. + // When a SaveData archive is created for the first time, it is not yet formatted and the + // save file/directory structure expected by the game has not yet been initialized. + // Returning the NotFormatted error code will signal the game to provision the SaveData + // archive with the files and folders that it expects. return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, - ErrorSummary::InvalidState, ErrorLevel::Status); + ErrorSummary::InvalidState, ErrorLevel::Status); } auto archive = std::make_unique<DiskArchive>(std::move(concrete_mount_point)); return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); } -ResultCode ArchiveFactory_SaveData::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { - std::string concrete_mount_point = GetSaveDataPath(mount_point, Kernel::g_current_process->codeset->program_id); +ResultCode ArchiveFactory_SaveData::Format(const Path& path, + const FileSys::ArchiveFormatInfo& format_info) { + std::string concrete_mount_point = + GetSaveDataPath(mount_point, Kernel::g_current_process->codeset->program_id); FileUtil::DeleteDirRecursively(concrete_mount_point); FileUtil::CreateFullPath(concrete_mount_point); // Write the format metadata - std::string metadata_path = GetSaveDataMetadataPath(mount_point, Kernel::g_current_process->codeset->program_id); + std::string metadata_path = + GetSaveDataMetadataPath(mount_point, Kernel::g_current_process->codeset->program_id); FileUtil::IOFile file(metadata_path, "wb"); if (file.IsOpen()) { @@ -74,13 +78,15 @@ ResultCode ArchiveFactory_SaveData::Format(const Path& path, const FileSys::Arch } ResultVal<ArchiveFormatInfo> ArchiveFactory_SaveData::GetFormatInfo(const Path& path) const { - std::string metadata_path = GetSaveDataMetadataPath(mount_point, Kernel::g_current_process->codeset->program_id); + std::string metadata_path = + GetSaveDataMetadataPath(mount_point, Kernel::g_current_process->codeset->program_id); FileUtil::IOFile file(metadata_path, "rb"); if (!file.IsOpen()) { LOG_ERROR(Service_FS, "Could not open metadata information for archive"); // TODO(Subv): Verify error code - return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, ErrorSummary::InvalidState, ErrorLevel::Status); + return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, + ErrorSummary::InvalidState, ErrorLevel::Status); } ArchiveFormatInfo info = {}; diff --git a/src/core/file_sys/archive_savedata.h b/src/core/file_sys/archive_savedata.h index 7a5a24089..6a372865a 100644 --- a/src/core/file_sys/archive_savedata.h +++ b/src/core/file_sys/archive_savedata.h @@ -6,7 +6,6 @@ #include <memory> #include <string> - #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" @@ -20,7 +19,9 @@ class ArchiveFactory_SaveData final : public ArchiveFactory { public: ArchiveFactory_SaveData(const std::string& mount_point); - std::string GetName() const override { return "SaveData"; } + std::string GetName() const override { + return "SaveData"; + } ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; diff --git a/src/core/file_sys/archive_savedatacheck.cpp b/src/core/file_sys/archive_savedatacheck.cpp index 9f65e5455..6c4542b7d 100644 --- a/src/core/file_sys/archive_savedatacheck.cpp +++ b/src/core/file_sys/archive_savedatacheck.cpp @@ -5,12 +5,10 @@ #include <algorithm> #include <memory> #include <vector> - #include "common/common_types.h" #include "common/file_util.h" #include "common/logging/log.h" #include "common/string_util.h" - #include "core/file_sys/archive_savedatacheck.h" #include "core/file_sys/ivfc_archive.h" #include "core/hle/service/fs/archive.h" @@ -25,13 +23,12 @@ static std::string GetSaveDataCheckContainerPath(const std::string& nand_directo } static std::string GetSaveDataCheckPath(const std::string& mount_point, u32 high, u32 low) { - return Common::StringFromFormat("%s%08x/%08x/content/00000000.app.romfs", - mount_point.c_str(), high, low); + return Common::StringFromFormat("%s%08x/%08x/content/00000000.app.romfs", mount_point.c_str(), + high, low); } -ArchiveFactory_SaveDataCheck::ArchiveFactory_SaveDataCheck(const std::string& nand_directory) : - mount_point(GetSaveDataCheckContainerPath(nand_directory)) { -} +ArchiveFactory_SaveDataCheck::ArchiveFactory_SaveDataCheck(const std::string& nand_directory) + : mount_point(GetSaveDataCheckContainerPath(nand_directory)) {} ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveDataCheck::Open(const Path& path) { auto vec = path.AsBinary(); @@ -48,11 +45,12 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SaveDataCheck::Open(co return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); } -ResultCode ArchiveFactory_SaveDataCheck::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { +ResultCode ArchiveFactory_SaveDataCheck::Format(const Path& path, + const FileSys::ArchiveFormatInfo& format_info) { LOG_ERROR(Service_FS, "Attempted to format a SaveDataCheck archive."); // TODO: Verify error code - return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, - ErrorSummary::NotSupported, ErrorLevel::Permanent); + return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, + ErrorLevel::Permanent); } ResultVal<ArchiveFormatInfo> ArchiveFactory_SaveDataCheck::GetFormatInfo(const Path& path) const { diff --git a/src/core/file_sys/archive_savedatacheck.h b/src/core/file_sys/archive_savedatacheck.h index ea2624d64..e9cafbed9 100644 --- a/src/core/file_sys/archive_savedatacheck.h +++ b/src/core/file_sys/archive_savedatacheck.h @@ -6,7 +6,6 @@ #include <memory> #include <string> - #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" @@ -20,7 +19,9 @@ class ArchiveFactory_SaveDataCheck final : public ArchiveFactory { public: ArchiveFactory_SaveDataCheck(const std::string& mount_point); - std::string GetName() const override { return "SaveDataCheck"; } + std::string GetName() const override { + return "SaveDataCheck"; + } ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp index 9b218af58..bcb03ed36 100644 --- a/src/core/file_sys/archive_sdmc.cpp +++ b/src/core/file_sys/archive_sdmc.cpp @@ -4,10 +4,8 @@ #include <algorithm> #include <memory> - #include "common/file_util.h" #include "common/logging/log.h" - #include "core/file_sys/archive_sdmc.h" #include "core/file_sys/disk_archive.h" #include "core/settings.h" @@ -17,7 +15,8 @@ namespace FileSys { -ArchiveFactory_SDMC::ArchiveFactory_SDMC(const std::string& sdmc_directory) : sdmc_directory(sdmc_directory) { +ArchiveFactory_SDMC::ArchiveFactory_SDMC(const std::string& sdmc_directory) + : sdmc_directory(sdmc_directory) { LOG_INFO(Service_FS, "Directory %s set as SDMC.", sdmc_directory.c_str()); } @@ -40,7 +39,8 @@ ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SDMC::Open(const Path& return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); } -ResultCode ArchiveFactory_SDMC::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { +ResultCode ArchiveFactory_SDMC::Format(const Path& path, + const FileSys::ArchiveFormatInfo& format_info) { // This is kind of an undesirable operation, so let's just ignore it. :) return RESULT_SUCCESS; } diff --git a/src/core/file_sys/archive_sdmc.h b/src/core/file_sys/archive_sdmc.h index 35c0f3725..88e855351 100644 --- a/src/core/file_sys/archive_sdmc.h +++ b/src/core/file_sys/archive_sdmc.h @@ -6,7 +6,6 @@ #include <memory> #include <string> - #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" @@ -26,7 +25,9 @@ public: */ bool Initialize(); - std::string GetName() const override { return "SDMC"; } + std::string GetName() const override { + return "SDMC"; + } ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override; ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; diff --git a/src/core/file_sys/archive_systemsavedata.cpp b/src/core/file_sys/archive_systemsavedata.cpp index 1bcc228a1..48ebc0ed4 100644 --- a/src/core/file_sys/archive_systemsavedata.cpp +++ b/src/core/file_sys/archive_systemsavedata.cpp @@ -5,11 +5,9 @@ #include <algorithm> #include <memory> #include <vector> - #include "common/common_types.h" #include "common/file_util.h" #include "common/string_util.h" - #include "core/file_sys/archive_systemsavedata.h" #include "core/file_sys/disk_archive.h" #include "core/hle/service/fs/archive.h" @@ -45,25 +43,25 @@ Path ConstructSystemSaveDataBinaryPath(u32 high, u32 low) { for (unsigned i = 0; i < 4; ++i) binary_path.push_back((low >> (8 * i)) & 0xFF); - return { binary_path }; + return {binary_path}; } ArchiveFactory_SystemSaveData::ArchiveFactory_SystemSaveData(const std::string& nand_path) - : base_path(GetSystemSaveDataContainerPath(nand_path)) { -} + : base_path(GetSystemSaveDataContainerPath(nand_path)) {} ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SystemSaveData::Open(const Path& path) { std::string fullpath = GetSystemSaveDataPath(base_path, path); if (!FileUtil::Exists(fullpath)) { // TODO(Subv): Check error code, this one is probably wrong return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS, - ErrorSummary::InvalidState, ErrorLevel::Status); + ErrorSummary::InvalidState, ErrorLevel::Status); } auto archive = std::make_unique<DiskArchive>(fullpath); return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive)); } -ResultCode ArchiveFactory_SystemSaveData::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { +ResultCode ArchiveFactory_SystemSaveData::Format(const Path& path, + const FileSys::ArchiveFormatInfo& format_info) { std::string fullpath = GetSystemSaveDataPath(base_path, path); FileUtil::DeleteDirRecursively(fullpath); FileUtil::CreateFullPath(fullpath); diff --git a/src/core/file_sys/archive_systemsavedata.h b/src/core/file_sys/archive_systemsavedata.h index 2bc13d4ee..a24b89f2b 100644 --- a/src/core/file_sys/archive_systemsavedata.h +++ b/src/core/file_sys/archive_systemsavedata.h @@ -6,9 +6,7 @@ #include <memory> #include <string> - #include "common/common_types.h" - #include "core/file_sys/archive_backend.h" #include "core/hle/result.h" @@ -26,7 +24,9 @@ public: ResultCode Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) override; ResultVal<ArchiveFormatInfo> GetFormatInfo(const Path& path) const override; - std::string GetName() const override { return "SystemSaveData"; } + std::string GetName() const override { + return "SystemSaveData"; + } private: std::string base_path; @@ -42,7 +42,8 @@ private: std::string GetSystemSaveDataPath(const std::string& mount_point, const Path& path); /** - * Constructs a path to the base folder to hold concrete SystemSaveData archives in the host file system. + * Constructs a path to the base folder to hold concrete SystemSaveData archives in the host file + * system. * @param mount_point The base folder where this folder resides, ie. SDMC or NAND. * @returns The path to the base SystemSaveData archives' folder in the host file system */ diff --git a/src/core/file_sys/directory_backend.h b/src/core/file_sys/directory_backend.h index a25dc0cfa..b55e382ef 100644 --- a/src/core/file_sys/directory_backend.h +++ b/src/core/file_sys/directory_backend.h @@ -6,7 +6,6 @@ #include <array> #include <cstddef> - #include "common/common_types.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -19,15 +18,16 @@ const size_t FILENAME_LENGTH = 0x20C / 2; struct Entry { char16_t filename[FILENAME_LENGTH]; // Entry name (UTF-16, null-terminated) std::array<char, 9> short_name; // 8.3 file name ('longfilename' -> 'LONGFI~1', null-terminated) - char unknown1; // unknown (observed values: 0x0A, 0x70, 0xFD) - std::array<char, 4> extension; // 8.3 file extension (set to spaces for directories, null-terminated) - char unknown2; // unknown (always 0x01) - char unknown3; // unknown (0x00 or 0x08) + char unknown1; // unknown (observed values: 0x0A, 0x70, 0xFD) + std::array<char, 4> + extension; // 8.3 file extension (set to spaces for directories, null-terminated) + char unknown2; // unknown (always 0x01) + char unknown3; // unknown (0x00 or 0x08) char is_directory; // directory flag - char is_hidden; // hidden flag - char is_archive; // archive flag + char is_hidden; // hidden flag + char is_archive; // archive flag char is_read_only; // read-only flag - u64 file_size; // file size (for files only) + u64 file_size; // file size (for files only) }; static_assert(sizeof(Entry) == 0x228, "Directory Entry struct isn't exactly 0x228 bytes long!"); static_assert(offsetof(Entry, short_name) == 0x20C, "Wrong offset for short_name in Entry."); @@ -37,8 +37,8 @@ static_assert(offsetof(Entry, file_size) == 0x220, "Wrong offset for file_size i class DirectoryBackend : NonCopyable { public: - DirectoryBackend() { } - virtual ~DirectoryBackend() { } + DirectoryBackend() {} + virtual ~DirectoryBackend() {} /** * Open the directory diff --git a/src/core/file_sys/disk_archive.cpp b/src/core/file_sys/disk_archive.cpp index 489cc96fb..0f66998e1 100644 --- a/src/core/file_sys/disk_archive.cpp +++ b/src/core/file_sys/disk_archive.cpp @@ -5,11 +5,9 @@ #include <algorithm> #include <cstdio> #include <memory> - #include "common/common_types.h" #include "common/file_util.h" #include "common/logging/log.h" - #include "core/file_sys/disk_archive.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -17,7 +15,8 @@ namespace FileSys { -ResultVal<std::unique_ptr<FileBackend>> DiskArchive::OpenFile(const Path& path, const Mode mode) const { +ResultVal<std::unique_ptr<FileBackend>> DiskArchive::OpenFile(const Path& path, + const Mode mode) const { LOG_DEBUG(Service_FS, "called path=%s mode=%01X", path.DebugStr().c_str(), mode.hex); auto file = std::make_unique<DiskFile>(*this, path, mode); ResultCode result = file->Open(); @@ -30,15 +29,18 @@ ResultCode DiskArchive::DeleteFile(const Path& path) const { std::string file_path = mount_point + path.AsString(); if (FileUtil::IsDirectory(file_path)) - return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled, ErrorLevel::Status); + return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled, + ErrorLevel::Status); if (!FileUtil::Exists(file_path)) - return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, ErrorLevel::Status); + return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, + ErrorLevel::Status); if (FileUtil::Delete(file_path)) return RESULT_SUCCESS; - return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled, ErrorLevel::Status); + return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled, + ErrorLevel::Status); } bool DiskArchive::RenameFile(const Path& src_path, const Path& dest_path) const { @@ -53,10 +55,12 @@ ResultCode DiskArchive::CreateFile(const FileSys::Path& path, u64 size) const { std::string full_path = mount_point + path.AsString(); if (FileUtil::IsDirectory(full_path)) - return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled, ErrorLevel::Status); + return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled, + ErrorLevel::Status); if (FileUtil::Exists(full_path)) - return ResultCode(ErrorDescription::FS_AlreadyExists, ErrorModule::FS, ErrorSummary::NothingHappened, ErrorLevel::Status); + return ResultCode(ErrorDescription::FS_AlreadyExists, ErrorModule::FS, + ErrorSummary::NothingHappened, ErrorLevel::Status); if (size == 0) { FileUtil::CreateEmptyFile(full_path); @@ -69,10 +73,10 @@ ResultCode DiskArchive::CreateFile(const FileSys::Path& path, u64 size) const { if (file.Seek(size - 1, SEEK_SET) && file.WriteBytes("", 1) == 1) return RESULT_SUCCESS; - return ResultCode(ErrorDescription::TooLarge, ErrorModule::FS, ErrorSummary::OutOfResource, ErrorLevel::Info); + return ResultCode(ErrorDescription::TooLarge, ErrorModule::FS, ErrorSummary::OutOfResource, + ErrorLevel::Info); } - bool DiskArchive::CreateDirectory(const Path& path) const { return FileUtil::CreateDir(mount_point + path.AsString()); } @@ -106,17 +110,21 @@ DiskFile::DiskFile(const DiskArchive& archive, const Path& path, const Mode mode ResultCode DiskFile::Open() { if (FileUtil::IsDirectory(path)) - return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled, ErrorLevel::Status); + return ResultCode(ErrorDescription::FS_NotAFile, ErrorModule::FS, ErrorSummary::Canceled, + ErrorLevel::Status); // Specifying only the Create flag is invalid if (mode.create_flag && !mode.read_flag && !mode.write_flag) { - return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS, ErrorSummary::Canceled, ErrorLevel::Status); + return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS, + ErrorSummary::Canceled, ErrorLevel::Status); } if (!FileUtil::Exists(path)) { if (!mode.create_flag) { - LOG_ERROR(Service_FS, "Non-existing file %s can't be open without mode create.", path.c_str()); - return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, ErrorLevel::Status); + LOG_ERROR(Service_FS, "Non-existing file %s can't be open without mode create.", + path.c_str()); + return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, + ErrorSummary::NotFound, ErrorLevel::Status); } else { // Create the file FileUtil::CreateEmptyFile(path); @@ -135,20 +143,24 @@ ResultCode DiskFile::Open() { file = std::make_unique<FileUtil::IOFile>(path, mode_string.c_str()); if (file->IsOpen()) return RESULT_SUCCESS; - return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, ErrorLevel::Status); + return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, + ErrorLevel::Status); } ResultVal<size_t> DiskFile::Read(const u64 offset, const size_t length, u8* buffer) const { if (!mode.read_flag && !mode.write_flag) - return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS, ErrorSummary::Canceled, ErrorLevel::Status); + return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS, + ErrorSummary::Canceled, ErrorLevel::Status); file->Seek(offset, SEEK_SET); return MakeResult<size_t>(file->ReadBytes(buffer, length)); } -ResultVal<size_t> DiskFile::Write(const u64 offset, const size_t length, const bool flush, const u8* buffer) const { +ResultVal<size_t> DiskFile::Write(const u64 offset, const size_t length, const bool flush, + const u8* buffer) const { if (!mode.write_flag) - return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS, ErrorSummary::Canceled, ErrorLevel::Status); + return ResultCode(ErrorDescription::FS_InvalidOpenFlags, ErrorModule::FS, + ErrorSummary::Canceled, ErrorLevel::Status); file->Seek(offset, SEEK_SET); size_t written = file->WriteBytes(buffer, length); @@ -198,7 +210,8 @@ u32 DiskDirectory::Read(const u32 count, Entry* entries) { const std::string& filename = file.virtualName; Entry& entry = entries[entries_read]; - LOG_TRACE(Service_FS, "File %s: size=%llu dir=%d", filename.c_str(), file.size, file.isDirectory); + LOG_TRACE(Service_FS, "File %s: size=%llu dir=%d", filename.c_str(), file.size, + file.isDirectory); // TODO(Link Mauve): use a proper conversion to UTF-16. for (size_t j = 0; j < FILENAME_LENGTH; ++j) { diff --git a/src/core/file_sys/disk_archive.h b/src/core/file_sys/disk_archive.h index b4cc2f702..2165f27f9 100644 --- a/src/core/file_sys/disk_archive.h +++ b/src/core/file_sys/disk_archive.h @@ -8,10 +8,8 @@ #include <memory> #include <string> #include <vector> - #include "common/common_types.h" #include "common/file_util.h" - #include "core/file_sys/archive_backend.h" #include "core/file_sys/directory_backend.h" #include "core/file_sys/file_backend.h" @@ -31,9 +29,12 @@ class DiskArchive : public ArchiveBackend { public: DiskArchive(const std::string& mount_point_) : mount_point(mount_point_) {} - virtual std::string GetName() const override { return "DiskArchive: " + mount_point; } + virtual std::string GetName() const override { + return "DiskArchive: " + mount_point; + } - ResultVal<std::unique_ptr<FileBackend>> OpenFile(const Path& path, const Mode mode) const override; + ResultVal<std::unique_ptr<FileBackend>> OpenFile(const Path& path, + const Mode mode) const override; ResultCode DeleteFile(const Path& path) const override; bool RenameFile(const Path& src_path, const Path& dest_path) const override; bool DeleteDirectory(const Path& path) const override; diff --git a/src/core/file_sys/file_backend.h b/src/core/file_sys/file_backend.h index 9137bbbad..ed997537f 100644 --- a/src/core/file_sys/file_backend.h +++ b/src/core/file_sys/file_backend.h @@ -5,7 +5,6 @@ #pragma once #include <cstddef> - #include "common/common_types.h" #include "core/hle/result.h" @@ -16,8 +15,8 @@ namespace FileSys { class FileBackend : NonCopyable { public: - FileBackend() { } - virtual ~FileBackend() { } + FileBackend() {} + virtual ~FileBackend() {} /** * Open the file @@ -42,7 +41,8 @@ public: * @param buffer Buffer to read data from * @return Number of bytes written, or error code */ - virtual ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) const = 0; + virtual ResultVal<size_t> Write(u64 offset, size_t length, bool flush, + const u8* buffer) const = 0; /** * Get the size of the file in bytes diff --git a/src/core/file_sys/ivfc_archive.cpp b/src/core/file_sys/ivfc_archive.cpp index c61791ef7..49cc1de10 100644 --- a/src/core/file_sys/ivfc_archive.cpp +++ b/src/core/file_sys/ivfc_archive.cpp @@ -4,10 +4,8 @@ #include <cstring> #include <memory> - #include "common/common_types.h" #include "common/logging/log.h" - #include "core/file_sys/ivfc_archive.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -19,40 +17,49 @@ std::string IVFCArchive::GetName() const { return "IVFC"; } -ResultVal<std::unique_ptr<FileBackend>> IVFCArchive::OpenFile(const Path& path, const Mode mode) const { - return MakeResult<std::unique_ptr<FileBackend>>(std::make_unique<IVFCFile>(romfs_file, data_offset, data_size)); +ResultVal<std::unique_ptr<FileBackend>> IVFCArchive::OpenFile(const Path& path, + const Mode mode) const { + return MakeResult<std::unique_ptr<FileBackend>>( + std::make_unique<IVFCFile>(romfs_file, data_offset, data_size)); } ResultCode IVFCArchive::DeleteFile(const Path& path) const { - LOG_CRITICAL(Service_FS, "Attempted to delete a file from an IVFC archive (%s).", GetName().c_str()); + LOG_CRITICAL(Service_FS, "Attempted to delete a file from an IVFC archive (%s).", + GetName().c_str()); // TODO(Subv): Verify error code - return ResultCode(ErrorDescription::NoData, ErrorModule::FS, - ErrorSummary::Canceled, ErrorLevel::Status); + return ResultCode(ErrorDescription::NoData, ErrorModule::FS, ErrorSummary::Canceled, + ErrorLevel::Status); } bool IVFCArchive::RenameFile(const Path& src_path, const Path& dest_path) const { - LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str()); + LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", + GetName().c_str()); return false; } bool IVFCArchive::DeleteDirectory(const Path& path) const { - LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an IVFC archive (%s).", GetName().c_str()); + LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an IVFC archive (%s).", + GetName().c_str()); return false; } ResultCode IVFCArchive::CreateFile(const Path& path, u64 size) const { - LOG_CRITICAL(Service_FS, "Attempted to create a file in an IVFC archive (%s).", GetName().c_str()); + LOG_CRITICAL(Service_FS, "Attempted to create a file in an IVFC archive (%s).", + GetName().c_str()); // TODO: Verify error code - return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent); + return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, + ErrorLevel::Permanent); } bool IVFCArchive::CreateDirectory(const Path& path) const { - LOG_CRITICAL(Service_FS, "Attempted to create a directory in an IVFC archive (%s).", GetName().c_str()); + LOG_CRITICAL(Service_FS, "Attempted to create a directory in an IVFC archive (%s).", + GetName().c_str()); return false; } bool IVFCArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const { - LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str()); + LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", + GetName().c_str()); return false; } @@ -75,7 +82,8 @@ ResultVal<size_t> IVFCFile::Read(const u64 offset, const size_t length, u8* buff return MakeResult<size_t>(romfs_file->ReadBytes(buffer, read_length)); } -ResultVal<size_t> IVFCFile::Write(const u64 offset, const size_t length, const bool flush, const u8* buffer) const { +ResultVal<size_t> IVFCFile::Write(const u64 offset, const size_t length, const bool flush, + const u8* buffer) const { LOG_ERROR(Service_FS, "Attempted to write to IVFC file"); // TODO(Subv): Find error code return MakeResult<size_t>(0); diff --git a/src/core/file_sys/ivfc_archive.h b/src/core/file_sys/ivfc_archive.h index 19d32dcca..0df6cf83a 100644 --- a/src/core/file_sys/ivfc_archive.h +++ b/src/core/file_sys/ivfc_archive.h @@ -8,10 +8,8 @@ #include <memory> #include <string> #include <vector> - #include "common/common_types.h" #include "common/file_util.h" - #include "core/file_sys/archive_backend.h" #include "core/file_sys/directory_backend.h" #include "core/file_sys/file_backend.h" @@ -34,7 +32,8 @@ public: std::string GetName() const override; - ResultVal<std::unique_ptr<FileBackend>> OpenFile(const Path& path, const Mode mode) const override; + ResultVal<std::unique_ptr<FileBackend>> OpenFile(const Path& path, + const Mode mode) const override; ResultCode DeleteFile(const Path& path) const override; bool RenameFile(const Path& src_path, const Path& dest_path) const override; bool DeleteDirectory(const Path& path) const override; @@ -55,13 +54,17 @@ public: IVFCFile(std::shared_ptr<FileUtil::IOFile> file, u64 offset, u64 size) : romfs_file(file), data_offset(offset), data_size(size) {} - ResultCode Open() override { return RESULT_SUCCESS; } + ResultCode Open() override { + return RESULT_SUCCESS; + } ResultVal<size_t> Read(u64 offset, size_t length, u8* buffer) const override; ResultVal<size_t> Write(u64 offset, size_t length, bool flush, const u8* buffer) const override; u64 GetSize() const override; bool SetSize(u64 size) const override; - bool Close() const override { return false; } - void Flush() const override { } + bool Close() const override { + return false; + } + void Flush() const override {} private: std::shared_ptr<FileUtil::IOFile> romfs_file; @@ -71,9 +74,15 @@ private: class IVFCDirectory : public DirectoryBackend { public: - bool Open() override { return false; } - u32 Read(const u32 count, Entry* entries) override { return 0; } - bool Close() const override { return false; } + bool Open() override { + return false; + } + u32 Read(const u32 count, Entry* entries) override { + return 0; + } + bool Close() const override { + return false; + } }; } // namespace FileSys diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index 28d403158..7fc72d801 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp @@ -10,31 +10,31 @@ #include <cstdarg> #include <cstdio> #include <cstring> -#include <fcntl.h> #include <map> #include <numeric> +#include <fcntl.h> #ifdef _MSC_VER #include <WinSock2.h> -#include <ws2tcpip.h> #include <common/x64/abi.h> #include <io.h> #include <iphlpapi.h> +#include <ws2tcpip.h> #define SHUT_RDWR 2 #else -#include <unistd.h> +#include <netinet/in.h> #include <sys/select.h> #include <sys/socket.h> #include <sys/un.h> -#include <netinet/in.h> +#include <unistd.h> #endif #include "common/logging/log.h" #include "common/string_util.h" -#include "core/core.h" -#include "core/memory.h" #include "core/arm/arm_interface.h" +#include "core/core.h" #include "core/gdbstub/gdbstub.h" +#include "core/memory.h" const int GDB_BUFFER_SIZE = 10000; @@ -64,7 +64,7 @@ const u32 FPSCR_REGISTER = 58; // GDB also wants the l character at the start // This XML defines what the registers are for this specific ARM device static const char* target_xml = -R"(l<?xml version="1.0"?> + R"(l<?xml version="1.0"?> <!DOCTYPE target SYSTEM "gdb-target.dtd"> <target version="1.0"> <feature name="org.gnu.gdb.arm.core"> @@ -297,7 +297,8 @@ static void RemoveBreakpoint(BreakpointType type, PAddr addr) { auto bp = p.find(addr); if (bp != p.end()) { - LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: %08x bytes at %08x of type %d\n", bp->second.len, bp->second.addr, type); + LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: %08x bytes at %08x of type %d\n", + bp->second.len, bp->second.addr, type); p.erase(addr); } } @@ -342,7 +343,9 @@ bool CheckBreakpoint(PAddr addr, BreakpointType type) { } if (bp->second.active && (addr >= bp->second.addr && addr < bp->second.addr + len)) { - LOG_DEBUG(Debug_GDBStub, "Found breakpoint type %d @ %08x, range: %08x - %08x (%d bytes)\n", type, addr, bp->second.addr, bp->second.addr + len, len); + LOG_DEBUG(Debug_GDBStub, + "Found breakpoint type %d @ %08x, range: %08x - %08x (%d bytes)\n", type, + addr, bp->second.addr, bp->second.addr + len, len); return true; } } @@ -408,12 +411,13 @@ static void HandleQuery() { const char* query = reinterpret_cast<const char*>(command_buffer + 1); - if (strcmp(query, "TStatus") == 0 ) { + if (strcmp(query, "TStatus") == 0) { SendReply("T0"); } else if (strncmp(query, "Supported:", strlen("Supported:")) == 0) { // PacketSize needs to be large enough for target xml SendReply("PacketSize=800;qXfer:features:read+"); - } else if (strncmp(query, "Xfer:features:read:target.xml:", strlen("Xfer:features:read:target.xml:")) == 0) { + } else if (strncmp(query, "Xfer:features:read:target.xml:", + strlen("Xfer:features:read:target.xml:")) == 0) { SendReply(target_xml); } else { SendReply(""); @@ -422,10 +426,8 @@ static void HandleQuery() { /// Handle set thread command from gdb client. static void HandleSetThread() { - if (memcmp(command_buffer, "Hg0", 3) == 0 || - memcmp(command_buffer, "Hc-1", 4) == 0 || - memcmp(command_buffer, "Hc0", 4) == 0 || - memcmp(command_buffer, "Hc1", 4) == 0) { + if (memcmp(command_buffer, "Hg0", 3) == 0 || memcmp(command_buffer, "Hc-1", 4) == 0 || + memcmp(command_buffer, "Hc0", 4) == 0 || memcmp(command_buffer, "Hc1", 4) == 0) { return SendReply("OK"); } @@ -444,7 +446,9 @@ static void SendSignal(u32 signal) { latest_signal = signal; - std::string buffer = Common::StringFromFormat("T%02x%02x:%08x;%02x:%08x;", latest_signal, 15, htonl(Core::g_app_core->GetPC()), 13, htonl(Core::g_app_core->GetReg(13))); + std::string buffer = Common::StringFromFormat("T%02x%02x:%08x;%02x:%08x;", latest_signal, 15, + htonl(Core::g_app_core->GetPC()), 13, + htonl(Core::g_app_core->GetReg(13))); LOG_DEBUG(Debug_GDBStub, "Response: %s", buffer.c_str()); SendReply(buffer.c_str()); } @@ -456,7 +460,7 @@ static void ReadCommand() { u8 c = ReadByte(); if (c == '+') { - //ignore ack + // ignore ack return; } else if (c == 0x03) { LOG_INFO(Debug_GDBStub, "gdb: found break command\n"); @@ -483,8 +487,9 @@ static void ReadCommand() { u8 checksum_calculated = CalculateChecksum(command_buffer, command_length); if (checksum_received != checksum_calculated) { - LOG_ERROR(Debug_GDBStub, "gdb: invalid checksum: calculated %02x and read %02x for $%s# (length: %d)\n", - checksum_calculated, checksum_received, command_buffer, command_length); + LOG_ERROR(Debug_GDBStub, + "gdb: invalid checksum: calculated %02x and read %02x for $%s# (length: %d)\n", + checksum_calculated, checksum_received, command_buffer, command_length); command_length = 0; @@ -534,7 +539,9 @@ static void ReadRegister() { } else if (id == CPSR_REGISTER) { IntToGdbHex(reply, Core::g_app_core->GetCPSR()); } else if (id > CPSR_REGISTER && id < FPSCR_REGISTER) { - IntToGdbHex(reply, Core::g_app_core->GetVFPReg(id - CPSR_REGISTER - 1)); // VFP registers should start at 26, so one after CSPR_REGISTER + IntToGdbHex(reply, Core::g_app_core->GetVFPReg( + id - CPSR_REGISTER - + 1)); // VFP registers should start at 26, so one after CSPR_REGISTER } else if (id == FPSCR_REGISTER) { IntToGdbHex(reply, Core::g_app_core->GetVFPSystemReg(VFP_FPSCR)); // Get FPSCR IntToGdbHex(reply + 8, 0); @@ -617,7 +624,8 @@ static void WriteRegisters() { // Dummy FPA registers, ignore i += 2; } else if (reg > CPSR_REGISTER && reg < FPSCR_REGISTER) { - Core::g_app_core->SetVFPReg(reg - CPSR_REGISTER - 1, GdbHexToInt(buffer_ptr + i * CHAR_BIT)); + Core::g_app_core->SetVFPReg(reg - CPSR_REGISTER - 1, + GdbHexToInt(buffer_ptr + i * CHAR_BIT)); i++; // Skip padding } else if (reg == FPSCR_REGISTER) { Core::g_app_core->SetVFPSystemReg(VFP_FPSCR, GdbHexToInt(buffer_ptr + i * CHAR_BIT)); @@ -631,12 +639,13 @@ static void WriteRegisters() { static void ReadMemory() { static u8 reply[GDB_BUFFER_SIZE - 4]; - auto start_offset = command_buffer+1; - auto addr_pos = std::find(start_offset, command_buffer+command_length, ','); + auto start_offset = command_buffer + 1; + auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); PAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset)); - start_offset = addr_pos+1; - u32 len = HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset)); + start_offset = addr_pos + 1; + u32 len = + HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset)); LOG_DEBUG(Debug_GDBStub, "gdb: addr: %08x len: %08x\n", addr, len); @@ -656,12 +665,12 @@ static void ReadMemory() { /// Modify location in memory with data received from the gdb client. static void WriteMemory() { - auto start_offset = command_buffer+1; - auto addr_pos = std::find(start_offset, command_buffer+command_length, ','); + auto start_offset = command_buffer + 1; + auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); PAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset)); - start_offset = addr_pos+1; - auto len_pos = std::find(start_offset, command_buffer+command_length, ':'); + start_offset = addr_pos + 1; + auto len_pos = std::find(start_offset, command_buffer + command_length, ':'); u32 len = HexToInt(start_offset, static_cast<u32>(len_pos - start_offset)); u8* dst = Memory::GetPointer(addr); @@ -720,9 +729,10 @@ static bool CommitBreakpoint(BreakpointType type, PAddr addr, u32 len) { breakpoint.active = true; breakpoint.addr = addr; breakpoint.len = len; - p.insert({ addr, breakpoint }); + p.insert({addr, breakpoint}); - LOG_DEBUG(Debug_GDBStub, "gdb: added %d breakpoint: %08x bytes at %08x\n", type, breakpoint.len, breakpoint.addr); + LOG_DEBUG(Debug_GDBStub, "gdb: added %d breakpoint: %08x bytes at %08x\n", type, breakpoint.len, + breakpoint.addr); return true; } @@ -750,12 +760,13 @@ static void AddBreakpoint() { return SendReply("E01"); } - auto start_offset = command_buffer+3; - auto addr_pos = std::find(start_offset, command_buffer+command_length, ','); + auto start_offset = command_buffer + 3; + auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); PAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset)); - start_offset = addr_pos+1; - u32 len = HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset)); + start_offset = addr_pos + 1; + u32 len = + HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset)); if (type == BreakpointType::Access) { // Access is made up of Read and Write types, so add both breakpoints @@ -798,12 +809,13 @@ static void RemoveBreakpoint() { return SendReply("E01"); } - auto start_offset = command_buffer+3; - auto addr_pos = std::find(start_offset, command_buffer+command_length, ','); + auto start_offset = command_buffer + 3; + auto addr_pos = std::find(start_offset, command_buffer + command_length, ','); PAddr addr = HexToInt(start_offset, static_cast<u32>(addr_pos - start_offset)); - start_offset = addr_pos+1; - u32 len = HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset)); + start_offset = addr_pos + 1; + u32 len = + HexToInt(start_offset, static_cast<u32>((command_buffer + command_length) - start_offset)); if (type == BreakpointType::Access) { // Access is made up of Read and Write types, so add both breakpoints @@ -896,8 +908,7 @@ void ToggleServer(bool status) { if (!IsConnected() && Core::g_sys_core != nullptr) { Init(); } - } - else { + } else { // Stop server if (IsConnected()) { Shutdown(); @@ -943,7 +954,8 @@ static void Init(u16 port) { // Set socket to SO_REUSEADDR so it can always bind on the same port int reuse_enabled = 1; - if (setsockopt(tmpsock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse_enabled, sizeof(reuse_enabled)) < 0) { + if (setsockopt(tmpsock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse_enabled, + sizeof(reuse_enabled)) < 0) { LOG_ERROR(Debug_GDBStub, "Failed to set gdb socket option"); } @@ -964,13 +976,13 @@ static void Init(u16 port) { socklen_t client_addrlen = sizeof(saddr_client); gdbserver_socket = accept(tmpsock, client_addr, &client_addrlen); if (gdbserver_socket < 0) { - // In the case that we couldn't start the server for whatever reason, just start CPU execution like normal. + // In the case that we couldn't start the server for whatever reason, just start CPU + // execution like normal. halt_loop = false; step_loop = false; LOG_ERROR(Debug_GDBStub, "Failed to accept gdb client"); - } - else { + } else { LOG_INFO(Debug_GDBStub, "Client connected.\n"); saddr_client.sin_addr.s_addr = ntohl(saddr_client.sin_addr.s_addr); } @@ -1018,5 +1030,4 @@ bool GetCpuStepFlag() { void SetCpuStepFlag(bool is_step) { step_loop = is_step; } - }; diff --git a/src/core/gdbstub/gdbstub.h b/src/core/gdbstub/gdbstub.h index 4f21da23b..a7483bb10 100644 --- a/src/core/gdbstub/gdbstub.h +++ b/src/core/gdbstub/gdbstub.h @@ -6,18 +6,17 @@ #pragma once #include <atomic> - #include "common/common_types.h" namespace GDBStub { /// Breakpoint Method enum class BreakpointType { - None, ///< None - Execute, ///< Execution Breakpoint - Read, ///< Read Breakpoint - Write, ///< Write Breakpoint - Access ///< Access (R/W) Breakpoint + None, ///< None + Execute, ///< Execution Breakpoint + Read, ///< Read Breakpoint + Write, ///< Write Breakpoint + Access ///< Access (R/W) Breakpoint }; struct BreakpointAddress { @@ -25,7 +24,8 @@ struct BreakpointAddress { BreakpointType type; }; -/// If set to false, the server will never be started and no gdbstub-related functions will be executed. +/// If set to false, the server will never be started and no gdbstub-related functions will be +/// executed. extern std::atomic<bool> g_server_enabled; /** @@ -92,5 +92,4 @@ bool GetCpuStepFlag(); * @param is_step */ void SetCpuStepFlag(bool is_step); - } diff --git a/src/core/hle/applets/applet.cpp b/src/core/hle/applets/applet.cpp index ccf35fa07..4311d9897 100644 --- a/src/core/hle/applets/applet.cpp +++ b/src/core/hle/applets/applet.cpp @@ -6,10 +6,8 @@ #include <memory> #include <type_traits> #include <unordered_map> - #include "common/assert.h" #include "common/common_types.h" - #include "core/core_timing.h" #include "core/hle/applets/applet.h" #include "core/hle/applets/erreula.h" @@ -23,23 +21,24 @@ // Specializes std::hash for AppletId, so that we can use it in std::unordered_map. // Workaround for libstdc++ bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60970 namespace std { - template <> - struct hash<Service::APT::AppletId> { - typedef Service::APT::AppletId argument_type; - typedef std::size_t result_type; - - result_type operator()(const argument_type& id_code) const { - typedef std::underlying_type<argument_type>::type Type; - return std::hash<Type>()(static_cast<Type>(id_code)); - } - }; +template <> +struct hash<Service::APT::AppletId> { + typedef Service::APT::AppletId argument_type; + typedef std::size_t result_type; + + result_type operator()(const argument_type& id_code) const { + typedef std::underlying_type<argument_type>::type Type; + return std::hash<Type>()(static_cast<Type>(id_code)); + } +}; } namespace HLE { namespace Applets { static std::unordered_map<Service::APT::AppletId, std::shared_ptr<Applet>> applets; -static u32 applet_update_event = -1; ///< The CoreTiming event identifier for the Applet update callback. +static u32 applet_update_event = + -1; ///< The CoreTiming event identifier for the Applet update callback. /// The interval at which the Applet update callback will be called, 16.6ms static const u64 applet_update_interval_us = 16666; @@ -60,7 +59,8 @@ ResultCode Applet::Create(Service::APT::AppletId id) { default: LOG_ERROR(Service_APT, "Could not create applet %u", id); // TODO(Subv): Find the right error code - return ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, ErrorSummary::NotSupported, ErrorLevel::Permanent); + return ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, + ErrorSummary::NotSupported, ErrorLevel::Permanent); } return RESULT_SUCCESS; @@ -84,7 +84,7 @@ static void AppletUpdateEvent(u64 applet_id, int cycles_late) { // If the applet is still running after the last update, reschedule the event if (applet->IsRunning()) { CoreTiming::ScheduleEvent(usToCycles(applet_update_interval_us) - cycles_late, - applet_update_event, applet_id); + applet_update_event, applet_id); } else { // Otherwise the applet has terminated, in which case we should clean it up applets[id] = nullptr; @@ -96,7 +96,8 @@ ResultCode Applet::Start(const Service::APT::AppletStartupParameter& parameter) if (result.IsError()) return result; // Schedule the update event - CoreTiming::ScheduleEvent(usToCycles(applet_update_interval_us), applet_update_event, static_cast<u64>(id)); + CoreTiming::ScheduleEvent(usToCycles(applet_update_interval_us), applet_update_event, + static_cast<u64>(id)); return result; } @@ -116,6 +117,5 @@ void Init() { void Shutdown() { CoreTiming::RemoveEvent(applet_update_event); } - } } // namespace diff --git a/src/core/hle/applets/applet.h b/src/core/hle/applets/applet.h index 754c6f7db..bfdcad126 100644 --- a/src/core/hle/applets/applet.h +++ b/src/core/hle/applets/applet.h @@ -5,7 +5,6 @@ #pragma once #include <memory> - #include "core/hle/result.h" #include "core/hle/service/apt/apt.h" @@ -14,8 +13,8 @@ namespace Applets { class Applet { public: - virtual ~Applet() { } - Applet(Service::APT::AppletId id) : id(id) { } + virtual ~Applet() {} + Applet(Service::APT::AppletId id) : id(id) {} /** * Creates an instance of the Applet subclass identified by the parameter. @@ -64,7 +63,7 @@ protected: */ virtual ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) = 0; - Service::APT::AppletId id; ///< Id of this Applet + Service::APT::AppletId id; ///< Id of this Applet std::shared_ptr<std::vector<u8>> heap_memory; ///< Heap memory for this Applet }; @@ -76,6 +75,5 @@ void Init(); /// Shuts down the HLE applets void Shutdown(); - } } // namespace diff --git a/src/core/hle/applets/erreula.cpp b/src/core/hle/applets/erreula.cpp index 92a4b2323..14964427b 100644 --- a/src/core/hle/applets/erreula.cpp +++ b/src/core/hle/applets/erreula.cpp @@ -3,7 +3,6 @@ // Refer to the license.txt file included. #include "common/string_util.h" - #include "core/hle/applets/erreula.h" #include "core/hle/service/apt/apt.h" @@ -18,7 +17,8 @@ ResultCode ErrEula::ReceiveParameter(const Service::APT::MessageParameter& param return ResultCode(-1); } - // The LibAppJustStarted message contains a buffer with the size of the framebuffer shared memory. + // The LibAppJustStarted message contains a buffer with the size of the framebuffer shared + // memory. // Create the SharedMemory that will hold the framebuffer data Service::APT::CaptureBufferInfo capture_info; ASSERT(sizeof(capture_info) == parameter.buffer.size()); @@ -30,9 +30,9 @@ ResultCode ErrEula::ReceiveParameter(const Service::APT::MessageParameter& param // Allocate a heap block of the required size for this applet. heap_memory = std::make_shared<std::vector<u8>>(capture_info.size); // Create a SharedMemory that directly points to this heap block. - framebuffer_memory = Kernel::SharedMemory::CreateForApplet(heap_memory, 0, heap_memory->size(), - MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, - "ErrEula Memory"); + framebuffer_memory = Kernel::SharedMemory::CreateForApplet( + heap_memory, 0, heap_memory->size(), MemoryPermission::ReadWrite, + MemoryPermission::ReadWrite, "ErrEula Memory"); // Send the response message with the newly created SharedMemory Service::APT::MessageParameter result; @@ -49,7 +49,8 @@ ResultCode ErrEula::ReceiveParameter(const Service::APT::MessageParameter& param ResultCode ErrEula::StartImpl(const Service::APT::AppletStartupParameter& parameter) { started = true; - // TODO(Subv): Set the expected fields in the response buffer before resending it to the application. + // TODO(Subv): Set the expected fields in the response buffer before resending it to the + // application. // TODO(Subv): Reverse the parameter format for the ErrEula applet // Let the application know that we're closing @@ -65,8 +66,7 @@ ResultCode ErrEula::StartImpl(const Service::APT::AppletStartupParameter& parame return RESULT_SUCCESS; } -void ErrEula::Update() { -} +void ErrEula::Update() {} } // namespace Applets } // namespace HLE diff --git a/src/core/hle/applets/erreula.h b/src/core/hle/applets/erreula.h index 9fe72ae07..a7ec7ec01 100644 --- a/src/core/hle/applets/erreula.h +++ b/src/core/hle/applets/erreula.h @@ -12,16 +12,20 @@ namespace Applets { class ErrEula final : public Applet { public: - explicit ErrEula(Service::APT::AppletId id): Applet(id) { } + explicit ErrEula(Service::APT::AppletId id) : Applet(id) {} ResultCode ReceiveParameter(const Service::APT::MessageParameter& parameter) override; ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) override; void Update() override; - bool IsRunning() const override { return started; } + bool IsRunning() const override { + return started; + } /// This SharedMemory will be created when we receive the LibAppJustStarted message. - /// It holds the framebuffer info retrieved by the application with GSPGPU::ImportDisplayCaptureInfo + /// It holds the framebuffer info retrieved by the application with + /// GSPGPU::ImportDisplayCaptureInfo Kernel::SharedPtr<Kernel::SharedMemory> framebuffer_memory; + private: /// Whether this applet is currently running instead of the host application or not. bool started = false; diff --git a/src/core/hle/applets/mii_selector.cpp b/src/core/hle/applets/mii_selector.cpp index 77f01d208..53a8683a4 100644 --- a/src/core/hle/applets/mii_selector.cpp +++ b/src/core/hle/applets/mii_selector.cpp @@ -4,16 +4,13 @@ #include <cstring> #include <string> - #include "common/assert.h" #include "common/logging/log.h" #include "common/string_util.h" - #include "core/hle/applets/mii_selector.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/shared_memory.h" #include "core/hle/result.h" - #include "video_core/video_core.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -29,7 +26,8 @@ ResultCode MiiSelector::ReceiveParameter(const Service::APT::MessageParameter& p return ResultCode(-1); } - // The LibAppJustStarted message contains a buffer with the size of the framebuffer shared memory. + // The LibAppJustStarted message contains a buffer with the size of the framebuffer shared + // memory. // Create the SharedMemory that will hold the framebuffer data Service::APT::CaptureBufferInfo capture_info; ASSERT(sizeof(capture_info) == parameter.buffer.size()); @@ -40,9 +38,9 @@ ResultCode MiiSelector::ReceiveParameter(const Service::APT::MessageParameter& p // Allocate a heap block of the required size for this applet. heap_memory = std::make_shared<std::vector<u8>>(capture_info.size); // Create a SharedMemory that directly points to this heap block. - framebuffer_memory = Kernel::SharedMemory::CreateForApplet(heap_memory, 0, heap_memory->size(), - MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, - "MiiSelector Memory"); + framebuffer_memory = Kernel::SharedMemory::CreateForApplet( + heap_memory, 0, heap_memory->size(), MemoryPermission::ReadWrite, + MemoryPermission::ReadWrite, "MiiSelector Memory"); // Send the response message with the newly created SharedMemory Service::APT::MessageParameter result; @@ -59,12 +57,14 @@ ResultCode MiiSelector::ReceiveParameter(const Service::APT::MessageParameter& p ResultCode MiiSelector::StartImpl(const Service::APT::AppletStartupParameter& parameter) { started = true; - // TODO(Subv): Set the expected fields in the response buffer before resending it to the application. + // TODO(Subv): Set the expected fields in the response buffer before resending it to the + // application. // TODO(Subv): Reverse the parameter format for the Mii Selector memcpy(&config, parameter.buffer.data(), parameter.buffer.size()); - // TODO(Subv): Find more about this structure, result code 0 is enough to let most games continue. + // TODO(Subv): Find more about this structure, result code 0 is enough to let most games + // continue. MiiResult result; memset(&result, 0, sizeof(result)); result.result_code = 0; @@ -82,8 +82,6 @@ ResultCode MiiSelector::StartImpl(const Service::APT::AppletStartupParameter& pa return RESULT_SUCCESS; } -void MiiSelector::Update() { -} - +void MiiSelector::Update() {} } } // namespace diff --git a/src/core/hle/applets/mii_selector.h b/src/core/hle/applets/mii_selector.h index 24e8e721d..e3ab9f0cd 100644 --- a/src/core/hle/applets/mii_selector.h +++ b/src/core/hle/applets/mii_selector.h @@ -4,9 +4,8 @@ #pragma once -#include "common/common_types.h" #include "common/common_funcs.h" - +#include "common/common_types.h" #include "core/hle/applets/applet.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/shared_memory.h" @@ -17,28 +16,30 @@ namespace HLE { namespace Applets { struct MiiConfig { - u8 unk_000; - u8 unk_001; - u8 unk_002; - u8 unk_003; - u8 unk_004; + u8 unk_000; + u8 unk_001; + u8 unk_002; + u8 unk_003; + u8 unk_004; INSERT_PADDING_BYTES(3); u16 unk_008; INSERT_PADDING_BYTES(0x82); - u8 unk_08C; + u8 unk_08C; INSERT_PADDING_BYTES(3); u16 unk_090; INSERT_PADDING_BYTES(2); u32 unk_094; u16 unk_098; - u8 unk_09A[0x64]; - u8 unk_0FE; - u8 unk_0FF; + u8 unk_09A[0x64]; + u8 unk_0FE; + u8 unk_0FF; u32 unk_100; }; static_assert(sizeof(MiiConfig) == 0x104, "MiiConfig structure has incorrect size"); -#define ASSERT_REG_POSITION(field_name, position) static_assert(offsetof(MiiConfig, field_name) == position, "Field "#field_name" has invalid position") +#define ASSERT_REG_POSITION(field_name, position) \ + static_assert(offsetof(MiiConfig, field_name) == position, \ + "Field " #field_name " has invalid position") ASSERT_REG_POSITION(unk_008, 0x08); ASSERT_REG_POSITION(unk_08C, 0x8C); ASSERT_REG_POSITION(unk_090, 0x90); @@ -55,22 +56,27 @@ struct MiiResult { INSERT_PADDING_BYTES(2); }; static_assert(sizeof(MiiResult) == 0x84, "MiiResult structure has incorrect size"); -#define ASSERT_REG_POSITION(field_name, position) static_assert(offsetof(MiiResult, field_name) == position, "Field "#field_name" has invalid position") +#define ASSERT_REG_POSITION(field_name, position) \ + static_assert(offsetof(MiiResult, field_name) == position, \ + "Field " #field_name " has invalid position") ASSERT_REG_POSITION(unk_0C, 0x0C); ASSERT_REG_POSITION(unk_6C, 0x6C); #undef ASSERT_REG_POSITION class MiiSelector final : public Applet { public: - MiiSelector(Service::APT::AppletId id) : Applet(id), started(false) { } + MiiSelector(Service::APT::AppletId id) : Applet(id), started(false) {} ResultCode ReceiveParameter(const Service::APT::MessageParameter& parameter) override; ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) override; void Update() override; - bool IsRunning() const override { return started; } + bool IsRunning() const override { + return started; + } /// This SharedMemory will be created when we receive the LibAppJustStarted message. - /// It holds the framebuffer info retrieved by the application with GSPGPU::ImportDisplayCaptureInfo + /// It holds the framebuffer info retrieved by the application with + /// GSPGPU::ImportDisplayCaptureInfo Kernel::SharedPtr<Kernel::SharedMemory> framebuffer_memory; /// Whether this applet is currently running instead of the host application or not. @@ -78,6 +84,5 @@ public: MiiConfig config; }; - } } // namespace diff --git a/src/core/hle/applets/swkbd.cpp b/src/core/hle/applets/swkbd.cpp index d87bf3d57..06ddf538b 100644 --- a/src/core/hle/applets/swkbd.cpp +++ b/src/core/hle/applets/swkbd.cpp @@ -4,19 +4,16 @@ #include <cstring> #include <string> - #include "common/assert.h" #include "common/logging/log.h" #include "common/string_util.h" - #include "core/hle/applets/swkbd.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/shared_memory.h" -#include "core/hle/service/hid/hid.h" -#include "core/hle/service/gsp_gpu.h" #include "core/hle/result.h" +#include "core/hle/service/gsp_gpu.h" +#include "core/hle/service/hid/hid.h" #include "core/memory.h" - #include "video_core/video_core.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -32,7 +29,8 @@ ResultCode SoftwareKeyboard::ReceiveParameter(Service::APT::MessageParameter con return ResultCode(-1); } - // The LibAppJustStarted message contains a buffer with the size of the framebuffer shared memory. + // The LibAppJustStarted message contains a buffer with the size of the framebuffer shared + // memory. // Create the SharedMemory that will hold the framebuffer data Service::APT::CaptureBufferInfo capture_info; ASSERT(sizeof(capture_info) == parameter.buffer.size()); @@ -43,9 +41,9 @@ ResultCode SoftwareKeyboard::ReceiveParameter(Service::APT::MessageParameter con // Allocate a heap block of the required size for this applet. heap_memory = std::make_shared<std::vector<u8>>(capture_info.size); // Create a SharedMemory that directly points to this heap block. - framebuffer_memory = Kernel::SharedMemory::CreateForApplet(heap_memory, 0, heap_memory->size(), - MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, - "SoftwareKeyboard Memory"); + framebuffer_memory = Kernel::SharedMemory::CreateForApplet( + heap_memory, 0, heap_memory->size(), MemoryPermission::ReadWrite, + MemoryPermission::ReadWrite, "SoftwareKeyboard Memory"); // Send the response message with the newly created SharedMemory Service::APT::MessageParameter result; @@ -60,10 +58,12 @@ ResultCode SoftwareKeyboard::ReceiveParameter(Service::APT::MessageParameter con } ResultCode SoftwareKeyboard::StartImpl(Service::APT::AppletStartupParameter const& parameter) { - ASSERT_MSG(parameter.buffer.size() == sizeof(config), "The size of the parameter (SoftwareKeyboardConfig) is wrong"); + ASSERT_MSG(parameter.buffer.size() == sizeof(config), + "The size of the parameter (SoftwareKeyboardConfig) is wrong"); memcpy(&config, parameter.buffer.data(), parameter.buffer.size()); - text_memory = boost::static_pointer_cast<Kernel::SharedMemory, Kernel::Object>(parameter.object); + text_memory = + boost::static_pointer_cast<Kernel::SharedMemory, Kernel::Object>(parameter.object); // TODO(Subv): Verify if this is the correct behavior memset(text_memory->GetPointer(), 0, text_memory->size); @@ -115,6 +115,5 @@ void SoftwareKeyboard::Finalize() { started = false; } - } } // namespace diff --git a/src/core/hle/applets/swkbd.h b/src/core/hle/applets/swkbd.h index cf26a8fb7..ea0b1fba9 100644 --- a/src/core/hle/applets/swkbd.h +++ b/src/core/hle/applets/swkbd.h @@ -4,9 +4,8 @@ #pragma once -#include "common/common_types.h" #include "common/common_funcs.h" - +#include "common/common_types.h" #include "core/hle/applets/applet.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/shared_memory.h" @@ -53,12 +52,14 @@ static_assert(sizeof(SoftwareKeyboardConfig) == 0x400, "Software Keyboard Config class SoftwareKeyboard final : public Applet { public: - SoftwareKeyboard(Service::APT::AppletId id) : Applet(id), started(false) { } + SoftwareKeyboard(Service::APT::AppletId id) : Applet(id), started(false) {} ResultCode ReceiveParameter(const Service::APT::MessageParameter& parameter) override; ResultCode StartImpl(const Service::APT::AppletStartupParameter& parameter) override; void Update() override; - bool IsRunning() const override { return started; } + bool IsRunning() const override { + return started; + } /** * Draws a keyboard to the current bottom screen framebuffer. @@ -72,7 +73,8 @@ public: void Finalize(); /// This SharedMemory will be created when we receive the LibAppJustStarted message. - /// It holds the framebuffer info retrieved by the application with GSPGPU::ImportDisplayCaptureInfo + /// It holds the framebuffer info retrieved by the application with + /// GSPGPU::ImportDisplayCaptureInfo Kernel::SharedPtr<Kernel::SharedMemory> framebuffer_memory; /// SharedMemory where the output text will be stored @@ -84,6 +86,5 @@ public: /// Whether this applet is currently running instead of the host application or not. bool started; }; - } } // namespace diff --git a/src/core/hle/config_mem.h b/src/core/hle/config_mem.h index 24a1254f2..42fa6d789 100644 --- a/src/core/hle/config_mem.h +++ b/src/core/hle/config_mem.h @@ -12,7 +12,6 @@ #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" - #include "core/memory.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -20,16 +19,16 @@ namespace ConfigMem { struct ConfigMemDef { - u8 kernel_unk; // 0 - u8 kernel_version_rev; // 1 - u8 kernel_version_min; // 2 - u8 kernel_version_maj; // 3 + u8 kernel_unk; // 0 + u8 kernel_version_rev; // 1 + u8 kernel_version_min; // 2 + u8 kernel_version_maj; // 3 u32_le update_flag; // 4 u64_le ns_tid; // 8 u32_le sys_core_ver; // 10 - u8 unit_info; // 14 - u8 boot_firm; // 15 - u8 prev_firm; // 16 + u8 unit_info; // 14 + u8 boot_firm; // 15 + u8 prev_firm; // 16 INSERT_PADDING_BYTES(0x1); // 17 u32_le ctr_sdk_ver; // 18 INSERT_PADDING_BYTES(0x30 - 0x1C); // 1C @@ -39,15 +38,16 @@ struct ConfigMemDef { u32_le sys_mem_alloc; // 44 u32_le base_mem_alloc; // 48 INSERT_PADDING_BYTES(0x60 - 0x4C); // 4C - u8 firm_unk; // 60 - u8 firm_version_rev; // 61 - u8 firm_version_min; // 62 - u8 firm_version_maj; // 63 + u8 firm_unk; // 60 + u8 firm_version_rev; // 61 + u8 firm_version_min; // 62 + u8 firm_version_maj; // 63 u32_le firm_sys_core_ver; // 64 u32_le firm_ctr_sdk_ver; // 68 INSERT_PADDING_BYTES(0x1000 - 0x6C); // 6C }; -static_assert(sizeof(ConfigMemDef) == Memory::CONFIG_MEMORY_SIZE, "Config Memory structure size is wrong"); +static_assert(sizeof(ConfigMemDef) == Memory::CONFIG_MEMORY_SIZE, + "Config Memory structure size is wrong"); extern ConfigMemDef config_mem; diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h index 8839ce482..8ce0f6d2b 100644 --- a/src/core/hle/function_wrappers.h +++ b/src/core/hle/function_wrappers.h @@ -5,16 +5,16 @@ #pragma once #include "common/common_types.h" - #include "core/arm/arm_interface.h" -#include "core/memory.h" +#include "core/core.h" #include "core/hle/hle.h" #include "core/hle/result.h" #include "core/hle/svc.h" +#include "core/memory.h" namespace HLE { -#define PARAM(n) Core::g_app_core->GetReg(n) +#define PARAM(n) Core::g_app_core->GetReg(n) /// An invalid result code that is meant to be overwritten when a thread resumes from waiting static const ResultCode RESULT_INVALID(0xDEADC0DE); @@ -40,28 +40,33 @@ static inline void FuncReturn64(u64 res) { //////////////////////////////////////////////////////////////////////////////////////////////////// // Function wrappers that return type ResultCode -template<ResultCode func(u32, u32, u32, u32)> void Wrap() { +template <ResultCode func(u32, u32, u32, u32)> +void Wrap() { FuncReturn(func(PARAM(0), PARAM(1), PARAM(2), PARAM(3)).raw); } -template<ResultCode func(u32*, u32, u32, u32, u32, u32)> void Wrap(){ +template <ResultCode func(u32*, u32, u32, u32, u32, u32)> +void Wrap() { u32 param_1 = 0; u32 retval = func(¶m_1, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)).raw; Core::g_app_core->SetReg(1, param_1); FuncReturn(retval); } -template<ResultCode func(u32*, s32, u32, u32, u32, s32)> void Wrap() { +template <ResultCode func(u32*, s32, u32, u32, u32, s32)> +void Wrap() { u32 param_1 = 0; u32 retval = func(¶m_1, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4)).raw; Core::g_app_core->SetReg(1, param_1); FuncReturn(retval); } -template<ResultCode func(s32*, u32*, s32, bool, s64)> void Wrap() { +template <ResultCode func(s32*, u32*, s32, bool, s64)> +void Wrap() { s32 param_1 = 0; s32 retval = func(¶m_1, (Handle*)Memory::GetPointer(PARAM(1)), (s32)PARAM(2), - (PARAM(3) != 0), (((s64)PARAM(4) << 32) | PARAM(0))).raw; + (PARAM(3) != 0), (((s64)PARAM(4) << 32) | PARAM(0))) + .raw; if (retval != RESULT_INVALID.raw) { Core::g_app_core->SetReg(1, (u32)param_1); @@ -69,18 +74,22 @@ template<ResultCode func(s32*, u32*, s32, bool, s64)> void Wrap() { } } -template<ResultCode func(u32, u32, u32, u32, s64)> void Wrap() { - FuncReturn(func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), (((s64)PARAM(5) << 32) | PARAM(4))).raw); +template <ResultCode func(u32, u32, u32, u32, s64)> +void Wrap() { + FuncReturn( + func(PARAM(0), PARAM(1), PARAM(2), PARAM(3), (((s64)PARAM(5) << 32) | PARAM(4))).raw); } -template<ResultCode func(u32*)> void Wrap(){ +template <ResultCode func(u32*)> +void Wrap() { u32 param_1 = 0; u32 retval = func(¶m_1).raw; Core::g_app_core->SetReg(1, param_1); FuncReturn(retval); } -template<ResultCode func(u32, s64)> void Wrap() { +template <ResultCode func(u32, s64)> +void Wrap() { s32 retval = func(PARAM(0), (((s64)PARAM(3) << 32) | PARAM(2))).raw; if (retval != RESULT_INVALID.raw) { @@ -88,7 +97,8 @@ template<ResultCode func(u32, s64)> void Wrap() { } } -template<ResultCode func(MemoryInfo*, PageInfo*, u32)> void Wrap() { +template <ResultCode func(MemoryInfo*, PageInfo*, u32)> +void Wrap() { MemoryInfo memory_info = {}; PageInfo page_info = {}; u32 retval = func(&memory_info, &page_info, PARAM(2)).raw; @@ -100,7 +110,8 @@ template<ResultCode func(MemoryInfo*, PageInfo*, u32)> void Wrap() { FuncReturn(retval); } -template<ResultCode func(MemoryInfo*, PageInfo*, Handle, u32)> void Wrap() { +template <ResultCode func(MemoryInfo*, PageInfo*, Handle, u32)> +void Wrap() { MemoryInfo memory_info = {}; PageInfo page_info = {}; u32 retval = func(&memory_info, &page_info, PARAM(2), PARAM(3)).raw; @@ -112,55 +123,65 @@ template<ResultCode func(MemoryInfo*, PageInfo*, Handle, u32)> void Wrap() { FuncReturn(retval); } -template<ResultCode func(s32*, u32)> void Wrap(){ +template <ResultCode func(s32*, u32)> +void Wrap() { s32 param_1 = 0; u32 retval = func(¶m_1, PARAM(1)).raw; Core::g_app_core->SetReg(1, param_1); FuncReturn(retval); } -template<ResultCode func(u32, s32)> void Wrap() { +template <ResultCode func(u32, s32)> +void Wrap() { FuncReturn(func(PARAM(0), (s32)PARAM(1)).raw); } -template<ResultCode func(u32*, u32)> void Wrap(){ +template <ResultCode func(u32*, u32)> +void Wrap() { u32 param_1 = 0; u32 retval = func(¶m_1, PARAM(1)).raw; Core::g_app_core->SetReg(1, param_1); FuncReturn(retval); } -template<ResultCode func(u32)> void Wrap() { +template <ResultCode func(u32)> +void Wrap() { FuncReturn(func(PARAM(0)).raw); } -template<ResultCode func(s64*, u32, u32*, u32)> void Wrap(){ - FuncReturn(func((s64*)Memory::GetPointer(PARAM(0)), PARAM(1), (u32*)Memory::GetPointer(PARAM(2)), - (s32)PARAM(3)).raw); +template <ResultCode func(s64*, u32, u32*, u32)> +void Wrap() { + FuncReturn(func((s64*)Memory::GetPointer(PARAM(0)), PARAM(1), + (u32*)Memory::GetPointer(PARAM(2)), (s32)PARAM(3)) + .raw); } -template<ResultCode func(u32*, const char*)> void Wrap() { +template <ResultCode func(u32*, const char*)> +void Wrap() { u32 param_1 = 0; u32 retval = func(¶m_1, (char*)Memory::GetPointer(PARAM(1))).raw; Core::g_app_core->SetReg(1, param_1); FuncReturn(retval); } -template<ResultCode func(u32*, s32, s32)> void Wrap() { +template <ResultCode func(u32*, s32, s32)> +void Wrap() { u32 param_1 = 0; u32 retval = func(¶m_1, PARAM(1), PARAM(2)).raw; Core::g_app_core->SetReg(1, param_1); FuncReturn(retval); } -template<ResultCode func(s32*, u32, s32)> void Wrap() { +template <ResultCode func(s32*, u32, s32)> +void Wrap() { s32 param_1 = 0; u32 retval = func(¶m_1, PARAM(1), PARAM(2)).raw; Core::g_app_core->SetReg(1, param_1); FuncReturn(retval); } -template<ResultCode func(s64*, u32, s32)> void Wrap() { +template <ResultCode func(s64*, u32, s32)> +void Wrap() { s64 param_1 = 0; u32 retval = func(¶m_1, PARAM(1), PARAM(2)).raw; Core::g_app_core->SetReg(1, (u32)param_1); @@ -168,7 +189,8 @@ template<ResultCode func(s64*, u32, s32)> void Wrap() { FuncReturn(retval); } -template<ResultCode func(u32*, u32, u32, u32, u32)> void Wrap() { +template <ResultCode func(u32*, u32, u32, u32, u32)> +void Wrap() { u32 param_1 = 0; // The last parameter is passed in R0 instead of R4 u32 retval = func(¶m_1, PARAM(1), PARAM(2), PARAM(3), PARAM(0)).raw; @@ -176,13 +198,15 @@ template<ResultCode func(u32*, u32, u32, u32, u32)> void Wrap() { FuncReturn(retval); } -template<ResultCode func(u32, s64, s64)> void Wrap() { +template <ResultCode func(u32, s64, s64)> +void Wrap() { s64 param1 = ((u64)PARAM(3) << 32) | PARAM(2); s64 param2 = ((u64)PARAM(4) << 32) | PARAM(1); FuncReturn(func(PARAM(0), param1, param2).raw); } -template<ResultCode func(s64*, Handle, u32)> void Wrap() { +template <ResultCode func(s64*, Handle, u32)> +void Wrap() { s64 param_1 = 0; u32 retval = func(¶m_1, PARAM(1), PARAM(2)).raw; Core::g_app_core->SetReg(1, (u32)param_1); @@ -190,14 +214,18 @@ template<ResultCode func(s64*, Handle, u32)> void Wrap() { FuncReturn(retval); } -template<ResultCode func(Handle, u32)> void Wrap() { +template <ResultCode func(Handle, u32)> +void Wrap() { FuncReturn(func(PARAM(0), PARAM(1)).raw); } -template<ResultCode func(Handle*, Handle*, const char*, u32)> void Wrap() { +template <ResultCode func(Handle*, Handle*, const char*, u32)> +void Wrap() { Handle param_1 = 0; Handle param_2 = 0; - u32 retval = func(¶m_1, ¶m_2, reinterpret_cast<const char*>(Memory::GetPointer(PARAM(2))), PARAM(3)).raw; + u32 retval = func(¶m_1, ¶m_2, + reinterpret_cast<const char*>(Memory::GetPointer(PARAM(2))), PARAM(3)) + .raw; // The first out parameter is moved into R2 and the second is moved into R1. Core::g_app_core->SetReg(1, param_2); Core::g_app_core->SetReg(2, param_1); @@ -207,29 +235,34 @@ template<ResultCode func(Handle*, Handle*, const char*, u32)> void Wrap() { //////////////////////////////////////////////////////////////////////////////////////////////////// // Function wrappers that return type u32 -template<u32 func()> void Wrap() { +template <u32 func()> +void Wrap() { FuncReturn(func()); } //////////////////////////////////////////////////////////////////////////////////////////////////// // Function wrappers that return type s64 -template<s64 func()> void Wrap() { +template <s64 func()> +void Wrap() { FuncReturn64(func()); } //////////////////////////////////////////////////////////////////////////////////////////////////// /// Function wrappers that return type void -template<void func(s64)> void Wrap() { +template <void func(s64)> +void Wrap() { func(((s64)PARAM(1) << 32) | PARAM(0)); } -template<void func(const char*)> void Wrap() { +template <void func(const char*)> +void Wrap() { func((char*)Memory::GetPointer(PARAM(0))); } -template<void func(u8)> void Wrap() { +template <void func(u8)> +void Wrap() { func((u8)PARAM(0)); } diff --git a/src/core/hle/hle.cpp b/src/core/hle/hle.cpp index 5c5373517..41b772163 100644 --- a/src/core/hle/hle.cpp +++ b/src/core/hle/hle.cpp @@ -4,7 +4,6 @@ #include "common/assert.h" #include "common/logging/log.h" - #include "core/arm/arm_interface.h" #include "core/core.h" #include "core/hle/hle.h" @@ -15,13 +14,13 @@ namespace { bool reschedule; ///< If true, immediately reschedules the CPU to a new thread - } namespace HLE { -void Reschedule(const char *reason) { - DEBUG_ASSERT_MSG(reason != nullptr && strlen(reason) < 256, "Reschedule: Invalid or too long reason."); +void Reschedule(const char* reason) { + DEBUG_ASSERT_MSG(reason != nullptr && strlen(reason) < 256, + "Reschedule: Invalid or too long reason."); // TODO(bunnei): It seems that games depend on some CPU execution time elapsing during HLE // routines. This simulates that time by artificially advancing the number of CPU "ticks". diff --git a/src/core/hle/hle.h b/src/core/hle/hle.h index 69ac0ade6..23859e129 100644 --- a/src/core/hle/hle.h +++ b/src/core/hle/hle.h @@ -13,7 +13,7 @@ const Handle INVALID_HANDLE = 0; namespace HLE { -void Reschedule(const char *reason); +void Reschedule(const char* reason); bool IsReschedulePending(); void DoneRescheduling(); diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 5c3c47acf..37eec4c84 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -4,12 +4,10 @@ #include "common/common_types.h" #include "common/logging/log.h" - -#include "core/memory.h" - #include "core/hle/hle.h" #include "core/hle/kernel/address_arbiter.h" #include "core/hle/kernel/thread.h" +#include "core/memory.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // Kernel namespace @@ -28,7 +26,7 @@ SharedPtr<AddressArbiter> AddressArbiter::Create(std::string name) { } ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address, s32 value, - u64 nanoseconds) { + u64 nanoseconds) { switch (type) { // Signal thread(s) waiting for arbitrate address... @@ -38,7 +36,7 @@ ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address, ArbitrateAllThreads(address); } else { // Resume first N threads - for(int i = 0; i < value; i++) + for (int i = 0; i < value; i++) ArbitrateHighestPriorityThread(address); } break; @@ -55,8 +53,7 @@ ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address, GetCurrentThread()->WakeAfterDelay(nanoseconds); } break; - case ArbitrationType::DecrementAndWaitIfLessThan: - { + case ArbitrationType::DecrementAndWaitIfLessThan: { s32 memory_value = Memory::Read32(address); if (memory_value < value) { // Only change the memory value if the thread should wait @@ -65,8 +62,7 @@ ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address, } break; } - case ArbitrationType::DecrementAndWaitIfLessThanWithTimeout: - { + case ArbitrationType::DecrementAndWaitIfLessThanWithTimeout: { s32 memory_value = Memory::Read32(address); if (memory_value < value) { // Only change the memory value if the thread should wait @@ -79,17 +75,19 @@ ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address, default: LOG_ERROR(Kernel, "unknown type=%d", type); - return ResultCode(ErrorDescription::InvalidEnumValue, ErrorModule::Kernel, ErrorSummary::WrongArgument, ErrorLevel::Usage); + return ResultCode(ErrorDescription::InvalidEnumValue, ErrorModule::Kernel, + ErrorSummary::WrongArgument, ErrorLevel::Usage); } HLE::Reschedule(__func__); - // The calls that use a timeout seem to always return a Timeout error even if they did not put the thread to sleep + // The calls that use a timeout seem to always return a Timeout error even if they did not put + // the thread to sleep if (type == ArbitrationType::WaitIfLessThanWithTimeout || type == ArbitrationType::DecrementAndWaitIfLessThanWithTimeout) { - return ResultCode(ErrorDescription::Timeout, ErrorModule::OS, - ErrorSummary::StatusChanged, ErrorLevel::Info); + return ResultCode(ErrorDescription::Timeout, ErrorModule::OS, ErrorSummary::StatusChanged, + ErrorLevel::Info); } return RESULT_SUCCESS; } diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index 8f6a1a8df..6a7af93a9 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h @@ -5,7 +5,6 @@ #pragma once #include "common/common_types.h" - #include "core/hle/kernel/kernel.h" // Address arbiters are an underlying kernel synchronization object that can be created/used via @@ -36,13 +35,19 @@ public: */ static SharedPtr<AddressArbiter> Create(std::string name = "Unknown"); - std::string GetTypeName() const override { return "Arbiter"; } - std::string GetName() const override { return name; } + std::string GetTypeName() const override { + return "Arbiter"; + } + std::string GetName() const override { + return name; + } static const HandleType HANDLE_TYPE = HandleType::AddressArbiter; - HandleType GetHandleType() const override { return HANDLE_TYPE; } + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } - std::string name; ///< Name of address arbiter object (optional) + std::string name; ///< Name of address arbiter object (optional) ResultCode ArbitrateAddress(ArbitrationType type, VAddr address, s32 value, u64 nanoseconds); diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index 444ce8d45..aedc6f989 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -3,7 +3,6 @@ // Refer to the license.txt file included. #include "common/assert.h" - #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/server_port.h" diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h index 480b6ddae..d28147718 100644 --- a/src/core/hle/kernel/client_port.h +++ b/src/core/hle/kernel/client_port.h @@ -5,9 +5,7 @@ #pragma once #include <string> - #include "common/common_types.h" - #include "core/hle/kernel/kernel.h" namespace Kernel { @@ -17,16 +15,22 @@ class ServerPort; class ClientPort : public Object { public: friend class ServerPort; - std::string GetTypeName() const override { return "ClientPort"; } - std::string GetName() const override { return name; } + std::string GetTypeName() const override { + return "ClientPort"; + } + std::string GetName() const override { + return name; + } static const HandleType HANDLE_TYPE = HandleType::ClientPort; - HandleType GetHandleType() const override { return HANDLE_TYPE; } - - SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port. - u32 max_sessions; ///< Maximum number of simultaneous sessions the port can have - u32 active_sessions; ///< Number of currently open sessions to this port - std::string name; ///< Name of client port (optional) + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } + + SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port. + u32 max_sessions; ///< Maximum number of simultaneous sessions the port can have + u32 active_sessions; ///< Number of currently open sessions to this port + std::string name; ///< Name of client port (optional) protected: ClientPort(); diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index 2b7c6992a..1489c7002 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -2,14 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include <map> #include <algorithm> +#include <map> #include <vector> - #include "common/assert.h" - -#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/event.h" +#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/thread.h" namespace Kernel { diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h index 73d0da419..6fe74065d 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/event.h @@ -5,7 +5,6 @@ #pragma once #include "common/common_types.h" - #include "core/hle/kernel/kernel.h" namespace Kernel { @@ -16,7 +15,6 @@ enum class ResetType { Pulse, }; - class Event final : public WaitObject { public: /** @@ -26,16 +24,22 @@ public: */ static SharedPtr<Event> Create(ResetType reset_type, std::string name = "Unknown"); - std::string GetTypeName() const override { return "Event"; } - std::string GetName() const override { return name; } + std::string GetTypeName() const override { + return "Event"; + } + std::string GetName() const override { + return name; + } static const HandleType HANDLE_TYPE = HandleType::Event; - HandleType GetHandleType() const override { return HANDLE_TYPE; } + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } - ResetType reset_type; ///< Current ResetType + ResetType reset_type; ///< Current ResetType - bool signaled; ///< Whether the event has already been signaled - std::string name; ///< Name of event (optional) + bool signaled; ///< Whether the event has already been signaled + std::string name; ///< Name of event (optional) bool ShouldWait() override; void Acquire() override; diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 7a401a965..9a2c8ce05 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -3,10 +3,8 @@ // Refer to the license.txt file included. #include <algorithm> - #include "common/assert.h" #include "common/logging/log.h" - #include "core/hle/config_mem.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/memory.h" @@ -61,7 +59,8 @@ ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) { // Overflow count so it fits in the 15 bits dedicated to the generation in the handle. // CTR-OS doesn't use generation 0, so skip straight to 1. - if (next_generation >= (1 << 15)) next_generation = 1; + if (next_generation >= (1 << 15)) + next_generation = 1; generations[slot] = generation; objects[slot] = std::move(obj); diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 27ba3f912..0e95f7ff0 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -4,16 +4,13 @@ #pragma once -#include <boost/smart_ptr/intrusive_ptr.hpp> - #include <algorithm> #include <array> #include <cstddef> #include <string> #include <vector> - +#include <boost/smart_ptr/intrusive_ptr.hpp> #include "common/common_types.h" - #include "core/hle/hle.h" #include "core/hle/result.h" @@ -23,37 +20,37 @@ class Thread; // TODO: Verify code const ResultCode ERR_OUT_OF_HANDLES(ErrorDescription::OutOfMemory, ErrorModule::Kernel, - ErrorSummary::OutOfResource, ErrorLevel::Temporary); + ErrorSummary::OutOfResource, ErrorLevel::Temporary); // TOOD: Verify code const ResultCode ERR_INVALID_HANDLE(ErrorDescription::InvalidHandle, ErrorModule::Kernel, - ErrorSummary::InvalidArgument, ErrorLevel::Permanent); + ErrorSummary::InvalidArgument, ErrorLevel::Permanent); enum KernelHandle : Handle { - CurrentThread = 0xFFFF8000, - CurrentProcess = 0xFFFF8001, + CurrentThread = 0xFFFF8000, + CurrentProcess = 0xFFFF8001, }; enum class HandleType : u32 { - Unknown = 0, - - Session = 2, - Event = 3, - Mutex = 4, - SharedMemory = 5, - Redirection = 6, - Thread = 7, - Process = 8, - AddressArbiter = 9, - Semaphore = 10, - Timer = 11, - ResourceLimit = 12, - CodeSet = 13, - ClientPort = 14, - ServerPort = 15, + Unknown = 0, + + Session = 2, + Event = 3, + Mutex = 4, + SharedMemory = 5, + Redirection = 6, + Thread = 7, + Process = 8, + AddressArbiter = 9, + Semaphore = 10, + Timer = 11, + ResourceLimit = 12, + CodeSet = 13, + ClientPort = 14, + ServerPort = 15, }; enum { - DEFAULT_STACK_SIZE = 0x4000, + DEFAULT_STACK_SIZE = 0x4000, }; class Object : NonCopyable { @@ -61,10 +58,16 @@ public: virtual ~Object() {} /// Returns a unique identifier for the object. For debugging purposes only. - unsigned int GetObjectId() const { return object_id; } + unsigned int GetObjectId() const { + return object_id; + } - virtual std::string GetTypeName() const { return "[BAD KERNEL OBJECT TYPE]"; } - virtual std::string GetName() const { return "[UNKNOWN KERNEL OBJECT]"; } + virtual std::string GetTypeName() const { + return "[BAD KERNEL OBJECT TYPE]"; + } + virtual std::string GetName() const { + return "[UNKNOWN KERNEL OBJECT]"; + } virtual Kernel::HandleType GetHandleType() const = 0; /** @@ -122,7 +125,6 @@ using SharedPtr = boost::intrusive_ptr<T>; /// Class that represents a Kernel object that a thread can be waiting on class WaitObject : public Object { public: - /** * Check if the current thread should wait until the object is available * @return True if the current thread should wait due to this object being unavailable @@ -247,8 +249,12 @@ private: */ static const size_t MAX_COUNT = 4096; - static u16 GetSlot(Handle handle) { return handle >> 15; } - static u16 GetGeneration(Handle handle) { return handle & 0x7FFF; } + static u16 GetSlot(Handle handle) { + return handle >> 15; + } + static u16 GetGeneration(Handle handle) { + return handle & 0x7FFF; + } /// Stores the Object referenced by the handle or null if the slot is empty. std::array<SharedPtr<Object>, MAX_COUNT> objects; diff --git a/src/core/hle/kernel/memory.cpp b/src/core/hle/kernel/memory.cpp index 17ae87aef..e65fd5c41 100644 --- a/src/core/hle/kernel/memory.cpp +++ b/src/core/hle/kernel/memory.cpp @@ -6,12 +6,9 @@ #include <memory> #include <utility> #include <vector> - #include "audio_core/audio_core.h" - #include "common/common_types.h" #include "common/logging/log.h" - #include "core/hle/config_mem.h" #include "core/hle/kernel/memory.h" #include "core/hle/kernel/vm_manager.h" @@ -31,7 +28,7 @@ static MemoryRegionInfo memory_regions[3]; static const u32 memory_region_sizes[8][3] = { // Old 3DS layouts {0x04000000, 0x02C00000, 0x01400000}, // 0 - { /* This appears to be unused. */ }, // 1 + {/* This appears to be unused. */}, // 1 {0x06000000, 0x00C00000, 0x01400000}, // 2 {0x05000000, 0x01C00000, 0x01400000}, // 3 {0x04800000, 0x02400000, 0x01400000}, // 4 @@ -95,7 +92,6 @@ MemoryRegionInfo* GetMemoryRegion(MemoryRegion region) { UNREACHABLE(); } } - } namespace Memory { @@ -110,9 +106,8 @@ struct MemoryArea { // We don't declare the IO regions in here since its handled by other means. static MemoryArea memory_areas[] = { - {VRAM_VADDR, VRAM_SIZE, "VRAM"}, // Video memory (VRAM) + {VRAM_VADDR, VRAM_SIZE, "VRAM"}, // Video memory (VRAM) }; - } void Init() { @@ -125,15 +120,21 @@ void InitLegacyAddressSpace(Kernel::VMManager& address_space) { for (MemoryArea& area : memory_areas) { auto block = std::make_shared<std::vector<u8>>(area.size); - address_space.MapMemoryBlock(area.base, std::move(block), 0, area.size, MemoryState::Private).Unwrap(); + address_space + .MapMemoryBlock(area.base, std::move(block), 0, area.size, MemoryState::Private) + .Unwrap(); } - auto cfg_mem_vma = address_space.MapBackingMemory(CONFIG_MEMORY_VADDR, - (u8*)&ConfigMem::config_mem, CONFIG_MEMORY_SIZE, MemoryState::Shared).MoveFrom(); + auto cfg_mem_vma = address_space + .MapBackingMemory(CONFIG_MEMORY_VADDR, (u8*)&ConfigMem::config_mem, + CONFIG_MEMORY_SIZE, MemoryState::Shared) + .MoveFrom(); address_space.Reprotect(cfg_mem_vma, VMAPermission::Read); - auto shared_page_vma = address_space.MapBackingMemory(SHARED_PAGE_VADDR, - (u8*)&SharedPage::shared_page, SHARED_PAGE_SIZE, MemoryState::Shared).MoveFrom(); + auto shared_page_vma = address_space + .MapBackingMemory(SHARED_PAGE_VADDR, (u8*)&SharedPage::shared_page, + SHARED_PAGE_SIZE, MemoryState::Shared) + .MoveFrom(); address_space.Reprotect(shared_page_vma, VMAPermission::Read); AudioCore::AddAddressSpace(address_space); diff --git a/src/core/hle/kernel/memory.h b/src/core/hle/kernel/memory.h index 091c1f89f..4e1856a41 100644 --- a/src/core/hle/kernel/memory.h +++ b/src/core/hle/kernel/memory.h @@ -5,9 +5,7 @@ #pragma once #include <memory> - #include "common/common_types.h" - #include "core/hle/kernel/process.h" namespace Kernel { @@ -25,7 +23,6 @@ struct MemoryRegionInfo { void MemoryInit(u32 mem_type); void MemoryShutdown(); MemoryRegionInfo* GetMemoryRegion(MemoryRegion region); - } namespace Memory { diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index edb97d324..736944bae 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -4,11 +4,8 @@ #include <map> #include <vector> - #include <boost/range/algorithm_ext/erase.hpp> - #include "common/assert.h" - #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/mutex.h" #include "core/hle/kernel/thread.h" diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 1746360e4..53c3dc1f1 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h @@ -5,9 +5,7 @@ #pragma once #include <string> - #include "common/common_types.h" - #include "core/hle/kernel/kernel.h" namespace Kernel { @@ -24,15 +22,21 @@ public: */ static SharedPtr<Mutex> Create(bool initial_locked, std::string name = "Unknown"); - std::string GetTypeName() const override { return "Mutex"; } - std::string GetName() const override { return name; } + std::string GetTypeName() const override { + return "Mutex"; + } + std::string GetName() const override { + return name; + } static const HandleType HANDLE_TYPE = HandleType::Mutex; - HandleType GetHandleType() const override { return HANDLE_TYPE; } + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } - int lock_count; ///< Number of times the mutex has been acquired - std::string name; ///< Name of mutex (optional) - SharedPtr<Thread> holding_thread; ///< Thread that has acquired the mutex + int lock_count; ///< Number of times the mutex has been acquired + std::string name; ///< Name of mutex (optional) + SharedPtr<Thread> holding_thread; ///< Thread that has acquired the mutex bool ShouldWait() override; void Acquire() override; diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 69302cc82..ba80fe7f8 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -3,11 +3,9 @@ // Refer to the license.txt file included. #include <memory> - #include "common/assert.h" #include "common/common_funcs.h" #include "common/logging/log.h" - #include "core/hle/kernel/memory.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/resource_limit.h" @@ -60,7 +58,8 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) { while (bits && index < svc_access_mask.size()) { svc_access_mask.set(index, bits & 1); - ++index; bits >>= 1; + ++index; + bits >>= 1; } } else if ((type & 0xFF0) == 0xFE0) { // 0x00FF // Handle table size @@ -70,11 +69,11 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) { flags.raw = descriptor & 0xFFFF; } else if ((type & 0xFFE) == 0xFF8) { // 0x001F // Mapped memory range - if (i+1 >= len || ((kernel_caps[i+1] >> 20) & 0xFFE) != 0xFF8) { + if (i + 1 >= len || ((kernel_caps[i + 1] >> 20) & 0xFFE) != 0xFF8) { LOG_WARNING(Loader, "Incomplete exheader memory range descriptor ignored."); continue; } - u32 end_desc = kernel_caps[i+1]; + u32 end_desc = kernel_caps[i + 1]; ++i; // Skip over the second descriptor on the next iteration AddressMapping mapping; @@ -107,23 +106,28 @@ void Process::ParseKernelCaps(const u32* kernel_caps, size_t len) { void Process::Run(s32 main_thread_priority, u32 stack_size) { memory_region = GetMemoryRegion(flags.memory_region); - auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions, MemoryState memory_state) { - auto vma = vm_manager.MapMemoryBlock(segment.addr, codeset->memory, - segment.offset, segment.size, memory_state).Unwrap(); + auto MapSegment = [&](CodeSet::Segment& segment, VMAPermission permissions, + MemoryState memory_state) { + auto vma = vm_manager + .MapMemoryBlock(segment.addr, codeset->memory, segment.offset, segment.size, + memory_state) + .Unwrap(); vm_manager.Reprotect(vma, permissions); misc_memory_used += segment.size; memory_region->used += segment.size; }; // Map CodeSet segments - MapSegment(codeset->code, VMAPermission::ReadExecute, MemoryState::Code); - MapSegment(codeset->rodata, VMAPermission::Read, MemoryState::Code); - MapSegment(codeset->data, VMAPermission::ReadWrite, MemoryState::Private); + MapSegment(codeset->code, VMAPermission::ReadExecute, MemoryState::Code); + MapSegment(codeset->rodata, VMAPermission::Read, MemoryState::Code); + MapSegment(codeset->data, VMAPermission::ReadWrite, MemoryState::Private); // Allocate and map stack - vm_manager.MapMemoryBlock(Memory::HEAP_VADDR_END - stack_size, - std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size, MemoryState::Locked - ).Unwrap(); + vm_manager + .MapMemoryBlock(Memory::HEAP_VADDR_END - stack_size, + std::make_shared<std::vector<u8>>(stack_size, 0), 0, stack_size, + MemoryState::Locked) + .Unwrap(); misc_memory_used += stack_size; memory_region->used += stack_size; @@ -143,7 +147,8 @@ VAddr Process::GetLinearHeapLimit() const { } ResultVal<VAddr> Process::HeapAllocate(VAddr target, u32 size, VMAPermission perms) { - if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END || target + size < target) { + if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END || + target + size < target) { return ERR_INVALID_ADDRESS; } @@ -166,7 +171,8 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u32 size, VMAPermission per } ASSERT(heap_end - heap_start == heap_memory->size()); - CASCADE_RESULT(auto vma, vm_manager.MapMemoryBlock(target, heap_memory, target - heap_start, size, MemoryState::Private)); + CASCADE_RESULT(auto vma, vm_manager.MapMemoryBlock(target, heap_memory, target - heap_start, + size, MemoryState::Private)); vm_manager.Reprotect(vma, perms); heap_used += size; @@ -176,7 +182,8 @@ ResultVal<VAddr> Process::HeapAllocate(VAddr target, u32 size, VMAPermission per } ResultCode Process::HeapFree(VAddr target, u32 size) { - if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END || target + size < target) { + if (target < Memory::HEAP_VADDR || target + size > Memory::HEAP_VADDR_END || + target + size < target) { return ERR_INVALID_ADDRESS; } @@ -185,7 +192,8 @@ ResultCode Process::HeapFree(VAddr target, u32 size) { } ResultCode result = vm_manager.UnmapRange(target, size); - if (result.IsError()) return result; + if (result.IsError()) + return result; heap_used -= size; memory_region->used -= size; @@ -203,8 +211,8 @@ ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission p target = heap_end; } - if (target < GetLinearHeapBase() || target + size > GetLinearHeapLimit() || - target > heap_end || target + size < target) { + if (target < GetLinearHeapBase() || target + size > GetLinearHeapLimit() || target > heap_end || + target + size < target) { return ERR_INVALID_ADDRESS; } @@ -220,7 +228,8 @@ ResultVal<VAddr> Process::LinearAllocate(VAddr target, u32 size, VMAPermission p // TODO(yuriks): As is, this lets processes map memory allocated by other processes from the // same region. It is unknown if or how the 3DS kernel checks against this. size_t offset = target - GetLinearHeapBase(); - CASCADE_RESULT(auto vma, vm_manager.MapMemoryBlock(target, linheap_memory, offset, size, MemoryState::Continuous)); + CASCADE_RESULT(auto vma, vm_manager.MapMemoryBlock(target, linheap_memory, offset, size, + MemoryState::Continuous)); vm_manager.Reprotect(vma, perms); linear_heap_used += size; @@ -248,7 +257,8 @@ ResultCode Process::LinearFree(VAddr target, u32 size) { } ResultCode result = vm_manager.UnmapRange(target, size); - if (result.IsError()) return result; + if (result.IsError()) + return result; linear_heap_used -= size; memory_region->used -= size; @@ -272,5 +282,4 @@ Kernel::Process::Process() {} Kernel::Process::~Process() {} SharedPtr<Process> g_current_process; - } diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index d781ef32c..b566950b0 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -8,12 +8,9 @@ #include <cstddef> #include <memory> #include <string> - #include <boost/container/static_vector.hpp> - #include "common/bit_field.h" #include "common/common_types.h" - #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/vm_manager.h" @@ -36,15 +33,18 @@ enum class MemoryRegion : u16 { union ProcessFlags { u16 raw; - BitField< 0, 1, u16> allow_debug; ///< Allows other processes to attach to and debug this process. - BitField< 1, 1, u16> force_debug; ///< Allows this process to attach to processes even if they don't have allow_debug set. - BitField< 2, 1, u16> allow_nonalphanum; - BitField< 3, 1, u16> shared_page_writable; ///< Shared page is mapped with write permissions. - BitField< 4, 1, u16> privileged_priority; ///< Can use priority levels higher than 24. - BitField< 5, 1, u16> allow_main_args; - BitField< 6, 1, u16> shared_device_mem; - BitField< 7, 1, u16> runnable_on_sleep; - BitField< 8, 4, MemoryRegion> memory_region; ///< Default region for memory allocations for this process + BitField<0, 1, u16> + allow_debug; ///< Allows other processes to attach to and debug this process. + BitField<1, 1, u16> force_debug; ///< Allows this process to attach to processes even if they + /// don't have allow_debug set. + BitField<2, 1, u16> allow_nonalphanum; + BitField<3, 1, u16> shared_page_writable; ///< Shared page is mapped with write permissions. + BitField<4, 1, u16> privileged_priority; ///< Can use priority levels higher than 24. + BitField<5, 1, u16> allow_main_args; + BitField<6, 1, u16> shared_device_mem; + BitField<7, 1, u16> runnable_on_sleep; + BitField<8, 4, MemoryRegion> + memory_region; ///< Default region for memory allocations for this process BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000). }; @@ -54,11 +54,17 @@ struct MemoryRegionInfo; struct CodeSet final : public Object { static SharedPtr<CodeSet> Create(std::string name, u64 program_id); - std::string GetTypeName() const override { return "CodeSet"; } - std::string GetName() const override { return name; } + std::string GetTypeName() const override { + return "CodeSet"; + } + std::string GetName() const override { + return name; + } static const HandleType HANDLE_TYPE = HandleType::CodeSet; - HandleType GetHandleType() const override { return HANDLE_TYPE; } + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } /// Name of the process std::string name; @@ -85,11 +91,17 @@ class Process final : public Object { public: static SharedPtr<Process> Create(SharedPtr<CodeSet> code_set); - std::string GetTypeName() const override { return "Process"; } - std::string GetName() const override { return codeset->name; } + std::string GetTypeName() const override { + return "Process"; + } + std::string GetName() const override { + return codeset->name; + } static const HandleType HANDLE_TYPE = HandleType::Process; - HandleType GetHandleType() const override { return HANDLE_TYPE; } + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } static u32 next_process_id; @@ -124,7 +136,6 @@ public: */ void Run(s32 main_thread_priority, u32 stack_size); - /////////////////////////////////////////////////////////////////////////////////////////////// // Memory Management @@ -144,7 +155,8 @@ public: /// The Thread Local Storage area is allocated as processes create threads, /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part - /// holds the TLS for a specific thread. This vector contains which parts are in use for each page as a bitmask. + /// holds the TLS for a specific thread. This vector contains which parts are in use for each + /// page as a bitmask. /// This vector will grow as more pages are allocated for new threads. std::vector<std::bitset<8>> tls_slots; @@ -164,5 +176,4 @@ private: }; extern SharedPtr<Process> g_current_process; - } diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp index 67dde08c2..253ab7045 100644 --- a/src/core/hle/kernel/resource_limit.cpp +++ b/src/core/hle/kernel/resource_limit.cpp @@ -3,9 +3,7 @@ // Refer to the license.txt file included. #include <cstring> - #include "common/logging/log.h" - #include "core/hle/kernel/resource_limit.h" namespace Kernel { @@ -23,70 +21,69 @@ SharedPtr<ResourceLimit> ResourceLimit::Create(std::string name) { } SharedPtr<ResourceLimit> ResourceLimit::GetForCategory(ResourceLimitCategory category) { - switch (category) - { - case ResourceLimitCategory::APPLICATION: - case ResourceLimitCategory::SYS_APPLET: - case ResourceLimitCategory::LIB_APPLET: - case ResourceLimitCategory::OTHER: - return resource_limits[static_cast<u8>(category)]; - default: - LOG_CRITICAL(Kernel, "Unknown resource limit category"); - UNREACHABLE(); + switch (category) { + case ResourceLimitCategory::APPLICATION: + case ResourceLimitCategory::SYS_APPLET: + case ResourceLimitCategory::LIB_APPLET: + case ResourceLimitCategory::OTHER: + return resource_limits[static_cast<u8>(category)]; + default: + LOG_CRITICAL(Kernel, "Unknown resource limit category"); + UNREACHABLE(); } } s32 ResourceLimit::GetCurrentResourceValue(u32 resource) const { switch (resource) { - case COMMIT: - return current_commit; - case THREAD: - return current_threads; - case EVENT: - return current_events; - case MUTEX: - return current_mutexes; - case SEMAPHORE: - return current_semaphores; - case TIMER: - return current_timers; - case SHARED_MEMORY: - return current_shared_mems; - case ADDRESS_ARBITER: - return current_address_arbiters; - case CPU_TIME: - return current_cpu_time; - default: - LOG_ERROR(Kernel, "Unknown resource type=%08X", resource); - UNIMPLEMENTED(); - return 0; + case COMMIT: + return current_commit; + case THREAD: + return current_threads; + case EVENT: + return current_events; + case MUTEX: + return current_mutexes; + case SEMAPHORE: + return current_semaphores; + case TIMER: + return current_timers; + case SHARED_MEMORY: + return current_shared_mems; + case ADDRESS_ARBITER: + return current_address_arbiters; + case CPU_TIME: + return current_cpu_time; + default: + LOG_ERROR(Kernel, "Unknown resource type=%08X", resource); + UNIMPLEMENTED(); + return 0; } } s32 ResourceLimit::GetMaxResourceValue(u32 resource) const { switch (resource) { - case COMMIT: - return max_commit; - case THREAD: - return max_threads; - case EVENT: - return max_events; - case MUTEX: - return max_mutexes; - case SEMAPHORE: - return max_semaphores; - case TIMER: - return max_timers; - case SHARED_MEMORY: - return max_shared_mems; - case ADDRESS_ARBITER: - return max_address_arbiters; - case CPU_TIME: - return max_cpu_time; - default: - LOG_ERROR(Kernel, "Unknown resource type=%08X", resource); - UNIMPLEMENTED(); - return 0; + case COMMIT: + return max_commit; + case THREAD: + return max_threads; + case EVENT: + return max_events; + case MUTEX: + return max_mutexes; + case SEMAPHORE: + return max_semaphores; + case TIMER: + return max_timers; + case SHARED_MEMORY: + return max_shared_mems; + case ADDRESS_ARBITER: + return max_address_arbiters; + case CPU_TIME: + return max_cpu_time; + default: + LOG_ERROR(Kernel, "Unknown resource type=%08X", resource); + UNIMPLEMENTED(); + return 0; } } @@ -149,8 +146,6 @@ void ResourceLimitsInit() { resource_limits[static_cast<u8>(ResourceLimitCategory::OTHER)] = resource_limit; } -void ResourceLimitsShutdown() { - -} +void ResourceLimitsShutdown() {} } // namespace diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h index 1b8249c74..6cdfbcf8d 100644 --- a/src/core/hle/kernel/resource_limit.h +++ b/src/core/hle/kernel/resource_limit.h @@ -5,29 +5,28 @@ #pragma once #include "common/common_types.h" - #include "core/hle/kernel/kernel.h" namespace Kernel { enum class ResourceLimitCategory : u8 { APPLICATION = 0, - SYS_APPLET = 1, - LIB_APPLET = 2, - OTHER = 3 + SYS_APPLET = 1, + LIB_APPLET = 2, + OTHER = 3 }; enum ResourceTypes { - PRIORITY = 0, - COMMIT = 1, - THREAD = 2, - EVENT = 3, - MUTEX = 4, - SEMAPHORE = 5, - TIMER = 6, - SHARED_MEMORY = 7, - ADDRESS_ARBITER = 8, - CPU_TIME = 9, + PRIORITY = 0, + COMMIT = 1, + THREAD = 2, + EVENT = 3, + MUTEX = 4, + SEMAPHORE = 5, + TIMER = 6, + SHARED_MEMORY = 7, + ADDRESS_ARBITER = 8, + CPU_TIME = 9, }; class ResourceLimit final : public Object { @@ -44,11 +43,17 @@ public: */ static SharedPtr<ResourceLimit> GetForCategory(ResourceLimitCategory category); - std::string GetTypeName() const override { return "ResourceLimit"; } - std::string GetName() const override { return name; } + std::string GetTypeName() const override { + return "ResourceLimit"; + } + std::string GetName() const override { + return name; + } static const HandleType HANDLE_TYPE = HandleType::ResourceLimit; - HandleType GetHandleType() const override { return HANDLE_TYPE; } + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } /** * Gets the current value for the specified resource. @@ -85,10 +90,12 @@ public: /// Max CPU time that the processes in this category can utilize s32 max_cpu_time = 0; - // TODO(Subv): Increment these in their respective Kernel::T::Create functions, keeping in mind that - // APPLICATION resource limits should not be affected by the objects created by service modules. + // TODO(Subv): Increment these in their respective Kernel::T::Create functions, keeping in mind + // that APPLICATION resource limits should not be affected by the objects created by service + // modules. // Currently we have no way of distinguishing if a Create was called by the running application, - // or by a service module. Approach this once we have separated the service modules into their own processes + // or by a service module. Approach this once we have separated the service modules into their + // own processes /// Current memory that the processes in this category are using s32 current_commit = 0; diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp index 4b359ed07..bf7600780 100644 --- a/src/core/hle/kernel/semaphore.cpp +++ b/src/core/hle/kernel/semaphore.cpp @@ -3,7 +3,6 @@ // Refer to the license.txt file included. #include "common/assert.h" - #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/semaphore.h" #include "core/hle/kernel/thread.h" @@ -14,7 +13,7 @@ Semaphore::Semaphore() {} Semaphore::~Semaphore() {} ResultVal<SharedPtr<Semaphore>> Semaphore::Create(s32 initial_count, s32 max_count, - std::string name) { + std::string name) { if (initial_count > max_count) return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::Kernel, diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h index 390f5e495..e01908a25 100644 --- a/src/core/hle/kernel/semaphore.h +++ b/src/core/hle/kernel/semaphore.h @@ -6,9 +6,7 @@ #include <queue> #include <string> - #include "common/common_types.h" - #include "core/hle/kernel/kernel.h" namespace Kernel { @@ -23,17 +21,23 @@ public: * @return The created semaphore */ static ResultVal<SharedPtr<Semaphore>> Create(s32 initial_count, s32 max_count, - std::string name = "Unknown"); + std::string name = "Unknown"); - std::string GetTypeName() const override { return "Semaphore"; } - std::string GetName() const override { return name; } + std::string GetTypeName() const override { + return "Semaphore"; + } + std::string GetName() const override { + return name; + } static const HandleType HANDLE_TYPE = HandleType::Semaphore; - HandleType GetHandleType() const override { return HANDLE_TYPE; } + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } - s32 max_count; ///< Maximum number of simultaneous holders the semaphore can have - s32 available_count; ///< Number of free slots left in the semaphore - std::string name; ///< Name of semaphore (optional) + s32 max_count; ///< Maximum number of simultaneous holders the semaphore can have + s32 available_count; ///< Number of free slots left in the semaphore + std::string name; ///< Name of semaphore (optional) bool ShouldWait() override; void Acquire() override; diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index fcc684a20..8e3ec8a14 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp @@ -3,9 +3,7 @@ // Refer to the license.txt file included. #include <tuple> - #include "common/assert.h" - #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/server_port.h" @@ -25,7 +23,9 @@ void ServerPort::Acquire() { ASSERT_MSG(!ShouldWait(), "object unavailable!"); } -std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> ServerPort::CreatePortPair(u32 max_sessions, std::string name) { +std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> ServerPort::CreatePortPair( + u32 max_sessions, std::string name) { + SharedPtr<ServerPort> server_port(new ServerPort); SharedPtr<ClientPort> client_port(new ClientPort); diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h index e9c972ce6..fa9448ca0 100644 --- a/src/core/hle/kernel/server_port.h +++ b/src/core/hle/kernel/server_port.h @@ -6,9 +6,7 @@ #include <string> #include <tuple> - #include "common/common_types.h" - #include "core/hle/kernel/kernel.h" namespace Kernel { @@ -23,17 +21,25 @@ public: * @param name Optional name of the ports * @return The created port tuple */ - static std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> CreatePortPair(u32 max_sessions, std::string name = "UnknownPort"); + static std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> CreatePortPair( + u32 max_sessions, std::string name = "UnknownPort"); - std::string GetTypeName() const override { return "ServerPort"; } - std::string GetName() const override { return name; } + std::string GetTypeName() const override { + return "ServerPort"; + } + std::string GetName() const override { + return name; + } static const HandleType HANDLE_TYPE = HandleType::ServerPort; - HandleType GetHandleType() const override { return HANDLE_TYPE; } + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } - std::string name; ///< Name of port (optional) + std::string name; ///< Name of port (optional) - std::vector<SharedPtr<WaitObject>> pending_sessions; ///< ServerSessions waiting to be accepted by the port + std::vector<SharedPtr<WaitObject>> + pending_sessions; ///< ServerSessions waiting to be accepted by the port bool ShouldWait() override; void Acquire() override; diff --git a/src/core/hle/kernel/session.cpp b/src/core/hle/kernel/session.cpp index 0594967f8..8a2a7e3fd 100644 --- a/src/core/hle/kernel/session.cpp +++ b/src/core/hle/kernel/session.cpp @@ -9,5 +9,4 @@ namespace Kernel { Session::Session() {} Session::~Session() {} - } diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h index 8ec889967..ec025f732 100644 --- a/src/core/hle/kernel/session.h +++ b/src/core/hle/kernel/session.h @@ -5,10 +5,8 @@ #pragma once #include <string> - #include "common/assert.h" #include "common/common_types.h" - #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/thread.h" #include "core/hle/result.h" @@ -19,12 +17,13 @@ namespace IPC { enum DescriptorType : u32 { // Buffer related desciptors types (mask : 0x0F) StaticBuffer = 0x02, - PXIBuffer = 0x04, + PXIBuffer = 0x04, MappedBuffer = 0x08, - // Handle related descriptors types (mask : 0x30, but need to check for buffer related descriptors first ) - CopyHandle = 0x00, - MoveHandle = 0x10, - CallingPid = 0x20, + // Handle related descriptors types (mask : 0x30, but need to check for buffer related + // descriptors first ) + CopyHandle = 0x00, + MoveHandle = 0x10, + CallingPid = 0x20, }; /** @@ -34,24 +33,28 @@ enum DescriptorType : u32 { * @param translate_params_size Size of the translate parameters in words. Up to 63. * @return The created IPC header. * - * Normal parameters are sent directly to the process while the translate parameters might go through modifications and checks by the kernel. + * Normal parameters are sent directly to the process while the translate parameters might go + * through modifications and checks by the kernel. * The translate parameters are described by headers generated with the IPC::*Desc functions. * - * @note While #normal_params is equivalent to the number of normal parameters, #translate_params_size includes the size occupied by the translate parameters headers. + * @note While #normal_params is equivalent to the number of normal parameters, + * #translate_params_size includes the size occupied by the translate parameters headers. */ -constexpr u32 MakeHeader(u16 command_id, unsigned int normal_params, unsigned int translate_params_size) { - return (u32(command_id) << 16) | ((u32(normal_params) & 0x3F) << 6) | (u32(translate_params_size) & 0x3F); +constexpr u32 MakeHeader(u16 command_id, unsigned int normal_params, + unsigned int translate_params_size) { + return (u32(command_id) << 16) | ((u32(normal_params) & 0x3F) << 6) | + (u32(translate_params_size) & 0x3F); } union Header { u32 raw; - BitField< 0, 6, u32> translate_params_size; - BitField< 6, 6, u32> normal_params; + BitField<0, 6, u32> translate_params_size; + BitField<6, 6, u32> normal_params; BitField<16, 16, u32> command_id; }; inline Header ParseHeader(u32 header) { - return{ header }; + return {header}; } constexpr u32 MoveHandleDesc(u32 num_handles = 1) { @@ -80,27 +83,29 @@ constexpr u32 StaticBufferDesc(u32 size, u8 buffer_id) { union StaticBufferDescInfo { u32 raw; - BitField< 10, 4, u32> buffer_id; - BitField< 14, 18, u32> size; + BitField<10, 4, u32> buffer_id; + BitField<14, 18, u32> size; }; inline StaticBufferDescInfo ParseStaticBufferDesc(const u32 desc) { - return{ desc }; + return {desc}; } /** * @brief Creates a header describing a buffer to be sent over PXI. * @param size Size of the buffer. Max 0x00FFFFFF. * @param buffer_id The Id of the buffer. Max 0xF. - * @param is_read_only true if the buffer is read-only. If false, the buffer is considered to have read-write access. + * @param is_read_only true if the buffer is read-only. If false, the buffer is considered to have + * read-write access. * @return The created PXI buffer header. * * The next value is a phys-address of a table located in the BASE memregion. */ inline u32 PXIBufferDesc(u32 size, unsigned buffer_id, bool is_read_only) { u32 type = PXIBuffer; - if (is_read_only) type |= 0x2; - return type | (size << 8) | ((buffer_id & 0xF) << 4); + if (is_read_only) + type |= 0x2; + return type | (size << 8) | ((buffer_id & 0xF) << 4); } enum MappedBufferPermissions { @@ -115,12 +120,12 @@ constexpr u32 MappedBufferDesc(u32 size, MappedBufferPermissions perms) { union MappedBufferDescInfo { u32 raw; - BitField< 4, 28, u32> size; - BitField< 1, 2, MappedBufferPermissions> perms; + BitField<4, 28, u32> size; + BitField<1, 2, MappedBufferPermissions> perms; }; inline MappedBufferDescInfo ParseMappedBufferDesc(const u32 desc) { - return{ desc }; + return {desc}; } inline DescriptorType GetDescriptorType(u32 descriptor) { @@ -153,7 +158,8 @@ static const int kCommandHeaderOffset = 0x80; ///< Offset into command buffer of * @return Pointer to command buffer */ inline u32* GetCommandBuffer(const int offset = 0) { - return (u32*)Memory::GetPointer(GetCurrentThread()->GetTLSAddress() + kCommandHeaderOffset + offset); + return (u32*)Memory::GetPointer(GetCurrentThread()->GetTLSAddress() + kCommandHeaderOffset + + offset); } /** @@ -183,10 +189,14 @@ public: Session(); ~Session() override; - std::string GetTypeName() const override { return "Session"; } + std::string GetTypeName() const override { + return "Session"; + } static const HandleType HANDLE_TYPE = HandleType::Session; - HandleType GetHandleType() const override { return HANDLE_TYPE; } + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } /** * Handles a synchronous call to this session using HLE emulation. Emulated <-> emulated calls @@ -205,5 +215,4 @@ public: ASSERT_MSG(!ShouldWait(), "object unavailable!"); } }; - } diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 6a22c8986..bc1560d12 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -3,20 +3,20 @@ // Refer to the license.txt file included. #include <cstring> - #include "common/logging/log.h" - -#include "core/memory.h" #include "core/hle/kernel/memory.h" #include "core/hle/kernel/shared_memory.h" +#include "core/memory.h" namespace Kernel { SharedMemory::SharedMemory() {} SharedMemory::~SharedMemory() {} -SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u32 size, MemoryPermission permissions, - MemoryPermission other_permissions, VAddr address, MemoryRegion region, std::string name) { +SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u32 size, + MemoryPermission permissions, + MemoryPermission other_permissions, VAddr address, + MemoryRegion region, std::string name) { SharedPtr<SharedMemory> shared_memory(new SharedMemory); shared_memory->owner_process = owner_process; @@ -31,7 +31,8 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u MemoryRegionInfo* memory_region = GetMemoryRegion(region); auto& linheap_memory = memory_region->linear_heap_memory; - ASSERT_MSG(linheap_memory->size() + size <= memory_region->size, "Not enough space in region to allocate shared memory!"); + ASSERT_MSG(linheap_memory->size() + size <= memory_region->size, + "Not enough space in region to allocate shared memory!"); shared_memory->backing_block = linheap_memory; shared_memory->backing_block_offset = linheap_memory->size(); @@ -39,7 +40,8 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u linheap_memory->insert(linheap_memory->end(), size, 0); memory_region->used += size; - shared_memory->linear_heap_phys_address = Memory::FCRAM_PADDR + memory_region->base + shared_memory->backing_block_offset; + shared_memory->linear_heap_phys_address = + Memory::FCRAM_PADDR + memory_region->base + shared_memory->backing_block_offset; // Increase the amount of used linear heap memory for the owner process. if (shared_memory->owner_process != nullptr) { @@ -51,18 +53,20 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u Kernel::g_current_process->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get()); } } else { - // TODO(Subv): What happens if an application tries to create multiple memory blocks pointing to the same address? + // TODO(Subv): What happens if an application tries to create multiple memory blocks + // pointing to the same address? auto& vm_manager = shared_memory->owner_process->vm_manager; // The memory is already available and mapped in the owner process. auto vma = vm_manager.FindVMA(address)->second; // Copy it over to our own storage - shared_memory->backing_block = std::make_shared<std::vector<u8>>(vma.backing_block->data() + vma.offset, - vma.backing_block->data() + vma.offset + size); + shared_memory->backing_block = std::make_shared<std::vector<u8>>( + vma.backing_block->data() + vma.offset, vma.backing_block->data() + vma.offset + size); shared_memory->backing_block_offset = 0; // Unmap the existing pages vm_manager.UnmapRange(address, size); // Map our own block into the address space - vm_manager.MapMemoryBlock(address, shared_memory->backing_block, 0, size, MemoryState::Shared); + vm_manager.MapMemoryBlock(address, shared_memory->backing_block, 0, size, + MemoryState::Shared); // Reprotect the block with the new permissions vm_manager.ReprotectRange(address, size, ConvertPermissions(permissions)); } @@ -71,8 +75,11 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u return shared_memory; } -SharedPtr<SharedMemory> SharedMemory::CreateForApplet(std::shared_ptr<std::vector<u8>> heap_block, u32 offset, u32 size, - MemoryPermission permissions, MemoryPermission other_permissions, std::string name) { +SharedPtr<SharedMemory> SharedMemory::CreateForApplet(std::shared_ptr<std::vector<u8>> heap_block, + u32 offset, u32 size, + MemoryPermission permissions, + MemoryPermission other_permissions, + std::string name) { SharedPtr<SharedMemory> shared_memory(new SharedMemory); shared_memory->owner_process = nullptr; @@ -88,27 +95,31 @@ SharedPtr<SharedMemory> SharedMemory::CreateForApplet(std::shared_ptr<std::vecto } ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermission permissions, - MemoryPermission other_permissions) { + MemoryPermission other_permissions) { - MemoryPermission own_other_permissions = target_process == owner_process ? this->permissions : this->other_permissions; + MemoryPermission own_other_permissions = + target_process == owner_process ? this->permissions : this->other_permissions; // Automatically allocated memory blocks can only be mapped with other_permissions = DontCare if (base_address == 0 && other_permissions != MemoryPermission::DontCare) { - return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); + return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS, + ErrorSummary::InvalidArgument, ErrorLevel::Usage); } // Error out if the requested permissions don't match what the creator process allows. if (static_cast<u32>(permissions) & ~static_cast<u32>(own_other_permissions)) { LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s, permissions don't match", GetObjectId(), address, name.c_str()); - return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); + return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS, + ErrorSummary::InvalidArgument, ErrorLevel::Usage); } // Heap-backed memory blocks can not be mapped with other_permissions = DontCare if (base_address != 0 && other_permissions == MemoryPermission::DontCare) { LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s, permissions don't match", GetObjectId(), address, name.c_str()); - return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); + return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS, + ErrorSummary::InvalidArgument, ErrorLevel::Usage); } // Error out if the provided permissions are not compatible with what the creator process needs. @@ -116,12 +127,14 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi static_cast<u32>(this->permissions) & ~static_cast<u32>(other_permissions)) { LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s, permissions don't match", GetObjectId(), address, name.c_str()); - return ResultCode(ErrorDescription::WrongPermission, ErrorModule::OS, ErrorSummary::WrongArgument, ErrorLevel::Permanent); + return ResultCode(ErrorDescription::WrongPermission, ErrorModule::OS, + ErrorSummary::WrongArgument, ErrorLevel::Permanent); } // TODO(Subv): Check for the Shared Device Mem flag in the creator process. /*if (was_created_with_shared_device_mem && address != 0) { - return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); + return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS, + ErrorSummary::InvalidArgument, ErrorLevel::Usage); }*/ // TODO(Subv): The same process that created a SharedMemory object @@ -144,23 +157,29 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi } // Map the memory block into the target process - auto result = target_process->vm_manager.MapMemoryBlock(target_address, backing_block, backing_block_offset, size, MemoryState::Shared); + auto result = target_process->vm_manager.MapMemoryBlock( + target_address, backing_block, backing_block_offset, size, MemoryState::Shared); if (result.Failed()) { - LOG_ERROR(Kernel, "cannot map id=%u, target_address=0x%08X name=%s, error mapping to virtual memory", - GetObjectId(), target_address, name.c_str()); + LOG_ERROR( + Kernel, + "cannot map id=%u, target_address=0x%08X name=%s, error mapping to virtual memory", + GetObjectId(), target_address, name.c_str()); return result.Code(); } - return target_process->vm_manager.ReprotectRange(target_address, size, ConvertPermissions(permissions)); + return target_process->vm_manager.ReprotectRange(target_address, size, + ConvertPermissions(permissions)); } ResultCode SharedMemory::Unmap(Process* target_process, VAddr address) { - // TODO(Subv): Verify what happens if the application tries to unmap an address that is not mapped to a SharedMemory. + // TODO(Subv): Verify what happens if the application tries to unmap an address that is not + // mapped to a SharedMemory. return target_process->vm_manager.UnmapRange(address, size); } VMAPermission SharedMemory::ConvertPermissions(MemoryPermission permission) { - u32 masked_permissions = static_cast<u32>(permission) & static_cast<u32>(MemoryPermission::ReadWriteExecute); + u32 masked_permissions = + static_cast<u32>(permission) & static_cast<u32>(MemoryPermission::ReadWriteExecute); return static_cast<VMAPermission>(masked_permissions); }; diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index 0c404a9f8..94b335ed1 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -5,9 +5,7 @@ #pragma once #include <string> - #include "common/common_types.h" - #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/process.h" #include "core/hle/result.h" @@ -16,15 +14,15 @@ namespace Kernel { /// Permissions for mapped shared memory blocks enum class MemoryPermission : u32 { - None = 0, - Read = (1u << 0), - Write = (1u << 1), - ReadWrite = (Read | Write), - Execute = (1u << 2), - ReadExecute = (Read | Execute), - WriteExecute = (Write | Execute), + None = 0, + Read = (1u << 0), + Write = (1u << 1), + ReadWrite = (Read | Write), + Execute = (1u << 2), + ReadExecute = (Read | Execute), + WriteExecute = (Write | Execute), ReadWriteExecute = (Read | Write | Execute), - DontCare = (1u << 28) + DontCare = (1u << 28) }; class SharedMemory final : public Object { @@ -34,13 +32,18 @@ public: * @param owner_process Process that created this shared memory object. * @param size Size of the memory block. Must be page-aligned. * @param permissions Permission restrictions applied to the process which created the block. - * @param other_permissions Permission restrictions applied to other processes mapping the block. + * @param other_permissions Permission restrictions applied to other processes mapping the + * block. * @param address The address from which to map the Shared Memory. - * @param region If the address is 0, the shared memory will be allocated in this region of the linear heap. + * @param region If the address is 0, the shared memory will be allocated in this region of the + * linear heap. * @param name Optional object name, used for debugging purposes. */ - static SharedPtr<SharedMemory> Create(SharedPtr<Process> owner_process, u32 size, MemoryPermission permissions, - MemoryPermission other_permissions, VAddr address = 0, MemoryRegion region = MemoryRegion::BASE, std::string name = "Unknown"); + static SharedPtr<SharedMemory> Create(SharedPtr<Process> owner_process, u32 size, + MemoryPermission permissions, + MemoryPermission other_permissions, VAddr address = 0, + MemoryRegion region = MemoryRegion::BASE, + std::string name = "Unknown"); /** * Creates a shared memory object from a block of memory managed by an HLE applet. @@ -48,17 +51,27 @@ public: * @param offset The offset into the heap block that the SharedMemory will map. * @param size Size of the memory block. Must be page-aligned. * @param permissions Permission restrictions applied to the process which created the block. - * @param other_permissions Permission restrictions applied to other processes mapping the block. + * @param other_permissions Permission restrictions applied to other processes mapping the + * block. * @param name Optional object name, used for debugging purposes. */ - static SharedPtr<SharedMemory> CreateForApplet(std::shared_ptr<std::vector<u8>> heap_block, u32 offset, u32 size, - MemoryPermission permissions, MemoryPermission other_permissions, std::string name = "Unknown Applet"); - - std::string GetTypeName() const override { return "SharedMemory"; } - std::string GetName() const override { return name; } + static SharedPtr<SharedMemory> CreateForApplet(std::shared_ptr<std::vector<u8>> heap_block, + u32 offset, u32 size, + MemoryPermission permissions, + MemoryPermission other_permissions, + std::string name = "Unknown Applet"); + + std::string GetTypeName() const override { + return "SharedMemory"; + } + std::string GetName() const override { + return name; + } static const HandleType HANDLE_TYPE = HandleType::SharedMemory; - HandleType GetHandleType() const override { return HANDLE_TYPE; } + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } /** * Converts the specified MemoryPermission into the equivalent VMAPermission. @@ -73,7 +86,8 @@ public: * @param permissions Memory block map permissions (specified by SVC field) * @param other_permissions Memory block map other permissions (specified by SVC field) */ - ResultCode Map(Process* target_process, VAddr address, MemoryPermission permissions, MemoryPermission other_permissions); + ResultCode Map(Process* target_process, VAddr address, MemoryPermission permissions, + MemoryPermission other_permissions); /** * Unmaps a shared memory block from the specified address in system memory @@ -94,7 +108,8 @@ public: SharedPtr<Process> owner_process; /// Address of shared memory block in the owner process if specified. VAddr base_address; - /// Physical address of the shared memory block in the linear heap if no address was specified during creation. + /// Physical address of the shared memory block in the linear heap if no address was specified + /// during creation. PAddr linear_heap_phys_address; /// Backing memory for this shared memory block. std::shared_ptr<std::vector<u8>> backing_block; diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index f1e5cf3cb..4486a812c 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -5,23 +5,21 @@ #include <algorithm> #include <list> #include <vector> - #include "common/assert.h" #include "common/common_types.h" #include "common/logging/log.h" #include "common/math_util.h" #include "common/thread_queue_list.h" - #include "core/arm/arm_interface.h" #include "core/arm/skyeye_common/armstate.h" #include "core/core.h" #include "core/core_timing.h" #include "core/hle/hle.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/process.h" -#include "core/hle/kernel/thread.h" #include "core/hle/kernel/memory.h" #include "core/hle/kernel/mutex.h" +#include "core/hle/kernel/process.h" +#include "core/hle/kernel/thread.h" #include "core/hle/result.h" #include "core/memory.h" @@ -46,7 +44,7 @@ static Kernel::HandleTable wakeup_callback_handle_table; static std::vector<SharedPtr<Thread>> thread_list; // Lists only ready thread ids. -static Common::ThreadQueueList<Thread*, THREADPRIO_LOWEST+1> ready_queue; +static Common::ThreadQueueList<Thread*, THREADPRIO_LOWEST + 1> ready_queue; static Thread* current_thread; @@ -103,7 +101,7 @@ void Thread::Stop() { // Clean up thread from ready queue // This is only needed when the thread is termintated forcefully (SVC TerminateProcess) - if (status == THREADSTATUS_READY){ + if (status == THREADSTATUS_READY) { ready_queue.remove(current_priority, this); } @@ -119,7 +117,8 @@ void Thread::Stop() { // Mark the TLS slot in the thread's page as free. u32 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE; - u32 tls_slot = ((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE; + u32 tls_slot = + ((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE; Kernel::g_current_process->tls_slots[tls_page].reset(tls_slot); HLE::Reschedule(__func__); @@ -137,7 +136,7 @@ Thread* ArbitrateHighestPriorityThread(u32 address) { if (thread == nullptr) continue; - if(thread->current_priority <= priority) { + if (thread->current_priority <= priority) { highest_priority_thread = thread.get(); priority = thread->current_priority; } @@ -170,7 +169,7 @@ static void PriorityBoostStarvedThreads() { // on hardware. However, this is almost certainly not perfect, and the real CTR OS scheduler // should probably be reversed to verify this. - const u64 boost_timeout = 2000000; // Boost threads that have been ready for > this long + const u64 boost_timeout = 2000000; // Boost threads that have been ready for > this long u64 delta = current_ticks - thread->last_running_ticks; @@ -193,10 +192,12 @@ static std::tuple<u32*, u32*> GetWaitSynchTimeoutParameterRegister(Thread* threa if ((thumb_mode && thumb_inst == 0xDF24) || (!thumb_mode && inst == 0x0F000024)) { // svc #0x24 (WaitSynchronization1) - return std::make_tuple(&thread->context.cpu_registers[2], &thread->context.cpu_registers[3]); + return std::make_tuple(&thread->context.cpu_registers[2], + &thread->context.cpu_registers[3]); } else if ((thumb_mode && thumb_inst == 0xDF25) || (!thumb_mode && inst == 0x0F000025)) { // svc #0x25 (WaitSynchronizationN) - return std::make_tuple(&thread->context.cpu_registers[0], &thread->context.cpu_registers[4]); + return std::make_tuple(&thread->context.cpu_registers[0], + &thread->context.cpu_registers[4]); } UNREACHABLE(); @@ -245,7 +246,8 @@ static void SwitchContext(Thread* new_thread) { // Load context of new thread if (new_thread) { - DEBUG_ASSERT_MSG(new_thread->status == THREADSTATUS_READY, "Thread must be ready to become running."); + DEBUG_ASSERT_MSG(new_thread->status == THREADSTATUS_READY, + "Thread must be ready to become running."); // Cancel any outstanding wakeup events for this thread CoreTiming::UnscheduleEvent(ThreadWakeupEventType, new_thread->callback_handle); @@ -263,7 +265,7 @@ static void SwitchContext(Thread* new_thread) { new_thread->context.pc -= thumb_mode ? 2 : 4; // Get the register for timeout parameter - u32* timeout_low, *timeout_high; + u32 *timeout_low, *timeout_high; std::tie(timeout_low, timeout_high) = GetWaitSynchTimeoutParameterRegister(new_thread); // Update the timeout parameter @@ -307,7 +309,7 @@ static Thread* PopNextReadyThread() { // Otherwise just keep going with the current thread next = thread; } - } else { + } else { next = ready_queue.pop_first(); } @@ -321,7 +323,8 @@ void WaitCurrentThread_Sleep() { HLE::Reschedule(__func__); } -void WaitCurrentThread_WaitSynchronization(std::vector<SharedPtr<WaitObject>> wait_objects, bool wait_set_output, bool wait_all) { +void WaitCurrentThread_WaitSynchronization(std::vector<SharedPtr<WaitObject>> wait_objects, + bool wait_set_output, bool wait_all) { Thread* thread = GetCurrentThread(); thread->wait_set_output = wait_set_output; thread->wait_all = wait_all; @@ -352,7 +355,8 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) { if (thread->status == THREADSTATUS_WAIT_SYNCH || thread->status == THREADSTATUS_WAIT_ARB) { thread->SetWaitSynchronizationResult(ResultCode(ErrorDescription::Timeout, ErrorModule::OS, - ErrorSummary::StatusChanged, ErrorLevel::Info)); + ErrorSummary::StatusChanged, + ErrorLevel::Info)); if (thread->wait_set_output) thread->SetWaitSynchronizationOutput(-1); @@ -372,25 +376,25 @@ void Thread::WakeAfterDelay(s64 nanoseconds) { void Thread::ResumeFromWait() { switch (status) { - case THREADSTATUS_WAIT_SYNCH: - case THREADSTATUS_WAIT_ARB: - case THREADSTATUS_WAIT_SLEEP: - break; - - case THREADSTATUS_READY: - // If the thread is waiting on multiple wait objects, it might be awoken more than once - // before actually resuming. We can ignore subsequent wakeups if the thread status has - // already been set to THREADSTATUS_READY. - return; - - case THREADSTATUS_RUNNING: - DEBUG_ASSERT_MSG(false, "Thread with object id %u has already resumed.", GetObjectId()); - return; - case THREADSTATUS_DEAD: - // This should never happen, as threads must complete before being stopped. - DEBUG_ASSERT_MSG(false, "Thread with object id %u cannot be resumed because it's DEAD.", - GetObjectId()); - return; + case THREADSTATUS_WAIT_SYNCH: + case THREADSTATUS_WAIT_ARB: + case THREADSTATUS_WAIT_SLEEP: + break; + + case THREADSTATUS_READY: + // If the thread is waiting on multiple wait objects, it might be awoken more than once + // before actually resuming. We can ignore subsequent wakeups if the thread status has + // already been set to THREADSTATUS_READY. + return; + + case THREADSTATUS_RUNNING: + DEBUG_ASSERT_MSG(false, "Thread with object id %u has already resumed.", GetObjectId()); + return; + case THREADSTATUS_DEAD: + // This should never happen, as threads must complete before being stopped. + DEBUG_ASSERT_MSG(false, "Thread with object id %u cannot be resumed because it's DEAD.", + GetObjectId()); + return; } ready_queue.push_back(current_priority, this); @@ -405,7 +409,8 @@ static void DebugThreadQueue() { if (!thread) { LOG_DEBUG(Kernel, "Current: NO CURRENT THREAD"); } else { - LOG_DEBUG(Kernel, "0x%02X %u (current)", thread->current_priority, GetCurrentThread()->GetObjectId()); + LOG_DEBUG(Kernel, "0x%02X %u (current)", thread->current_priority, + GetCurrentThread()->GetObjectId()); } for (auto& t : thread_list) { @@ -448,7 +453,8 @@ std::tuple<u32, u32, bool> GetFreeThreadLocalSlot(std::vector<std::bitset<8>>& t * @param entry_point Address of entry point for execution * @param arg User argument for thread */ -static void ResetThreadContext(Core::ThreadContext& context, u32 stack_top, u32 entry_point, u32 arg) { +static void ResetThreadContext(Core::ThreadContext& context, u32 stack_top, u32 entry_point, + u32 arg) { memset(&context, 0, sizeof(Core::ThreadContext)); context.cpu_registers[0] = arg; @@ -458,11 +464,11 @@ static void ResetThreadContext(Core::ThreadContext& context, u32 stack_top, u32 } ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, s32 priority, - u32 arg, s32 processor_id, VAddr stack_top) { + u32 arg, s32 processor_id, VAddr stack_top) { if (priority < THREADPRIO_HIGHEST || priority > THREADPRIO_LOWEST) { s32 new_priority = MathUtil::Clamp<s32>(priority, THREADPRIO_HIGHEST, THREADPRIO_LOWEST); - LOG_WARNING(Kernel_SVC, "(name=%s): invalid priority=%d, clamping to %d", - name.c_str(), priority, new_priority); + LOG_WARNING(Kernel_SVC, "(name=%s): invalid priority=%d, clamping to %d", name.c_str(), + priority, new_priority); // TODO(bunnei): Clamping to a valid priority is not necessarily correct behavior... Confirm // validity of this priority = new_priority; @@ -472,7 +478,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, LOG_ERROR(Kernel_SVC, "(name=%s): invalid entry %08x", name.c_str(), entry_point); // TODO: Verify error return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, - ErrorSummary::InvalidArgument, ErrorLevel::Permanent); + ErrorSummary::InvalidArgument, ErrorLevel::Permanent); } SharedPtr<Thread> thread(new Thread); @@ -511,8 +517,10 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, auto& linheap_memory = memory_region->linear_heap_memory; if (linheap_memory->size() + Memory::PAGE_SIZE > memory_region->size) { - LOG_ERROR(Kernel_SVC, "Not enough space in region to allocate a new TLS page for thread"); - return ResultCode(ErrorDescription::OutOfMemory, ErrorModule::Kernel, ErrorSummary::OutOfResource, ErrorLevel::Permanent); + LOG_ERROR(Kernel_SVC, + "Not enough space in region to allocate a new TLS page for thread"); + return ResultCode(ErrorDescription::OutOfMemory, ErrorModule::Kernel, + ErrorSummary::OutOfResource, ErrorLevel::Permanent); } u32 offset = linheap_memory->size(); @@ -537,7 +545,8 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, // Mark the slot as used tls_slots[available_page].set(available_slot); - thread->tls_address = Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE + available_slot * Memory::TLS_ENTRY_SIZE; + thread->tls_address = Memory::TLS_AREA_VADDR + available_page * Memory::PAGE_SIZE + + available_slot * Memory::TLS_ENTRY_SIZE; // TODO(peachum): move to ScheduleThread() when scheduler is added so selected core is used // to initialize the context @@ -551,10 +560,12 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, return MakeResult<SharedPtr<Thread>>(std::move(thread)); } -// TODO(peachum): Remove this. Range checking should be done, and an appropriate error should be returned. +// TODO(peachum): Remove this. Range checking should be done, and an appropriate error should be +// returned. static void ClampPriority(const Thread* thread, s32* priority) { if (*priority < THREADPRIO_HIGHEST || *priority > THREADPRIO_LOWEST) { - DEBUG_ASSERT_MSG(false, "Application passed an out of range priority. An error should be returned."); + DEBUG_ASSERT_MSG( + false, "Application passed an out of range priority. An error should be returned."); s32 new_priority = MathUtil::Clamp<s32>(*priority, THREADPRIO_HIGHEST, THREADPRIO_LOWEST); LOG_WARNING(Kernel_SVC, "(name=%s): invalid priority=%d, clamping to %d", @@ -586,12 +597,13 @@ SharedPtr<Thread> SetupMainThread(u32 entry_point, s32 priority) { DEBUG_ASSERT(!GetCurrentThread()); // Initialize new "main" thread - auto thread_res = Thread::Create("main", entry_point, priority, 0, - THREADPROCESSORID_0, Memory::HEAP_VADDR_END); + auto thread_res = Thread::Create("main", entry_point, priority, 0, THREADPROCESSORID_0, + Memory::HEAP_VADDR_END); SharedPtr<Thread> thread = thread_res.MoveFrom(); - thread->context.fpscr = FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO | FPSCR_IXC; // 0x03C00010 + thread->context.fpscr = + FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO | FPSCR_IXC; // 0x03C00010 // Run new "main" thread SwitchContext(thread.get()); diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index deab5d5a6..f63131716 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -6,40 +6,36 @@ #include <string> #include <vector> - #include <boost/container/flat_set.hpp> - #include "common/common_types.h" - #include "core/core.h" - #include "core/hle/hle.h" #include "core/hle/kernel/kernel.h" #include "core/hle/result.h" -enum ThreadPriority : s32{ - THREADPRIO_HIGHEST = 0, ///< Highest thread priority - THREADPRIO_USERLAND_MAX = 24, ///< Highest thread priority for userland apps - THREADPRIO_DEFAULT = 48, ///< Default thread priority for userland apps - THREADPRIO_LOWEST = 63, ///< Lowest thread priority +enum ThreadPriority : s32 { + THREADPRIO_HIGHEST = 0, ///< Highest thread priority + THREADPRIO_USERLAND_MAX = 24, ///< Highest thread priority for userland apps + THREADPRIO_DEFAULT = 48, ///< Default thread priority for userland apps + THREADPRIO_LOWEST = 63, ///< Lowest thread priority }; enum ThreadProcessorId : s32 { - THREADPROCESSORID_DEFAULT = -2, ///< Run thread on default core specified by exheader - THREADPROCESSORID_ALL = -1, ///< Run thread on either core - THREADPROCESSORID_0 = 0, ///< Run thread on core 0 (AppCore) - THREADPROCESSORID_1 = 1, ///< Run thread on core 1 (SysCore) - THREADPROCESSORID_MAX = 2, ///< Processor ID must be less than this + THREADPROCESSORID_DEFAULT = -2, ///< Run thread on default core specified by exheader + THREADPROCESSORID_ALL = -1, ///< Run thread on either core + THREADPROCESSORID_0 = 0, ///< Run thread on core 0 (AppCore) + THREADPROCESSORID_1 = 1, ///< Run thread on core 1 (SysCore) + THREADPROCESSORID_MAX = 2, ///< Processor ID must be less than this }; enum ThreadStatus { - THREADSTATUS_RUNNING, ///< Currently running - THREADSTATUS_READY, ///< Ready to run - THREADSTATUS_WAIT_ARB, ///< Waiting on an address arbiter - THREADSTATUS_WAIT_SLEEP, ///< Waiting due to a SleepThread SVC - THREADSTATUS_WAIT_SYNCH, ///< Waiting due to a WaitSynchronization SVC - THREADSTATUS_DORMANT, ///< Created but not yet made ready - THREADSTATUS_DEAD ///< Run to completion, or forcefully terminated + THREADSTATUS_RUNNING, ///< Currently running + THREADSTATUS_READY, ///< Ready to run + THREADSTATUS_WAIT_ARB, ///< Waiting on an address arbiter + THREADSTATUS_WAIT_SLEEP, ///< Waiting due to a SleepThread SVC + THREADSTATUS_WAIT_SYNCH, ///< Waiting due to a WaitSynchronization SVC + THREADSTATUS_DORMANT, ///< Created but not yet made ready + THREADSTATUS_DEAD ///< Run to completion, or forcefully terminated }; namespace Kernel { @@ -60,13 +56,19 @@ public: * @return A shared pointer to the newly created thread */ static ResultVal<SharedPtr<Thread>> Create(std::string name, VAddr entry_point, s32 priority, - u32 arg, s32 processor_id, VAddr stack_top); + u32 arg, s32 processor_id, VAddr stack_top); - std::string GetName() const override { return name; } - std::string GetTypeName() const override { return "Thread"; } + std::string GetName() const override { + return name; + } + std::string GetTypeName() const override { + return "Thread"; + } static const HandleType HANDLE_TYPE = HandleType::Thread; - HandleType GetHandleType() const override { return HANDLE_TYPE; } + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } bool ShouldWait() override; void Acquire() override; @@ -75,7 +77,9 @@ public: * Gets the thread's current priority * @return The current thread's priority */ - s32 GetPriority() const { return current_priority; } + s32 GetPriority() const { + return current_priority; + } /** * Sets the thread's current priority @@ -93,7 +97,9 @@ public: * Gets the thread's thread ID * @return The thread's ID */ - u32 GetThreadId() const { return thread_id; } + u32 GetThreadId() const { + return thread_id; + } /** * Resumes a thread from waiting @@ -127,7 +133,9 @@ public: * Returns the Thread Local Storage address of the current thread * @returns VAddr of the thread's TLS */ - VAddr GetTLSAddress() const { return tls_address; } + VAddr GetTLSAddress() const { + return tls_address; + } Core::ThreadContext context; @@ -137,8 +145,8 @@ public: u32 entry_point; u32 stack_top; - s32 nominal_priority; ///< Nominal thread priority, as set by the emulated application - s32 current_priority; ///< Current thread priority, can be temporarily changed + s32 nominal_priority; ///< Nominal thread priority, as set by the emulated application + s32 current_priority; ///< Current thread priority, can be temporarily changed u64 last_running_ticks; ///< CPU tick when thread was last running @@ -151,11 +159,11 @@ public: /// Mutexes currently held by this thread, which will be released when it exits. boost::container::flat_set<SharedPtr<Mutex>> held_mutexes; - SharedPtr<Process> owner_process; ///< Process that owns this thread + SharedPtr<Process> owner_process; ///< Process that owns this thread std::vector<SharedPtr<WaitObject>> wait_objects; ///< Objects that the thread is waiting on - VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address - bool wait_all; ///< True if the thread is waiting on all objects before resuming - bool wait_set_output; ///< True if the output parameter should be set on thread wakeup + VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address + bool wait_all; ///< True if the thread is waiting on all objects before resuming + bool wait_set_output; ///< True if the output parameter should be set on thread wakeup std::string name; @@ -205,10 +213,12 @@ void WaitCurrentThread_Sleep(); /** * Waits the current thread from a WaitSynchronization call * @param wait_objects Kernel objects that we are waiting on - * @param wait_set_output If true, set the output parameter on thread wakeup (for WaitSynchronizationN only) + * @param wait_set_output If true, set the output parameter on thread wakeup (for + * WaitSynchronizationN only) * @param wait_all If true, wait on all objects before resuming (for WaitSynchronizationN only) */ -void WaitCurrentThread_WaitSynchronization(std::vector<SharedPtr<WaitObject>> wait_objects, bool wait_set_output, bool wait_all); +void WaitCurrentThread_WaitSynchronization(std::vector<SharedPtr<WaitObject>> wait_objects, + bool wait_set_output, bool wait_all); /** * Waits the current thread from an ArbitrateAddress call diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index b8daaeede..a9f98223c 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -3,14 +3,12 @@ // Refer to the license.txt file included. #include <cinttypes> - #include "common/assert.h" #include "common/logging/log.h" - #include "core/core_timing.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/timer.h" #include "core/hle/kernel/thread.h" +#include "core/hle/kernel/timer.h" namespace Kernel { @@ -41,7 +39,7 @@ bool Timer::ShouldWait() { } void Timer::Acquire() { - ASSERT_MSG( !ShouldWait(), "object unavailable!"); + ASSERT_MSG(!ShouldWait(), "object unavailable!"); if (reset_type == ResetType::OneShot) signaled = false; @@ -55,8 +53,8 @@ void Timer::Set(s64 initial, s64 interval) { interval_delay = interval; u64 initial_microseconds = initial / 1000; - CoreTiming::ScheduleEvent(usToCycles(initial_microseconds), - timer_callback_event_type, callback_handle); + CoreTiming::ScheduleEvent(usToCycles(initial_microseconds), timer_callback_event_type, + callback_handle); HLE::Reschedule(__func__); } @@ -73,7 +71,8 @@ void Timer::Clear() { /// The timer callback event, called when a timer is fired static void TimerCallback(u64 timer_handle, int cycles_late) { - SharedPtr<Timer> timer = timer_callback_handle_table.Get<Timer>(static_cast<Handle>(timer_handle)); + SharedPtr<Timer> timer = + timer_callback_handle_table.Get<Timer>(static_cast<Handle>(timer_handle)); if (timer == nullptr) { LOG_CRITICAL(Kernel, "Callback fired for invalid timer %08" PRIx64, timer_handle); @@ -91,7 +90,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) { // Reschedule the timer with the interval delay u64 interval_microseconds = timer->interval_delay / 1000; CoreTiming::ScheduleEvent(usToCycles(interval_microseconds) - cycles_late, - timer_callback_event_type, timer_handle); + timer_callback_event_type, timer_handle); } } @@ -100,7 +99,6 @@ void TimersInit() { timer_callback_event_type = CoreTiming::RegisterEvent("TimerCallback", TimerCallback); } -void TimersShutdown() { -} +void TimersShutdown() {} } // namespace diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index b1db60e8f..59a77aad3 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h @@ -5,7 +5,6 @@ #pragma once #include "common/common_types.h" - #include "core/hle/kernel/event.h" #include "core/hle/kernel/kernel.h" @@ -21,19 +20,25 @@ public: */ static SharedPtr<Timer> Create(ResetType reset_type, std::string name = "Unknown"); - std::string GetTypeName() const override { return "Timer"; } - std::string GetName() const override { return name; } + std::string GetTypeName() const override { + return "Timer"; + } + std::string GetName() const override { + return name; + } static const HandleType HANDLE_TYPE = HandleType::Timer; - HandleType GetHandleType() const override { return HANDLE_TYPE; } + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } - ResetType reset_type; ///< The ResetType of this timer + ResetType reset_type; ///< The ResetType of this timer - bool signaled; ///< Whether the timer has been signaled or not - std::string name; ///< Name of timer (optional) + bool signaled; ///< Whether the timer has been signaled or not + std::string name; ///< Name of timer (optional) - u64 initial_delay; ///< The delay until the timer fires for the first time - u64 interval_delay; ///< The delay until the timer fires after the first time + u64 initial_delay; ///< The delay until the timer fires for the first time + u64 interval_delay; ///< The delay until the timer fires after the first time bool ShouldWait() override; void Acquire() override; diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 066146cff..6dd24f846 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp @@ -3,9 +3,7 @@ // Refer to the license.txt file included. #include <iterator> - #include "common/assert.h" - #include "core/hle/kernel/vm_manager.h" #include "core/memory.h" #include "core/memory_setup.h" @@ -15,8 +13,8 @@ namespace Kernel { static const char* GetMemoryStateName(MemoryState state) { static const char* names[] = { - "Free", "Reserved", "IO", "Static", "Code", "Private", "Shared", "Continuous", "Aliased", - "Alias", "AliasCode", "Locked", + "Free", "Reserved", "IO", "Static", "Code", "Private", + "Shared", "Continuous", "Aliased", "Alias", "AliasCode", "Locked", }; return names[(int)state]; @@ -24,13 +22,12 @@ static const char* GetMemoryStateName(MemoryState state) { bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const { ASSERT(base + size == next.base); - if (permissions != next.permissions || - meminfo_state != next.meminfo_state || - type != next.type) { + if (permissions != next.permissions || meminfo_state != next.meminfo_state || + type != next.type) { return false; } if (type == VMAType::AllocatedMemoryBlock && - (backing_block != next.backing_block || offset + size != next.offset)) { + (backing_block != next.backing_block || offset + size != next.offset)) { return false; } if (type == VMAType::BackingMemory && backing_memory + size != next.backing_memory) { @@ -70,7 +67,9 @@ VMManager::VMAHandle VMManager::FindVMA(VAddr target) const { } ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target, - std::shared_ptr<std::vector<u8>> block, size_t offset, u32 size, MemoryState state) { + std::shared_ptr<std::vector<u8>> block, + size_t offset, u32 size, + MemoryState state) { ASSERT(block != nullptr); ASSERT(offset + size <= block->size()); @@ -89,7 +88,8 @@ ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target, return MakeResult<VMAHandle>(MergeAdjacent(vma_handle)); } -ResultVal<VMManager::VMAHandle> VMManager::MapBackingMemory(VAddr target, u8 * memory, u32 size, MemoryState state) { +ResultVal<VMManager::VMAHandle> VMManager::MapBackingMemory(VAddr target, u8* memory, u32 size, + MemoryState state) { ASSERT(memory != nullptr); // This is the appropriately sized VMA that will turn into our allocation. @@ -106,7 +106,9 @@ ResultVal<VMManager::VMAHandle> VMManager::MapBackingMemory(VAddr target, u8 * m return MakeResult<VMAHandle>(MergeAdjacent(vma_handle)); } -ResultVal<VMManager::VMAHandle> VMManager::MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state, Memory::MMIORegionPointer mmio_handler) { +ResultVal<VMManager::VMAHandle> VMManager::MapMMIO(VAddr target, PAddr paddr, u32 size, + MemoryState state, + Memory::MMIORegionPointer mmio_handler) { // This is the appropriately sized VMA that will turn into our allocation. CASCADE_RESULT(VMAIter vma_handle, CarveVMA(target, size)); VirtualMemoryArea& final_vma = vma_handle->second; @@ -191,15 +193,16 @@ void VMManager::RefreshMemoryBlockMappings(const std::vector<u8>* block) { void VMManager::LogLayout(Log::Level log_level) const { for (const auto& p : vma_map) { const VirtualMemoryArea& vma = p.second; - LOG_GENERIC(Log::Class::Kernel, log_level, "%08X - %08X size: %8X %c%c%c %s", - vma.base, vma.base + vma.size, vma.size, - (u8)vma.permissions & (u8)VMAPermission::Read ? 'R' : '-', - (u8)vma.permissions & (u8)VMAPermission::Write ? 'W' : '-', - (u8)vma.permissions & (u8)VMAPermission::Execute ? 'X' : '-', GetMemoryStateName(vma.meminfo_state)); + LOG_GENERIC(Log::Class::Kernel, log_level, "%08X - %08X size: %8X %c%c%c %s", vma.base, + vma.base + vma.size, vma.size, + (u8)vma.permissions & (u8)VMAPermission::Read ? 'R' : '-', + (u8)vma.permissions & (u8)VMAPermission::Write ? 'W' : '-', + (u8)vma.permissions & (u8)VMAPermission::Execute ? 'X' : '-', + GetMemoryStateName(vma.meminfo_state)); } } -VMManager::VMAIter VMManager::StripIterConstness(const VMAHandle & iter) { +VMManager::VMAIter VMManager::StripIterConstness(const VMAHandle& iter) { // This uses a neat C++ trick to convert a const_iterator to a regular iterator, given // non-const access to its container. return vma_map.erase(iter, iter); // Erases an empty range of elements @@ -337,5 +340,4 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) { break; } } - } diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h index 91d40655b..9055664b2 100644 --- a/src/core/hle/kernel/vm_manager.h +++ b/src/core/hle/kernel/vm_manager.h @@ -7,21 +7,19 @@ #include <map> #include <memory> #include <vector> - #include "common/common_types.h" - #include "core/hle/result.h" #include "core/mmio.h" namespace Kernel { -const ResultCode ERR_INVALID_ADDRESS{ // 0xE0E01BF5 - ErrorDescription::InvalidAddress, ErrorModule::OS, - ErrorSummary::InvalidArgument, ErrorLevel::Usage}; +const ResultCode ERR_INVALID_ADDRESS{// 0xE0E01BF5 + ErrorDescription::InvalidAddress, ErrorModule::OS, + ErrorSummary::InvalidArgument, ErrorLevel::Usage}; -const ResultCode ERR_INVALID_ADDRESS_STATE{ // 0xE0A01BF5 - ErrorDescription::InvalidAddress, ErrorModule::OS, - ErrorSummary::InvalidState, ErrorLevel::Usage}; +const ResultCode ERR_INVALID_ADDRESS_STATE{// 0xE0A01BF5 + ErrorDescription::InvalidAddress, ErrorModule::OS, + ErrorSummary::InvalidState, ErrorLevel::Usage}; enum class VMAType : u8 { /// VMA represents an unmapped region of the address space. @@ -115,7 +113,8 @@ class VMManager final { // TODO(yuriks): Make page tables switchable to support multiple VMManagers public: /** - * The maximum amount of address space managed by the kernel. Addresses above this are never used. + * The maximum amount of address space managed by the kernel. Addresses above this are never + * used. * @note This is the limit used by the New 3DS kernel. Old 3DS used 0x20000000. */ static const u32 MAX_ADDRESS = 0x40000000; @@ -151,7 +150,7 @@ public: * @param state MemoryState tag to attach to the VMA. */ ResultVal<VMAHandle> MapMemoryBlock(VAddr target, std::shared_ptr<std::vector<u8>> block, - size_t offset, u32 size, MemoryState state); + size_t offset, u32 size, MemoryState state); /** * Maps an unmanaged host memory pointer at a given address. @@ -172,7 +171,8 @@ public: * @param state MemoryState tag to attach to the VMA. * @param mmio_handler The handler that will implement read and write for this MMIO region. */ - ResultVal<VMAHandle> MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state, Memory::MMIORegionPointer mmio_handler); + ResultVal<VMAHandle> MapMMIO(VAddr target, PAddr paddr, u32 size, MemoryState state, + Memory::MMIORegionPointer mmio_handler); /// Unmaps a range of addresses, splitting VMAs as necessary. ResultCode UnmapRange(VAddr target, u32 size); @@ -228,5 +228,4 @@ private: /// Updates the pages corresponding to this VMA so they match the VMA's attributes. void UpdatePageTableForVMA(const VirtualMemoryArea& vma); }; - } diff --git a/src/core/hle/result.h b/src/core/hle/result.h index 268a8dad2..7f8d8e00d 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h @@ -6,7 +6,6 @@ #include <new> #include <utility> - #include "common/assert.h" #include "common/bit_field.h" #include "common/common_funcs.h" @@ -26,7 +25,8 @@ enum class ErrorDescription : u32 { FS_InvalidOpenFlags = 230, FS_NotAFile = 250, FS_NotFormatted = 340, ///< This is used by the FS service when creating a SaveData archive - OutofRangeOrMisalignedAddress = 513, // TODO(purpasmart): Check if this name fits its actual usage + OutofRangeOrMisalignedAddress = + 513, // TODO(purpasmart): Check if this name fits its actual usage GPU_FirstInitialization = 519, FS_InvalidPath = 702, InvalidSection = 1000, @@ -168,15 +168,15 @@ enum class ErrorSummary : u32 { Success = 0, NothingHappened = 1, WouldBlock = 2, - OutOfResource = 3, ///< There are no more kernel resources (memory, table slots) to - ///< execute the operation. - NotFound = 4, ///< A file or resource was not found. + OutOfResource = 3, ///< There are no more kernel resources (memory, table slots) to + ///< execute the operation. + NotFound = 4, ///< A file or resource was not found. InvalidState = 5, - NotSupported = 6, ///< The operation is not supported or not implemented. - InvalidArgument = 7, ///< Returned when a passed argument is invalid in the current runtime - ///< context. (Invalid handle, out-of-bounds pointer or size, etc.) - WrongArgument = 8, ///< Returned when a passed argument is in an incorrect format for use - ///< with the function. (E.g. Invalid enum value) + NotSupported = 6, ///< The operation is not supported or not implemented. + InvalidArgument = 7, ///< Returned when a passed argument is invalid in the current runtime + ///< context. (Invalid handle, out-of-bounds pointer or size, etc.) + WrongArgument = 8, ///< Returned when a passed argument is in an incorrect format for use + ///< with the function. (E.g. Invalid enum value) Canceled = 9, StatusChanged = 10, Internal = 11, @@ -208,19 +208,24 @@ union ResultCode { BitField<21, 6, ErrorSummary> summary; BitField<27, 5, ErrorLevel> level; - // The last bit of `level` is checked by apps and the kernel to determine if a result code is an error + // The last bit of `level` is checked by apps and the kernel to determine if a result code is an + // error BitField<31, 1, u32> is_error; explicit ResultCode(u32 raw) : raw(raw) {} - ResultCode(ErrorDescription description_, ErrorModule module_, - ErrorSummary summary_, ErrorLevel level_) : raw(0) { + ResultCode(ErrorDescription description_, ErrorModule module_, ErrorSummary summary_, + ErrorLevel level_) + : raw(0) { description.Assign(description_); module.Assign(module_); summary.Assign(summary_); level.Assign(level_); } - ResultCode& operator=(const ResultCode& o) { raw = o.raw; return *this; } + ResultCode& operator=(const ResultCode& o) { + raw = o.raw; + return *this; + } bool IsSuccess() const { return is_error == 0; @@ -246,8 +251,8 @@ const ResultCode RESULT_SUCCESS(0); /// Might be returned instead of a dummy success for unimplemented APIs. inline ResultCode UnimplementedFunction(ErrorModule module) { - return ResultCode(ErrorDescription::NotImplemented, module, - ErrorSummary::NotSupported, ErrorLevel::Permanent); + return ResultCode(ErrorDescription::NotImplemented, module, ErrorSummary::NotSupported, + ErrorLevel::Permanent); } /** @@ -285,10 +290,9 @@ inline ResultCode UnimplementedFunction(ErrorModule module) { template <typename T> class ResultVal { public: - /// Constructs an empty `ResultVal` with the given error code. The code must not be a success code. - ResultVal(ResultCode error_code = ResultCode(-1)) - : result_code(error_code) - { + /// Constructs an empty `ResultVal` with the given error code. The code must not be a success + /// code. + ResultVal(ResultCode error_code = ResultCode(-1)) : result_code(error_code) { ASSERT(error_code.IsError()); } @@ -303,17 +307,13 @@ public: return result; } - ResultVal(const ResultVal& o) - : result_code(o.result_code) - { + ResultVal(const ResultVal& o) : result_code(o.result_code) { if (!o.empty()) { new (&object) T(o.object); } } - ResultVal(ResultVal&& o) - : result_code(o.result_code) - { + ResultVal(ResultVal&& o) : result_code(o.result_code) { if (!o.empty()) { new (&object) T(std::move(o.object)); } @@ -357,19 +357,35 @@ public: } /// Returns true if the `ResultVal` contains an error code and no value. - bool empty() const { return result_code.IsError(); } + bool empty() const { + return result_code.IsError(); + } /// Returns true if the `ResultVal` contains a return value. - bool Succeeded() const { return result_code.IsSuccess(); } + bool Succeeded() const { + return result_code.IsSuccess(); + } /// Returns true if the `ResultVal` contains an error code and no value. - bool Failed() const { return empty(); } + bool Failed() const { + return empty(); + } - ResultCode Code() const { return result_code; } + ResultCode Code() const { + return result_code; + } - const T& operator* () const { return object; } - T& operator* () { return object; } - const T* operator->() const { return &object; } - T* operator->() { return &object; } + const T& operator*() const { + return object; + } + T& operator*() { + return object; + } + const T* operator->() const { + return &object; + } + T* operator->() { + return &object; + } /// Returns the value contained in this `ResultVal`, or the supplied default if it is missing. template <typename U> @@ -390,7 +406,9 @@ public: private: // A union is used to allocate the storage for the value, while allowing us to construct and // destruct it at will. - union { T object; }; + union { + T object; + }; ResultCode result_code; }; @@ -409,8 +427,8 @@ ResultVal<T> MakeResult(Args&&... args) { * variable declaration. If it fails the return code is returned from the current function. Thus it * can be used to cascade errors out, achieving something akin to exception handling. */ -#define CASCADE_RESULT(target, source) \ - auto CONCAT2(check_result_L, __LINE__) = source; \ - if (CONCAT2(check_result_L, __LINE__).Failed()) \ - return CONCAT2(check_result_L, __LINE__).Code(); \ - target = std::move(*CONCAT2(check_result_L, __LINE__)) +#define CASCADE_RESULT(target, source) \ + auto CONCAT2(check_result_L, __LINE__) = source; \ + if (CONCAT2(check_result_L, __LINE__).Failed()) \ + return CONCAT2(check_result_L, __LINE__).Code(); \ + target = std::move(*CONCAT2(check_result_L, __LINE__)) diff --git a/src/core/hle/service/ac_u.cpp b/src/core/hle/service/ac_u.cpp index 5241dd3e7..12d94f37a 100644 --- a/src/core/hle/service/ac_u.cpp +++ b/src/core/hle/service/ac_u.cpp @@ -3,7 +3,6 @@ // Refer to the license.txt file included. #include "common/logging/log.h" - #include "core/hle/kernel/event.h" #include "core/hle/service/ac_u.h" @@ -47,7 +46,7 @@ static void GetWifiStatus(Service::Interface* self) { // it returns a valid result without implementing full functionality. cmd_buff[1] = RESULT_SUCCESS.raw; // No error - cmd_buff[2] = 0; // Connection type set to none + cmd_buff[2] = 0; // Connection type set to none LOG_WARNING(Service_AC, "(STUBBED) called"); } @@ -62,29 +61,29 @@ static void IsConnected(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; // No error - cmd_buff[2] = false; // Not connected to ac:u service + cmd_buff[2] = false; // Not connected to ac:u service LOG_WARNING(Service_AC, "(STUBBED) called"); } const Interface::FunctionInfo FunctionTable[] = { - {0x00010000, nullptr, "CreateDefaultConfig"}, - {0x00040006, nullptr, "ConnectAsync"}, - {0x00050002, nullptr, "GetConnectResult"}, - {0x00080004, CloseAsync, "CloseAsync"}, - {0x00090002, nullptr, "GetCloseResult"}, - {0x000A0000, nullptr, "GetLastErrorCode"}, - {0x000D0000, GetWifiStatus, "GetWifiStatus"}, - {0x000E0042, nullptr, "GetCurrentAPInfo"}, - {0x00100042, nullptr, "GetCurrentNZoneInfo"}, - {0x00110042, nullptr, "GetNZoneApNumService"}, - {0x00240042, nullptr, "AddDenyApType"}, - {0x00270002, nullptr, "GetInfraPriority"}, - {0x002D0082, nullptr, "SetRequestEulaVersion"}, - {0x00300004, nullptr, "RegisterDisconnectEvent"}, - {0x003C0042, nullptr, "GetAPSSIDList"}, - {0x003E0042, IsConnected, "IsConnected"}, - {0x00400042, nullptr, "SetClientVersion"}, + {0x00010000, nullptr, "CreateDefaultConfig"}, + {0x00040006, nullptr, "ConnectAsync"}, + {0x00050002, nullptr, "GetConnectResult"}, + {0x00080004, CloseAsync, "CloseAsync"}, + {0x00090002, nullptr, "GetCloseResult"}, + {0x000A0000, nullptr, "GetLastErrorCode"}, + {0x000D0000, GetWifiStatus, "GetWifiStatus"}, + {0x000E0042, nullptr, "GetCurrentAPInfo"}, + {0x00100042, nullptr, "GetCurrentNZoneInfo"}, + {0x00110042, nullptr, "GetNZoneApNumService"}, + {0x00240042, nullptr, "AddDenyApType"}, + {0x00270002, nullptr, "GetInfraPriority"}, + {0x002D0082, nullptr, "SetRequestEulaVersion"}, + {0x00300004, nullptr, "RegisterDisconnectEvent"}, + {0x003C0042, nullptr, "GetAPSSIDList"}, + {0x003E0042, IsConnected, "IsConnected"}, + {0x00400042, nullptr, "SetClientVersion"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 3f71e7f2b..f7a990d69 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -3,22 +3,20 @@ // Refer to the license.txt file included. #include <cinttypes> - #include "common/logging/log.h" - -#include "core/hle/service/service.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/am_app.h" #include "core/hle/service/am/am_net.h" #include "core/hle/service/am/am_sys.h" #include "core/hle/service/am/am_u.h" +#include "core/hle/service/service.h" namespace Service { namespace AM { -static std::array<u32, 3> am_content_count = { 0, 0, 0 }; -static std::array<u32, 3> am_titles_count = { 0, 0, 0 }; -static std::array<u32, 3> am_titles_list_count = { 0, 0, 0 }; +static std::array<u32, 3> am_content_count = {0, 0, 0}; +static std::array<u32, 3> am_titles_count = {0, 0, 0}; +static std::array<u32, 3> am_titles_list_count = {0, 0, 0}; static u32 am_ticket_count = 0; static u32 am_ticket_list_count = 0; @@ -29,7 +27,8 @@ void GetTitleCount(Service::Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[2] = am_titles_count[media_type]; - LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, title_count=0x%08x", media_type, am_titles_count[media_type]); + LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, title_count=0x%08x", media_type, + am_titles_count[media_type]); } void FindContentInfos(Service::Interface* self) { @@ -43,8 +42,10 @@ void FindContentInfos(Service::Interface* self) { am_content_count[media_type] = cmd_buff[4]; cmd_buff[1] = RESULT_SUCCESS.raw; - LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, title_id=0x%016llx, content_cound=%u, content_ids_pointer=0x%08x, content_info_pointer=0x%08x", - media_type, title_id, am_content_count[media_type], content_ids_pointer, content_info_pointer); + LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, title_id=0x%016llx, content_cound=%u, " + "content_ids_pointer=0x%08x, content_info_pointer=0x%08x", + media_type, title_id, am_content_count[media_type], content_ids_pointer, + content_info_pointer); } void ListContentInfos(Service::Interface* self) { @@ -59,8 +60,10 @@ void ListContentInfos(Service::Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[2] = am_content_count[media_type]; - LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, content_count=%u, title_id=0x%016" PRIx64 ", start_index=0x%08x, content_info_pointer=0x%08X", - media_type, am_content_count[media_type], title_id, start_index, content_info_pointer); + LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, content_count=%u, title_id=0x%016" PRIx64 + ", start_index=0x%08x, content_info_pointer=0x%08X", + media_type, am_content_count[media_type], title_id, start_index, + content_info_pointer); } void DeleteContents(Service::Interface* self) { @@ -73,8 +76,9 @@ void DeleteContents(Service::Interface* self) { am_content_count[media_type] = cmd_buff[4]; cmd_buff[1] = RESULT_SUCCESS.raw; - LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, title_id=0x%016" PRIx64 ", content_count=%u, content_ids_pointer=0x%08x", - media_type, title_id, am_content_count[media_type], content_ids_pointer); + LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, title_id=0x%016" PRIx64 + ", content_count=%u, content_ids_pointer=0x%08x", + media_type, title_id, am_content_count[media_type], content_ids_pointer); } void GetTitleList(Service::Interface* self) { @@ -87,8 +91,10 @@ void GetTitleList(Service::Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[2] = am_titles_list_count[media_type]; - LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, titles_list_count=0x%08X, title_ids_output_pointer=0x%08X", - media_type, am_titles_list_count[media_type], title_ids_output_pointer); + LOG_WARNING( + Service_AM, + "(STUBBED) media_type=%u, titles_list_count=0x%08X, title_ids_output_pointer=0x%08X", + media_type, am_titles_list_count[media_type], title_ids_output_pointer); } void GetTitleInfo(Service::Interface* self) { @@ -101,7 +107,8 @@ void GetTitleInfo(Service::Interface* self) { am_titles_count[media_type] = cmd_buff[2]; cmd_buff[1] = RESULT_SUCCESS.raw; - LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, total_titles=0x%08X, title_id_list_pointer=0x%08X, title_list_pointer=0x%08X", + LOG_WARNING(Service_AM, "(STUBBED) media_type=%u, total_titles=0x%08X, " + "title_id_list_pointer=0x%08X, title_list_pointer=0x%08X", media_type, am_titles_count[media_type], title_id_list_pointer, title_list_pointer); } @@ -122,8 +129,9 @@ void ListDataTitleTicketInfos(Service::Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[2] = am_ticket_count; - LOG_WARNING(Service_AM, "(STUBBED) ticket_count=0x%08X, title_id=0x%016" PRIx64 ", start_index=0x%08X, ticket_info_pointer=0x%08X", - am_ticket_count, title_id, start_index, ticket_info_pointer); + LOG_WARNING(Service_AM, "(STUBBED) ticket_count=0x%08X, title_id=0x%016" PRIx64 + ", start_index=0x%08X, ticket_info_pointer=0x%08X", + am_ticket_count, title_id, start_index, ticket_info_pointer); } void GetNumContentInfos(Service::Interface* self) { @@ -140,7 +148,7 @@ void DeleteTicket(Service::Interface* self) { u64 title_id = (static_cast<u64>(cmd_buff[2]) << 32) | cmd_buff[1]; cmd_buff[1] = RESULT_SUCCESS.raw; - LOG_WARNING(Service_AM, "(STUBBED) called title_id=0x%016" PRIx64 "",title_id); + LOG_WARNING(Service_AM, "(STUBBED) called title_id=0x%016" PRIx64 "", title_id); } void GetTicketCount(Service::Interface* self) { @@ -148,7 +156,7 @@ void GetTicketCount(Service::Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[2] = am_ticket_count; - LOG_WARNING(Service_AM, "(STUBBED) called ticket_count=0x%08x",am_ticket_count); + LOG_WARNING(Service_AM, "(STUBBED) called ticket_count=0x%08x", am_ticket_count); } void GetTicketList(Service::Interface* self) { @@ -161,8 +169,10 @@ void GetTicketList(Service::Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[2] = am_ticket_list_count; - LOG_WARNING(Service_AM, "(STUBBED) ticket_list_count=0x%08x, num_of_skip=0x%08x, ticket_list_pointer=0x%08x", - am_ticket_list_count, num_of_skip, ticket_list_pointer); + LOG_WARNING( + Service_AM, + "(STUBBED) ticket_list_count=0x%08x, num_of_skip=0x%08x, ticket_list_pointer=0x%08x", + am_ticket_list_count, num_of_skip, ticket_list_pointer); } void Init() { @@ -174,9 +184,7 @@ void Init() { AddService(new AM_U_Interface); } -void Shutdown() { - -} +void Shutdown() {} } // namespace AM diff --git a/src/core/hle/service/am/am_app.cpp b/src/core/hle/service/am/am_app.cpp index d27b3defd..bfc1ca6bd 100644 --- a/src/core/hle/service/am/am_app.cpp +++ b/src/core/hle/service/am/am_app.cpp @@ -9,14 +9,14 @@ namespace Service { namespace AM { const Interface::FunctionInfo FunctionTable[] = { - {0x100100C0, GetNumContentInfos, "GetNumContentInfos"}, - {0x10020104, FindContentInfos, "FindContentInfos"}, - {0x10030142, ListContentInfos, "ListContentInfos"}, - {0x10040102, DeleteContents, "DeleteContents"}, - {0x10050084, GetDataTitleInfos, "GetDataTitleInfos"}, - {0x10070102, ListDataTitleTicketInfos, "ListDataTitleTicketInfos"}, - {0x100900C0, nullptr, "IsDataTitleInUse"}, - {0x100A0000, nullptr, "IsExternalTitleDatabaseInitialized"}, + {0x100100C0, GetNumContentInfos, "GetNumContentInfos"}, + {0x10020104, FindContentInfos, "FindContentInfos"}, + {0x10030142, ListContentInfos, "ListContentInfos"}, + {0x10040102, DeleteContents, "DeleteContents"}, + {0x10050084, GetDataTitleInfos, "GetDataTitleInfos"}, + {0x10070102, ListDataTitleTicketInfos, "ListDataTitleTicketInfos"}, + {0x100900C0, nullptr, "IsDataTitleInUse"}, + {0x100A0000, nullptr, "IsExternalTitleDatabaseInitialized"}, }; AM_APP_Interface::AM_APP_Interface() { diff --git a/src/core/hle/service/am/am_net.cpp b/src/core/hle/service/am/am_net.cpp index e75755245..3a597a34c 100644 --- a/src/core/hle/service/am/am_net.cpp +++ b/src/core/hle/service/am/am_net.cpp @@ -9,61 +9,61 @@ namespace Service { namespace AM { const Interface::FunctionInfo FunctionTable[] = { - {0x00010040, GetTitleCount, "GetTitleCount"}, - {0x00020082, GetTitleList, "GetTitleList"}, - {0x00030084, GetTitleInfo, "GetTitleInfo"}, - {0x000400C0, nullptr, "DeleteApplicationTitle"}, - {0x000500C0, nullptr, "GetTitleProductCode"}, - {0x000600C0, nullptr, "GetTitleExtDataId"}, - {0x00070080, DeleteTicket, "DeleteTicket"}, - {0x00080000, GetTicketCount, "GetTicketCount"}, - {0x00090082, GetTicketList, "GetTicketList"}, - {0x000A0000, nullptr, "GetDeviceID"}, - {0x000D0084, nullptr, "GetPendingTitleInfo"}, - {0x000E00C0, nullptr, "DeletePendingTitle"}, - {0x00140040, nullptr, "FinalizePendingTitles"}, - {0x00150040, nullptr, "DeleteAllPendingTitles"}, - {0x00180080, nullptr, "InitializeTitleDatabase"}, - {0x00190040, nullptr, "ReloadDBS"}, - {0x001A00C0, nullptr, "GetDSiWareExportSize"}, - {0x001B0144, nullptr, "ExportDSiWare"}, - {0x001C0084, nullptr, "ImportDSiWare"}, - {0x00230080, nullptr, "TitleIDListGetTotal2"}, - {0x002400C2, nullptr, "GetTitleIDList2"}, - {0x04010080, nullptr, "InstallFIRM"}, - {0x04020040, nullptr, "StartInstallCIADB0"}, - {0x04030000, nullptr, "StartInstallCIADB1"}, - {0x04040002, nullptr, "AbortCIAInstall"}, - {0x04050002, nullptr, "CloseCIAFinalizeInstall"}, - {0x04060002, nullptr, "CloseCIA"}, - {0x040700C2, nullptr, "FinalizeTitlesInstall"}, - {0x04080042, nullptr, "GetCiaFileInfo"}, - {0x040E00C2, nullptr, "InstallTitlesFinish"}, - {0x040F0000, nullptr, "InstallNATIVEFIRM"}, - {0x041000C0, nullptr, "DeleteTitle"}, - {0x04120000, nullptr, "Initialize"}, - {0x041700C0, nullptr, "MigrateAGBtoSAV"}, - {0x08010000, nullptr, "OpenTicket"}, - {0x08020002, nullptr, "TicketAbortInstall"}, - {0x08030002, nullptr, "TicketFinalizeInstall"}, - {0x08040100, nullptr, "InstallTitleBegin"}, - {0x08050000, nullptr, "InstallTitleAbort"}, - {0x080600C0, nullptr, "InstallTitleResume"}, - {0x08070000, nullptr, "InstallTitleAbortTMD"}, - {0x08080000, nullptr, "InstallTitleFinish"}, - {0x080A0000, nullptr, "OpenTMD"}, - {0x080B0002, nullptr, "TMDAbortInstall"}, - {0x080C0042, nullptr, "TMDFinalizeInstall"}, - {0x080E0040, nullptr, "OpenContentCreate"}, - {0x080F0002, nullptr, "ContentAbortInstall"}, - {0x08100040, nullptr, "OpenContentResume"}, - {0x08120002, nullptr, "ContentFinalizeInstall"}, - {0x08130000, nullptr, "GetTotalContents"}, - {0x08140042, nullptr, "GetContentIndexes"}, - {0x08150044, nullptr, "GetContentsInfo"}, - {0x08180042, nullptr, "GetCTCert"}, - {0x08190108, nullptr, "SetCertificates"}, - {0x081B00C2, nullptr, "InstallTitlesFinish"}, + {0x00010040, GetTitleCount, "GetTitleCount"}, + {0x00020082, GetTitleList, "GetTitleList"}, + {0x00030084, GetTitleInfo, "GetTitleInfo"}, + {0x000400C0, nullptr, "DeleteApplicationTitle"}, + {0x000500C0, nullptr, "GetTitleProductCode"}, + {0x000600C0, nullptr, "GetTitleExtDataId"}, + {0x00070080, DeleteTicket, "DeleteTicket"}, + {0x00080000, GetTicketCount, "GetTicketCount"}, + {0x00090082, GetTicketList, "GetTicketList"}, + {0x000A0000, nullptr, "GetDeviceID"}, + {0x000D0084, nullptr, "GetPendingTitleInfo"}, + {0x000E00C0, nullptr, "DeletePendingTitle"}, + {0x00140040, nullptr, "FinalizePendingTitles"}, + {0x00150040, nullptr, "DeleteAllPendingTitles"}, + {0x00180080, nullptr, "InitializeTitleDatabase"}, + {0x00190040, nullptr, "ReloadDBS"}, + {0x001A00C0, nullptr, "GetDSiWareExportSize"}, + {0x001B0144, nullptr, "ExportDSiWare"}, + {0x001C0084, nullptr, "ImportDSiWare"}, + {0x00230080, nullptr, "TitleIDListGetTotal2"}, + {0x002400C2, nullptr, "GetTitleIDList2"}, + {0x04010080, nullptr, "InstallFIRM"}, + {0x04020040, nullptr, "StartInstallCIADB0"}, + {0x04030000, nullptr, "StartInstallCIADB1"}, + {0x04040002, nullptr, "AbortCIAInstall"}, + {0x04050002, nullptr, "CloseCIAFinalizeInstall"}, + {0x04060002, nullptr, "CloseCIA"}, + {0x040700C2, nullptr, "FinalizeTitlesInstall"}, + {0x04080042, nullptr, "GetCiaFileInfo"}, + {0x040E00C2, nullptr, "InstallTitlesFinish"}, + {0x040F0000, nullptr, "InstallNATIVEFIRM"}, + {0x041000C0, nullptr, "DeleteTitle"}, + {0x04120000, nullptr, "Initialize"}, + {0x041700C0, nullptr, "MigrateAGBtoSAV"}, + {0x08010000, nullptr, "OpenTicket"}, + {0x08020002, nullptr, "TicketAbortInstall"}, + {0x08030002, nullptr, "TicketFinalizeInstall"}, + {0x08040100, nullptr, "InstallTitleBegin"}, + {0x08050000, nullptr, "InstallTitleAbort"}, + {0x080600C0, nullptr, "InstallTitleResume"}, + {0x08070000, nullptr, "InstallTitleAbortTMD"}, + {0x08080000, nullptr, "InstallTitleFinish"}, + {0x080A0000, nullptr, "OpenTMD"}, + {0x080B0002, nullptr, "TMDAbortInstall"}, + {0x080C0042, nullptr, "TMDFinalizeInstall"}, + {0x080E0040, nullptr, "OpenContentCreate"}, + {0x080F0002, nullptr, "ContentAbortInstall"}, + {0x08100040, nullptr, "OpenContentResume"}, + {0x08120002, nullptr, "ContentFinalizeInstall"}, + {0x08130000, nullptr, "GetTotalContents"}, + {0x08140042, nullptr, "GetContentIndexes"}, + {0x08150044, nullptr, "GetContentsInfo"}, + {0x08180042, nullptr, "GetCTCert"}, + {0x08190108, nullptr, "SetCertificates"}, + {0x081B00C2, nullptr, "InstallTitlesFinish"}, }; AM_NET_Interface::AM_NET_Interface() { diff --git a/src/core/hle/service/am/am_sys.cpp b/src/core/hle/service/am/am_sys.cpp index 8bad5e1c9..a2268303c 100644 --- a/src/core/hle/service/am/am_sys.cpp +++ b/src/core/hle/service/am/am_sys.cpp @@ -9,27 +9,27 @@ namespace Service { namespace AM { const Interface::FunctionInfo FunctionTable[] = { - {0x00010040, GetTitleCount, "GetTitleCount"}, - {0x00020082, GetTitleList, "GetTitleList"}, - {0x00030084, GetTitleInfo, "GetTitleInfo"}, - {0x000400C0, nullptr, "DeleteApplicationTitle"}, - {0x000500C0, nullptr, "GetTitleProductCode"}, - {0x000600C0, nullptr, "GetTitleExtDataId"}, - {0x00070080, DeleteTicket, "DeleteTicket"}, - {0x00080000, GetTicketCount, "GetTicketCount"}, - {0x00090082, GetTicketList, "GetTicketList"}, - {0x000A0000, nullptr, "GetDeviceID"}, - {0x000D0084, nullptr, "GetPendingTitleInfo"}, - {0x000E00C0, nullptr, "DeletePendingTitle"}, - {0x00140040, nullptr, "FinalizePendingTitles"}, - {0x00150040, nullptr, "DeleteAllPendingTitles"}, - {0x00180080, nullptr, "InitializeTitleDatabase"}, - {0x00190040, nullptr, "ReloadDBS"}, - {0x001A00C0, nullptr, "GetDSiWareExportSize"}, - {0x001B0144, nullptr, "ExportDSiWare"}, - {0x001C0084, nullptr, "ImportDSiWare"}, - {0x00230080, nullptr, "GetPendingTitleCount"}, - {0x002400C2, nullptr, "GetPendingTitleList"} + {0x00010040, GetTitleCount, "GetTitleCount"}, + {0x00020082, GetTitleList, "GetTitleList"}, + {0x00030084, GetTitleInfo, "GetTitleInfo"}, + {0x000400C0, nullptr, "DeleteApplicationTitle"}, + {0x000500C0, nullptr, "GetTitleProductCode"}, + {0x000600C0, nullptr, "GetTitleExtDataId"}, + {0x00070080, DeleteTicket, "DeleteTicket"}, + {0x00080000, GetTicketCount, "GetTicketCount"}, + {0x00090082, GetTicketList, "GetTicketList"}, + {0x000A0000, nullptr, "GetDeviceID"}, + {0x000D0084, nullptr, "GetPendingTitleInfo"}, + {0x000E00C0, nullptr, "DeletePendingTitle"}, + {0x00140040, nullptr, "FinalizePendingTitles"}, + {0x00150040, nullptr, "DeleteAllPendingTitles"}, + {0x00180080, nullptr, "InitializeTitleDatabase"}, + {0x00190040, nullptr, "ReloadDBS"}, + {0x001A00C0, nullptr, "GetDSiWareExportSize"}, + {0x001B0144, nullptr, "ExportDSiWare"}, + {0x001C0084, nullptr, "ImportDSiWare"}, + {0x00230080, nullptr, "GetPendingTitleCount"}, + {0x002400C2, nullptr, "GetPendingTitleList"}, }; AM_SYS_Interface::AM_SYS_Interface() { diff --git a/src/core/hle/service/am/am_u.cpp b/src/core/hle/service/am/am_u.cpp index d583dd9e6..151b5e42b 100644 --- a/src/core/hle/service/am/am_u.cpp +++ b/src/core/hle/service/am/am_u.cpp @@ -9,40 +9,40 @@ namespace Service { namespace AM { const Interface::FunctionInfo FunctionTable[] = { - {0x00010040, GetTitleCount, "GetTitleCount"}, - {0x00020082, GetTitleList, "GetTitleList"}, - {0x00030084, GetTitleInfo, "GetTitleInfo"}, - {0x000400C0, nullptr, "DeleteApplicationTitle"}, - {0x000500C0, nullptr, "GetTitleProductCode"}, - {0x000600C0, nullptr, "GetTitleExtDataId"}, - {0x00070080, DeleteTicket, "DeleteTicket"}, - {0x00080000, GetTicketCount, "GetTicketCount"}, - {0x00090082, GetTicketList, "GetTicketList"}, - {0x000A0000, nullptr, "GetDeviceID"}, - {0x000D0084, nullptr, "GetPendingTitleInfo"}, - {0x000E00C0, nullptr, "DeletePendingTitle"}, - {0x00140040, nullptr, "FinalizePendingTitles"}, - {0x00150040, nullptr, "DeleteAllPendingTitles"}, - {0x00180080, nullptr, "InitializeTitleDatabase"}, - {0x00190040, nullptr, "ReloadDBS"}, - {0x001A00C0, nullptr, "GetDSiWareExportSize"}, - {0x001B0144, nullptr, "ExportDSiWare"}, - {0x001C0084, nullptr, "ImportDSiWare"}, - {0x00230080, nullptr, "TitleIDListGetTotal2"}, - {0x002400C2, nullptr, "GetTitleIDList2"}, - {0x04010080, nullptr, "InstallFIRM"}, - {0x04020040, nullptr, "StartInstallCIADB0"}, - {0x04030000, nullptr, "StartInstallCIADB1"}, - {0x04040002, nullptr, "AbortCIAInstall"}, - {0x04050002, nullptr, "CloseCIAFinalizeInstall"}, - {0x04060002, nullptr, "CloseCIA"}, - {0x040700C2, nullptr, "FinalizeTitlesInstall"}, - {0x04080042, nullptr, "GetCiaFileInfo"}, - {0x040E00C2, nullptr, "InstallTitlesFinish"}, - {0x040F0000, nullptr, "InstallNATIVEFIRM"}, - {0x041000C0, nullptr, "DeleteTitle"}, - {0x04120000, nullptr, "Initialize"}, - {0x041700C0, nullptr, "MigrateAGBtoSAV"} + {0x00010040, GetTitleCount, "GetTitleCount"}, + {0x00020082, GetTitleList, "GetTitleList"}, + {0x00030084, GetTitleInfo, "GetTitleInfo"}, + {0x000400C0, nullptr, "DeleteApplicationTitle"}, + {0x000500C0, nullptr, "GetTitleProductCode"}, + {0x000600C0, nullptr, "GetTitleExtDataId"}, + {0x00070080, DeleteTicket, "DeleteTicket"}, + {0x00080000, GetTicketCount, "GetTicketCount"}, + {0x00090082, GetTicketList, "GetTicketList"}, + {0x000A0000, nullptr, "GetDeviceID"}, + {0x000D0084, nullptr, "GetPendingTitleInfo"}, + {0x000E00C0, nullptr, "DeletePendingTitle"}, + {0x00140040, nullptr, "FinalizePendingTitles"}, + {0x00150040, nullptr, "DeleteAllPendingTitles"}, + {0x00180080, nullptr, "InitializeTitleDatabase"}, + {0x00190040, nullptr, "ReloadDBS"}, + {0x001A00C0, nullptr, "GetDSiWareExportSize"}, + {0x001B0144, nullptr, "ExportDSiWare"}, + {0x001C0084, nullptr, "ImportDSiWare"}, + {0x00230080, nullptr, "TitleIDListGetTotal2"}, + {0x002400C2, nullptr, "GetTitleIDList2"}, + {0x04010080, nullptr, "InstallFIRM"}, + {0x04020040, nullptr, "StartInstallCIADB0"}, + {0x04030000, nullptr, "StartInstallCIADB1"}, + {0x04040002, nullptr, "AbortCIAInstall"}, + {0x04050002, nullptr, "CloseCIAFinalizeInstall"}, + {0x04060002, nullptr, "CloseCIA"}, + {0x040700C2, nullptr, "FinalizeTitlesInstall"}, + {0x04080042, nullptr, "GetCiaFileInfo"}, + {0x040E00C2, nullptr, "InstallTitlesFinish"}, + {0x040F0000, nullptr, "InstallNATIVEFIRM"}, + {0x041000C0, nullptr, "DeleteTitle"}, + {0x04120000, nullptr, "Initialize"}, + {0x041700C0, nullptr, "MigrateAGBtoSAV"}, }; AM_U_Interface::AM_U_Interface() { diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index 4d2956638..c4bd65986 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -5,9 +5,11 @@ #include "common/common_paths.h" #include "common/file_util.h" #include "common/logging/log.h" - #include "core/hle/applets/applet.h" -#include "core/hle/service/service.h" +#include "core/hle/kernel/event.h" +#include "core/hle/kernel/mutex.h" +#include "core/hle/kernel/process.h" +#include "core/hle/kernel/shared_memory.h" #include "core/hle/service/apt/apt.h" #include "core/hle/service/apt/apt_a.h" #include "core/hle/service/apt/apt_s.h" @@ -15,11 +17,7 @@ #include "core/hle/service/apt/bcfnt/bcfnt.h" #include "core/hle/service/fs/archive.h" #include "core/hle/service/ptm/ptm.h" - -#include "core/hle/kernel/event.h" -#include "core/hle/kernel/mutex.h" -#include "core/hle/kernel/process.h" -#include "core/hle/kernel/shared_memory.h" +#include "core/hle/service/service.h" namespace Service { namespace APT { @@ -30,7 +28,7 @@ static bool shared_font_relocated = false; static Kernel::SharedPtr<Kernel::Mutex> lock; static Kernel::SharedPtr<Kernel::Event> notification_event; ///< APT notification event -static Kernel::SharedPtr<Kernel::Event> parameter_event; ///< APT parameter event +static Kernel::SharedPtr<Kernel::Event> parameter_event; ///< APT parameter event static u32 cpu_percent; ///< CPU time available to the running application @@ -51,7 +49,7 @@ void SendParameter(const MessageParameter& parameter) { void Initialize(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 app_id = cmd_buff[1]; - u32 flags = cmd_buff[2]; + u32 flags = cmd_buff[2]; cmd_buff[2] = IPC::CopyHandleDesc(2); cmd_buff[3] = Kernel::g_handle_table.Create(notification_event).MoveFrom(); @@ -75,21 +73,23 @@ void GetSharedFont(Service::Interface* self) { if (!shared_font_mem) { LOG_ERROR(Service_APT, "shared font file missing - go dump it from your 3ds"); cmd_buff[0] = IPC::MakeHeader(0x44, 2, 2); - cmd_buff[1] = -1; // TODO: Find the right error code + cmd_buff[1] = -1; // TODO: Find the right error code return; } - // The shared font has to be relocated to the new address before being passed to the application. - VAddr target_address = Memory::PhysicalToVirtualAddress(shared_font_mem->linear_heap_phys_address); + // The shared font has to be relocated to the new address before being passed to the + // application. + VAddr target_address = + Memory::PhysicalToVirtualAddress(shared_font_mem->linear_heap_phys_address); if (!shared_font_relocated) { BCFNT::RelocateSharedFont(shared_font_mem, target_address); shared_font_relocated = true; } cmd_buff[0] = IPC::MakeHeader(0x44, 2, 2); cmd_buff[1] = RESULT_SUCCESS.raw; // No error - // Since the SharedMemory interface doesn't provide the address at which the memory was allocated, - // the real APT service calculates this address by scanning the entire address space (using svcQueryMemory) - // and searches for an allocation of the same size as the Shared Font. + // Since the SharedMemory interface doesn't provide the address at which the memory was + // allocated, the real APT service calculates this address by scanning the entire address space + // (using svcQueryMemory) and searches for an allocation of the same size as the Shared Font. cmd_buff[2] = target_address; cmd_buff[3] = IPC::CopyHandleDesc(); cmd_buff[4] = Kernel::g_handle_table.Create(shared_font_mem).MoveFrom(); @@ -112,18 +112,19 @@ void GetLockHandle(Service::Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; // No error cmd_buff[2] = applet_attributes; // Applet Attributes, this value is passed to Enable. - cmd_buff[3] = 0; // Least significant bit = power button state + cmd_buff[3] = 0; // Least significant bit = power button state cmd_buff[4] = IPC::CopyHandleDesc(); cmd_buff[5] = Kernel::g_handle_table.Create(lock).MoveFrom(); - LOG_WARNING(Service_APT, "(STUBBED) called handle=0x%08X applet_attributes=0x%08X", cmd_buff[5], applet_attributes); + LOG_WARNING(Service_APT, "(STUBBED) called handle=0x%08X applet_attributes=0x%08X", cmd_buff[5], + applet_attributes); } void Enable(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 attributes = cmd_buff[1]; cmd_buff[1] = RESULT_SUCCESS.raw; // No error - parameter_event->Signal(); // Let the application know that it has been started + parameter_event->Signal(); // Let the application know that it has been started LOG_WARNING(Service_APT, "(STUBBED) called attributes=0x%08X", attributes); } @@ -133,7 +134,7 @@ void GetAppletManInfo(Service::Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; // No error cmd_buff[2] = 0; cmd_buff[3] = 0; - cmd_buff[4] = static_cast<u32>(AppletId::HomeMenu); // Home menu AppID + cmd_buff[4] = static_cast<u32>(AppletId::HomeMenu); // Home menu AppID cmd_buff[5] = static_cast<u32>(AppletId::Application); // TODO(purpasmart96): Do this correctly LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X", unk); @@ -159,23 +160,24 @@ void IsRegistered(Service::Interface* self) { void InquireNotification(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 app_id = cmd_buff[1]; - cmd_buff[1] = RESULT_SUCCESS.raw; // No error + cmd_buff[1] = RESULT_SUCCESS.raw; // No error cmd_buff[2] = static_cast<u32>(SignalType::None); // Signal type LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X", app_id); } void SendParameter(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - u32 src_app_id = cmd_buff[1]; - u32 dst_app_id = cmd_buff[2]; - u32 signal_type = cmd_buff[3]; - u32 buffer_size = cmd_buff[4]; - u32 value = cmd_buff[5]; - u32 handle = cmd_buff[6]; - u32 size = cmd_buff[7]; - u32 buffer = cmd_buff[8]; - - std::shared_ptr<HLE::Applets::Applet> dest_applet = HLE::Applets::Applet::Get(static_cast<AppletId>(dst_app_id)); + u32 src_app_id = cmd_buff[1]; + u32 dst_app_id = cmd_buff[2]; + u32 signal_type = cmd_buff[3]; + u32 buffer_size = cmd_buff[4]; + u32 value = cmd_buff[5]; + u32 handle = cmd_buff[6]; + u32 size = cmd_buff[7]; + u32 buffer = cmd_buff[8]; + + std::shared_ptr<HLE::Applets::Applet> dest_applet = + HLE::Applets::Applet::Get(static_cast<AppletId>(dst_app_id)); if (dest_applet == nullptr) { LOG_ERROR(Service_APT, "Unknown applet id=0x%08X", dst_app_id); @@ -193,9 +195,11 @@ void SendParameter(Service::Interface* self) { cmd_buff[1] = dest_applet->ReceiveParameter(param).raw; - LOG_WARNING(Service_APT, "(STUBBED) called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X," - "buffer_size=0x%08X, value=0x%08X, handle=0x%08X, size=0x%08X, in_param_buffer_ptr=0x%08X", - src_app_id, dst_app_id, signal_type, buffer_size, value, handle, size, buffer); + LOG_WARNING( + Service_APT, + "(STUBBED) called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X," + "buffer_size=0x%08X, value=0x%08X, handle=0x%08X, size=0x%08X, in_param_buffer_ptr=0x%08X", + src_app_id, dst_app_id, signal_type, buffer_size, value, handle, size, buffer); } void ReceiveParameter(Service::Interface* self) { @@ -206,7 +210,7 @@ void ReceiveParameter(Service::Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; // No error cmd_buff[2] = next_parameter.sender_id; - cmd_buff[3] = next_parameter.signal; // Signal type + cmd_buff[3] = next_parameter.signal; // Signal type cmd_buff[4] = next_parameter.buffer.size(); // Parameter buffer size cmd_buff[5] = 0x10; cmd_buff[6] = 0; @@ -228,7 +232,7 @@ void GlanceParameter(Service::Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; // No error cmd_buff[2] = next_parameter.sender_id; - cmd_buff[3] = next_parameter.signal; // Signal type + cmd_buff[3] = next_parameter.signal; // Signal type cmd_buff[4] = next_parameter.buffer.size(); // Parameter buffer size cmd_buff[5] = 0x10; cmd_buff[6] = 0; @@ -237,32 +241,34 @@ void GlanceParameter(Service::Interface* self) { cmd_buff[7] = (next_parameter.buffer.size() << 14) | 2; cmd_buff[8] = buffer; - Memory::WriteBlock(buffer, next_parameter.buffer.data(), std::min(static_cast<size_t>(buffer_size), next_parameter.buffer.size())); + Memory::WriteBlock(buffer, next_parameter.buffer.data(), + std::min(static_cast<size_t>(buffer_size), next_parameter.buffer.size())); LOG_WARNING(Service_APT, "called app_id=0x%08X, buffer_size=0x%08X", app_id, buffer_size); } void CancelParameter(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - u32 flag1 = cmd_buff[1]; - u32 unk = cmd_buff[2]; - u32 flag2 = cmd_buff[3]; + u32 flag1 = cmd_buff[1]; + u32 unk = cmd_buff[2]; + u32 flag2 = cmd_buff[3]; u32 app_id = cmd_buff[4]; cmd_buff[1] = RESULT_SUCCESS.raw; // No error - cmd_buff[2] = 1; // Set to Success + cmd_buff[2] = 1; // Set to Success - LOG_WARNING(Service_APT, "(STUBBED) called flag1=0x%08X, unk=0x%08X, flag2=0x%08X, app_id=0x%08X", - flag1, unk, flag2, app_id); + LOG_WARNING(Service_APT, + "(STUBBED) called flag1=0x%08X, unk=0x%08X, flag2=0x%08X, app_id=0x%08X", flag1, + unk, flag2, app_id); } void PrepareToStartApplication(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - u32 title_info1 = cmd_buff[1]; - u32 title_info2 = cmd_buff[2]; - u32 title_info3 = cmd_buff[3]; - u32 title_info4 = cmd_buff[4]; - u32 flags = cmd_buff[5]; + u32 title_info1 = cmd_buff[1]; + u32 title_info2 = cmd_buff[2]; + u32 title_info3 = cmd_buff[3]; + u32 title_info4 = cmd_buff[4]; + u32 flags = cmd_buff[5]; if (flags & 0x00000100) { unknown_ns_state_field = 1; @@ -270,25 +276,28 @@ void PrepareToStartApplication(Service::Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; // No error - LOG_WARNING(Service_APT, "(STUBBED) called title_info1=0x%08X, title_info2=0x%08X, title_info3=0x%08X," - "title_info4=0x%08X, flags=0x%08X", title_info1, title_info2, title_info3, title_info4, flags); + LOG_WARNING(Service_APT, + "(STUBBED) called title_info1=0x%08X, title_info2=0x%08X, title_info3=0x%08X," + "title_info4=0x%08X, flags=0x%08X", + title_info1, title_info2, title_info3, title_info4, flags); } void StartApplication(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 buffer1_size = cmd_buff[1]; u32 buffer2_size = cmd_buff[2]; - u32 flag = cmd_buff[3]; - u32 size1 = cmd_buff[4]; - u32 buffer1_ptr = cmd_buff[5]; - u32 size2 = cmd_buff[6]; - u32 buffer2_ptr = cmd_buff[7]; + u32 flag = cmd_buff[3]; + u32 size1 = cmd_buff[4]; + u32 buffer1_ptr = cmd_buff[5]; + u32 size2 = cmd_buff[6]; + u32 buffer2_ptr = cmd_buff[7]; cmd_buff[1] = RESULT_SUCCESS.raw; // No error - LOG_WARNING(Service_APT, "(STUBBED) called buffer1_size=0x%08X, buffer2_size=0x%08X, flag=0x%08X," - "size1=0x%08X, buffer1_ptr=0x%08X, size2=0x%08X, buffer2_ptr=0x%08X", - buffer1_size, buffer2_size, flag, size1, buffer1_ptr, size2, buffer2_ptr); + LOG_WARNING(Service_APT, + "(STUBBED) called buffer1_size=0x%08X, buffer2_size=0x%08X, flag=0x%08X," + "size1=0x%08X, buffer1_ptr=0x%08X, size2=0x%08X, buffer2_ptr=0x%08X", + buffer1_size, buffer2_size, flag, size1, buffer1_ptr, size2, buffer2_ptr); } void AppletUtility(Service::Interface* self) { @@ -303,14 +312,15 @@ void AppletUtility(Service::Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; // No error - LOG_WARNING(Service_APT, "(STUBBED) called command=0x%08X, buffer1_size=0x%08X, buffer2_size=0x%08X, " - "buffer1_addr=0x%08X, buffer2_addr=0x%08X", command, buffer1_size, buffer2_size, - buffer1_addr, buffer2_addr); + LOG_WARNING(Service_APT, + "(STUBBED) called command=0x%08X, buffer1_size=0x%08X, buffer2_size=0x%08X, " + "buffer1_addr=0x%08X, buffer2_addr=0x%08X", + command, buffer1_size, buffer2_size, buffer1_addr, buffer2_addr); } void SetAppCpuTimeLimit(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - u32 value = cmd_buff[1]; + u32 value = cmd_buff[1]; cpu_percent = cmd_buff[2]; if (value != 1) { @@ -393,7 +403,8 @@ void SetScreenCapPostPermission(Service::Interface* self) { cmd_buff[0] = IPC::MakeHeader(0x55, 1, 0); cmd_buff[1] = RESULT_SUCCESS.raw; - LOG_WARNING(Service_APT, "(STUBBED) screen_capture_post_permission=%u", screen_capture_post_permission); + LOG_WARNING(Service_APT, "(STUBBED) screen_capture_post_permission=%u", + screen_capture_post_permission); } void GetScreenCapPostPermission(Service::Interface* self) { @@ -402,7 +413,8 @@ void GetScreenCapPostPermission(Service::Interface* self) { cmd_buff[0] = IPC::MakeHeader(0x56, 2, 0); cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[2] = static_cast<u32>(screen_capture_post_permission); - LOG_WARNING(Service_APT, "(STUBBED) screen_capture_post_permission=%u", screen_capture_post_permission); + LOG_WARNING(Service_APT, "(STUBBED) screen_capture_post_permission=%u", + screen_capture_post_permission); } void GetAppletInfo(Service::Interface* self) { @@ -418,7 +430,8 @@ void GetAppletInfo(Service::Interface* self) { cmd_buff[7] = 0; // Applet Attributes } else { cmd_buff[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Applet, - ErrorSummary::NotFound, ErrorLevel::Status).raw; + ErrorSummary::NotFound, ErrorLevel::Status) + .raw; } LOG_WARNING(Service_APT, "(stubbed) called appid=%u", app_id); } @@ -429,11 +442,15 @@ void GetStartupArgument(Service::Interface* self) { StartupArgumentType startup_argument_type = static_cast<StartupArgumentType>(cmd_buff[2]); if (parameter_size >= 0x300) { - LOG_ERROR(Service_APT, "Parameter size is outside the valid range (capped to 0x300): parameter_size=0x%08x", parameter_size); + LOG_ERROR( + Service_APT, + "Parameter size is outside the valid range (capped to 0x300): parameter_size=0x%08x", + parameter_size); return; } - LOG_WARNING(Service_APT,"(stubbed) called startup_argument_type=%u , parameter_size=0x%08x , parameter_value=0x%08x", + LOG_WARNING(Service_APT, "(stubbed) called startup_argument_type=%u , parameter_size=0x%08x , " + "parameter_value=0x%08x", startup_argument_type, parameter_size, Memory::Read32(cmd_buff[41])); cmd_buff[1] = RESULT_SUCCESS.raw; @@ -484,8 +501,10 @@ void Init() { if (file.IsOpen()) { // Create shared font memory object using Kernel::MemoryPermission; - shared_font_mem = Kernel::SharedMemory::Create(nullptr, 0x332000, // 3272 KB - MemoryPermission::ReadWrite, MemoryPermission::Read, 0, Kernel::MemoryRegion::SYSTEM, "APT:SharedFont"); + shared_font_mem = + Kernel::SharedMemory::Create(nullptr, 0x332000, // 3272 KB + MemoryPermission::ReadWrite, MemoryPermission::Read, 0, + Kernel::MemoryRegion::SYSTEM, "APT:SharedFont"); // Read shared font data file.ReadBytes(shared_font_mem->GetPointer(), file.GetSize()); } else { @@ -497,7 +516,8 @@ void Init() { cpu_percent = 0; unknown_ns_state_field = 0; - screen_capture_post_permission = ScreencapPostPermission::CleanThePermission; // TODO(JamePeng): verify the initial value + screen_capture_post_permission = + ScreencapPostPermission::CleanThePermission; // TODO(JamePeng): verify the initial value // TODO(bunnei): Check if these are created in Initialize or on APT process startup. notification_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "APT_U:Notification"); diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index 077a6a316..a118cda1f 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -6,7 +6,6 @@ #include "common/common_types.h" #include "common/swap.h" - #include "core/hle/kernel/kernel.h" namespace Service { @@ -46,58 +45,58 @@ static_assert(sizeof(CaptureBufferInfo) == 0x20, "CaptureBufferInfo struct has i /// Signals used by APT functions enum class SignalType : u32 { - None = 0x0, - AppJustStarted = 0x1, + None = 0x0, + AppJustStarted = 0x1, LibAppJustStarted = 0x2, - LibAppFinished = 0x3, - LibAppClosed = 0xA, - ReturningToApp = 0xB, - ExitingApp = 0xC, + LibAppFinished = 0x3, + LibAppClosed = 0xA, + ReturningToApp = 0xB, + ExitingApp = 0xC, }; /// App Id's used by APT functions enum class AppletId : u32 { - HomeMenu = 0x101, - AlternateMenu = 0x103, - Camera = 0x110, - FriendsList = 0x112, - GameNotes = 0x113, - InternetBrowser = 0x114, - InstructionManual = 0x115, - Notifications = 0x116, - Miiverse = 0x117, - MiiversePost = 0x118, - AmiiboSettings = 0x119, - SoftwareKeyboard1 = 0x201, - Ed1 = 0x202, - PnoteApp = 0x204, - SnoteApp = 0x205, - Error = 0x206, - Mint = 0x207, - Extrapad = 0x208, - Memolib = 0x209, - Application = 0x300, - AnyLibraryApplet = 0x400, - SoftwareKeyboard2 = 0x401, - Ed2 = 0x402, - PnoteApp2 = 0x404, - SnoteApp2 = 0x405, - Error2 = 0x406, - Mint2 = 0x407, - Extrapad2 = 0x408, - Memolib2 = 0x409, + HomeMenu = 0x101, + AlternateMenu = 0x103, + Camera = 0x110, + FriendsList = 0x112, + GameNotes = 0x113, + InternetBrowser = 0x114, + InstructionManual = 0x115, + Notifications = 0x116, + Miiverse = 0x117, + MiiversePost = 0x118, + AmiiboSettings = 0x119, + SoftwareKeyboard1 = 0x201, + Ed1 = 0x202, + PnoteApp = 0x204, + SnoteApp = 0x205, + Error = 0x206, + Mint = 0x207, + Extrapad = 0x208, + Memolib = 0x209, + Application = 0x300, + AnyLibraryApplet = 0x400, + SoftwareKeyboard2 = 0x401, + Ed2 = 0x402, + PnoteApp2 = 0x404, + SnoteApp2 = 0x405, + Error2 = 0x406, + Mint2 = 0x407, + Extrapad2 = 0x408, + Memolib2 = 0x409, }; enum class StartupArgumentType : u32 { - OtherApp = 0, - Restart = 1, + OtherApp = 0, + Restart = 1, OtherMedia = 2, }; enum class ScreencapPostPermission : u32 { - CleanThePermission = 0, //TODO(JamePeng): verify what "zero" means - NoExplicitSetting = 1, - EnableScreenshotPostingToMiiverse = 2, + CleanThePermission = 0, // TODO(JamePeng): verify what "zero" means + NoExplicitSetting = 1, + EnableScreenshotPostingToMiiverse = 2, DisableScreenshotPostingToMiiverse = 3 }; @@ -182,10 +181,11 @@ void GetAppletManInfo(Service::Interface* self); void GetAppletInfo(Service::Interface* self); /** - * APT::IsRegistered service function. This returns whether the specified AppID is registered with NS yet. - * An AppID is "registered" once the process associated with the AppID uses APT:Enable. Home Menu uses this - * command to determine when the launched process is running and to determine when to stop using GSP etc, - * while displaying the "Nintendo 3DS" loading screen. + * APT::IsRegistered service function. This returns whether the specified AppID is registered with + * NS yet. An AppID is "registered" once the process associated with the AppID uses APT:Enable. Home + * Menu uses this command to determine when the launched process is running and to determine when to + * stop using GSP, etc., while displaying the "Nintendo 3DS" loading screen. + * * Inputs: * 1 : AppID * Outputs: @@ -260,9 +260,11 @@ void GlanceParameter(Service::Interface* self); * clears the flag which indicates that parameter data is available * (same flag cleared by APT:ReceiveParameter). * Inputs: - * 1 : Flag, when non-zero NS will compare the word after this one with a field in the NS state. + * 1 : Flag, when non-zero NS will compare the word after this one with a field in the NS + * state. * 2 : Unknown, this is the same as the first unknown field returned by APT:ReceiveParameter. - * 3 : Flag, when non-zero NS will compare the word after this one with a field in the NS state. + * 3 : Flag, when non-zero NS will compare the word after this one with a field in the NS + * state. * 4 : AppID * Outputs: * 0 : Return header diff --git a/src/core/hle/service/apt/apt_a.cpp b/src/core/hle/service/apt/apt_a.cpp index 6c44c491c..f27ad91b7 100644 --- a/src/core/hle/service/apt/apt_a.cpp +++ b/src/core/hle/service/apt/apt_a.cpp @@ -9,34 +9,34 @@ namespace Service { namespace APT { const Interface::FunctionInfo FunctionTable[] = { - {0x00010040, GetLockHandle, "GetLockHandle?"}, - {0x00020080, Initialize, "Initialize?"}, - {0x00030040, Enable, "Enable?"}, - {0x00040040, nullptr, "Finalize?"}, - {0x00050040, GetAppletManInfo, "GetAppletManInfo"}, - {0x00060040, GetAppletInfo, "GetAppletInfo"}, - {0x00090040, IsRegistered, "IsRegistered"}, - {0x000B0040, InquireNotification, "InquireNotification"}, - {0x000C0104, SendParameter, "SendParameter"}, - {0x000D0080, ReceiveParameter, "ReceiveParameter"}, - {0x000E0080, GlanceParameter, "GlanceParameter"}, - {0x000F0100, CancelParameter, "CancelParameter"}, - {0x00150140, PrepareToStartApplication, "PrepareToStartApplication"}, - {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"}, - {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, - {0x001E0084, StartLibraryApplet, "StartLibraryApplet"}, - {0x003B0040, nullptr, "CancelLibraryApplet?"}, - {0x003E0080, nullptr, "ReplySleepQuery"}, - {0x00430040, NotifyToWait, "NotifyToWait?"}, - {0x00440000, GetSharedFont, "GetSharedFont?"}, - {0x004B00C2, AppletUtility, "AppletUtility?"}, - {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, - {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, - {0x00510080, GetStartupArgument, "GetStartupArgument"}, - {0x00550040, SetScreenCapPostPermission, "SetScreenCapPostPermission"}, - {0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"}, - {0x01010000, CheckNew3DSApp, "CheckNew3DSApp"}, - {0x01020000, CheckNew3DS, "CheckNew3DS"} + {0x00010040, GetLockHandle, "GetLockHandle?"}, + {0x00020080, Initialize, "Initialize?"}, + {0x00030040, Enable, "Enable?"}, + {0x00040040, nullptr, "Finalize?"}, + {0x00050040, GetAppletManInfo, "GetAppletManInfo"}, + {0x00060040, GetAppletInfo, "GetAppletInfo"}, + {0x00090040, IsRegistered, "IsRegistered"}, + {0x000B0040, InquireNotification, "InquireNotification"}, + {0x000C0104, SendParameter, "SendParameter"}, + {0x000D0080, ReceiveParameter, "ReceiveParameter"}, + {0x000E0080, GlanceParameter, "GlanceParameter"}, + {0x000F0100, CancelParameter, "CancelParameter"}, + {0x00150140, PrepareToStartApplication, "PrepareToStartApplication"}, + {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"}, + {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, + {0x001E0084, StartLibraryApplet, "StartLibraryApplet"}, + {0x003B0040, nullptr, "CancelLibraryApplet?"}, + {0x003E0080, nullptr, "ReplySleepQuery"}, + {0x00430040, NotifyToWait, "NotifyToWait?"}, + {0x00440000, GetSharedFont, "GetSharedFont?"}, + {0x004B00C2, AppletUtility, "AppletUtility?"}, + {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, + {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, + {0x00510080, GetStartupArgument, "GetStartupArgument"}, + {0x00550040, SetScreenCapPostPermission, "SetScreenCapPostPermission"}, + {0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"}, + {0x01010000, CheckNew3DSApp, "CheckNew3DSApp"}, + {0x01020000, CheckNew3DS, "CheckNew3DS"}, }; APT_A_Interface::APT_A_Interface() { diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp index c70f2201f..c4556a5de 100644 --- a/src/core/hle/service/apt/apt_s.cpp +++ b/src/core/hle/service/apt/apt_s.cpp @@ -9,94 +9,94 @@ namespace Service { namespace APT { const Interface::FunctionInfo FunctionTable[] = { - {0x00010040, GetLockHandle, "GetLockHandle"}, - {0x00020080, Initialize, "Initialize"}, - {0x00030040, Enable, "Enable"}, - {0x00040040, nullptr, "Finalize"}, - {0x00050040, GetAppletManInfo, "GetAppletManInfo"}, - {0x00060040, GetAppletInfo, "GetAppletInfo"}, - {0x00070000, nullptr, "GetLastSignaledAppletId"}, - {0x00080000, nullptr, "CountRegisteredApplet"}, - {0x00090040, nullptr, "IsRegistered"}, - {0x000A0040, nullptr, "GetAttribute"}, - {0x000B0040, InquireNotification, "InquireNotification"}, - {0x000C0104, nullptr, "SendParameter"}, - {0x000D0080, ReceiveParameter, "ReceiveParameter"}, - {0x000E0080, GlanceParameter, "GlanceParameter"}, - {0x000F0100, nullptr, "CancelParameter"}, - {0x001000C2, nullptr, "DebugFunc"}, - {0x001100C0, nullptr, "MapProgramIdForDebug"}, - {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"}, - {0x00130000, nullptr, "GetPreparationState"}, - {0x00140040, nullptr, "SetPreparationState"}, + {0x00010040, GetLockHandle, "GetLockHandle"}, + {0x00020080, Initialize, "Initialize"}, + {0x00030040, Enable, "Enable"}, + {0x00040040, nullptr, "Finalize"}, + {0x00050040, GetAppletManInfo, "GetAppletManInfo"}, + {0x00060040, GetAppletInfo, "GetAppletInfo"}, + {0x00070000, nullptr, "GetLastSignaledAppletId"}, + {0x00080000, nullptr, "CountRegisteredApplet"}, + {0x00090040, nullptr, "IsRegistered"}, + {0x000A0040, nullptr, "GetAttribute"}, + {0x000B0040, InquireNotification, "InquireNotification"}, + {0x000C0104, nullptr, "SendParameter"}, + {0x000D0080, ReceiveParameter, "ReceiveParameter"}, + {0x000E0080, GlanceParameter, "GlanceParameter"}, + {0x000F0100, nullptr, "CancelParameter"}, + {0x001000C2, nullptr, "DebugFunc"}, + {0x001100C0, nullptr, "MapProgramIdForDebug"}, + {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"}, + {0x00130000, nullptr, "GetPreparationState"}, + {0x00140040, nullptr, "SetPreparationState"}, {0x00150140, PrepareToStartApplication, "PrepareToStartApplication"}, - {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"}, - {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, - {0x00180040, PrepareToStartLibraryApplet,"PrepareToStartLibraryApplet"}, - {0x00190040, nullptr, "PrepareToStartSystemApplet"}, - {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"}, - {0x001B00C4, nullptr, "StartApplication"}, - {0x001C0000, nullptr, "WakeupApplication"}, - {0x001D0000, nullptr, "CancelApplication"}, - {0x001E0084, nullptr, "StartLibraryApplet"}, - {0x001F0084, nullptr, "StartSystemApplet"}, - {0x00200044, nullptr, "StartNewestHomeMenu"}, - {0x00210000, nullptr, "OrderToCloseApplication"}, - {0x00220040, nullptr, "PrepareToCloseApplication"}, - {0x00230040, nullptr, "PrepareToJumpToApplication"}, - {0x00240044, nullptr, "JumpToApplication"}, - {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"}, - {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, - {0x00270044, nullptr, "CloseApplication"}, - {0x00280044, nullptr, "CloseLibraryApplet"}, - {0x00290044, nullptr, "CloseSystemApplet"}, - {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, - {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"}, - {0x002C0044, nullptr, "JumpToHomeMenu"}, - {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"}, - {0x002E0044, nullptr, "LeaveHomeMenu"}, - {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, - {0x00300044, nullptr, "LeaveResidentApplet"}, - {0x00310100, nullptr, "PrepareToDoApplicationJump"}, - {0x00320084, nullptr, "DoApplicationJump"}, - {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, - {0x00340084, nullptr, "SendDeliverArg"}, - {0x00350080, nullptr, "ReceiveDeliverArg"}, - {0x00360040, nullptr, "LoadSysMenuArg"}, - {0x00370042, nullptr, "StoreSysMenuArg"}, - {0x00380040, nullptr, "PreloadResidentApplet"}, - {0x00390040, nullptr, "PrepareToStartResidentApplet"}, - {0x003A0044, nullptr, "StartResidentApplet"}, - {0x003B0040, nullptr, "CancelLibraryApplet"}, - {0x003C0042, nullptr, "SendDspSleep"}, - {0x003D0042, nullptr, "SendDspWakeUp"}, - {0x003E0080, nullptr, "ReplySleepQuery"}, - {0x003F0040, nullptr, "ReplySleepNotificationComplete"}, - {0x00400042, nullptr, "SendCaptureBufferInfo"}, - {0x00410040, nullptr, "ReceiveCaptureBufferInfo"}, - {0x00420080, nullptr, "SleepSystem"}, - {0x00430040, NotifyToWait, "NotifyToWait"}, - {0x00440000, GetSharedFont, "GetSharedFont"}, - {0x00450040, nullptr, "GetWirelessRebootInfo"}, - {0x00460104, nullptr, "Wrap"}, - {0x00470104, nullptr, "Unwrap"}, - {0x00480100, nullptr, "GetProgramInfo"}, - {0x00490180, nullptr, "Reboot"}, - {0x004A0040, nullptr, "GetCaptureInfo"}, - {0x004B00C2, AppletUtility, "AppletUtility"}, - {0x004C0000, nullptr, "SetFatalErrDispMode"}, - {0x004D0080, nullptr, "GetAppletProgramInfo"}, - {0x004E0000, nullptr, "HardwareResetAsync"}, - {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, - {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, - {0x00510080, GetStartupArgument, "GetStartupArgument"}, - {0x00520104, nullptr, "Wrap1"}, - {0x00530104, nullptr, "Unwrap1"}, + {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"}, + {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, + {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, + {0x00190040, nullptr, "PrepareToStartSystemApplet"}, + {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"}, + {0x001B00C4, nullptr, "StartApplication"}, + {0x001C0000, nullptr, "WakeupApplication"}, + {0x001D0000, nullptr, "CancelApplication"}, + {0x001E0084, nullptr, "StartLibraryApplet"}, + {0x001F0084, nullptr, "StartSystemApplet"}, + {0x00200044, nullptr, "StartNewestHomeMenu"}, + {0x00210000, nullptr, "OrderToCloseApplication"}, + {0x00220040, nullptr, "PrepareToCloseApplication"}, + {0x00230040, nullptr, "PrepareToJumpToApplication"}, + {0x00240044, nullptr, "JumpToApplication"}, + {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"}, + {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, + {0x00270044, nullptr, "CloseApplication"}, + {0x00280044, nullptr, "CloseLibraryApplet"}, + {0x00290044, nullptr, "CloseSystemApplet"}, + {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, + {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"}, + {0x002C0044, nullptr, "JumpToHomeMenu"}, + {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"}, + {0x002E0044, nullptr, "LeaveHomeMenu"}, + {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, + {0x00300044, nullptr, "LeaveResidentApplet"}, + {0x00310100, nullptr, "PrepareToDoApplicationJump"}, + {0x00320084, nullptr, "DoApplicationJump"}, + {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, + {0x00340084, nullptr, "SendDeliverArg"}, + {0x00350080, nullptr, "ReceiveDeliverArg"}, + {0x00360040, nullptr, "LoadSysMenuArg"}, + {0x00370042, nullptr, "StoreSysMenuArg"}, + {0x00380040, nullptr, "PreloadResidentApplet"}, + {0x00390040, nullptr, "PrepareToStartResidentApplet"}, + {0x003A0044, nullptr, "StartResidentApplet"}, + {0x003B0040, nullptr, "CancelLibraryApplet"}, + {0x003C0042, nullptr, "SendDspSleep"}, + {0x003D0042, nullptr, "SendDspWakeUp"}, + {0x003E0080, nullptr, "ReplySleepQuery"}, + {0x003F0040, nullptr, "ReplySleepNotificationComplete"}, + {0x00400042, nullptr, "SendCaptureBufferInfo"}, + {0x00410040, nullptr, "ReceiveCaptureBufferInfo"}, + {0x00420080, nullptr, "SleepSystem"}, + {0x00430040, NotifyToWait, "NotifyToWait"}, + {0x00440000, GetSharedFont, "GetSharedFont"}, + {0x00450040, nullptr, "GetWirelessRebootInfo"}, + {0x00460104, nullptr, "Wrap"}, + {0x00470104, nullptr, "Unwrap"}, + {0x00480100, nullptr, "GetProgramInfo"}, + {0x00490180, nullptr, "Reboot"}, + {0x004A0040, nullptr, "GetCaptureInfo"}, + {0x004B00C2, AppletUtility, "AppletUtility"}, + {0x004C0000, nullptr, "SetFatalErrDispMode"}, + {0x004D0080, nullptr, "GetAppletProgramInfo"}, + {0x004E0000, nullptr, "HardwareResetAsync"}, + {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, + {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, + {0x00510080, GetStartupArgument, "GetStartupArgument"}, + {0x00520104, nullptr, "Wrap1"}, + {0x00530104, nullptr, "Unwrap1"}, {0x00550040, SetScreenCapPostPermission, "SetScreenCapPostPermission"}, {0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"}, - {0x00580002, nullptr, "GetProgramID"}, - {0x01010000, CheckNew3DSApp, "CheckNew3DSApp"}, - {0x01020000, CheckNew3DS, "CheckNew3DS"} + {0x00580002, nullptr, "GetProgramID"}, + {0x01010000, CheckNew3DSApp, "CheckNew3DSApp"}, + {0x01020000, CheckNew3DS, "CheckNew3DS"}, }; APT_S_Interface::APT_S_Interface() { diff --git a/src/core/hle/service/apt/apt_u.cpp b/src/core/hle/service/apt/apt_u.cpp index 7bb804ffa..d6ad42e21 100644 --- a/src/core/hle/service/apt/apt_u.cpp +++ b/src/core/hle/service/apt/apt_u.cpp @@ -9,94 +9,94 @@ namespace Service { namespace APT { const Interface::FunctionInfo FunctionTable[] = { - {0x00010040, GetLockHandle, "GetLockHandle"}, - {0x00020080, Initialize, "Initialize"}, - {0x00030040, Enable, "Enable"}, - {0x00040040, nullptr, "Finalize"}, - {0x00050040, GetAppletManInfo, "GetAppletManInfo"}, - {0x00060040, GetAppletInfo, "GetAppletInfo"}, - {0x00070000, nullptr, "GetLastSignaledAppletId"}, - {0x00080000, nullptr, "CountRegisteredApplet"}, - {0x00090040, IsRegistered, "IsRegistered"}, - {0x000A0040, nullptr, "GetAttribute"}, - {0x000B0040, InquireNotification, "InquireNotification"}, - {0x000C0104, SendParameter, "SendParameter"}, - {0x000D0080, ReceiveParameter, "ReceiveParameter"}, - {0x000E0080, GlanceParameter, "GlanceParameter"}, - {0x000F0100, CancelParameter, "CancelParameter"}, - {0x001000C2, nullptr, "DebugFunc"}, - {0x001100C0, nullptr, "MapProgramIdForDebug"}, - {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"}, - {0x00130000, nullptr, "GetPreparationState"}, - {0x00140040, nullptr, "SetPreparationState"}, - {0x00150140, PrepareToStartApplication, "PrepareToStartApplication"}, - {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"}, - {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, - {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, - {0x00190040, nullptr, "PrepareToStartSystemApplet"}, - {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"}, - {0x001B00C4, nullptr, "StartApplication"}, - {0x001C0000, nullptr, "WakeupApplication"}, - {0x001D0000, nullptr, "CancelApplication"}, - {0x001E0084, StartLibraryApplet, "StartLibraryApplet"}, - {0x001F0084, nullptr, "StartSystemApplet"}, - {0x00200044, nullptr, "StartNewestHomeMenu"}, - {0x00210000, nullptr, "OrderToCloseApplication"}, - {0x00220040, nullptr, "PrepareToCloseApplication"}, - {0x00230040, nullptr, "PrepareToJumpToApplication"}, - {0x00240044, nullptr, "JumpToApplication"}, - {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"}, - {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, - {0x00270044, nullptr, "CloseApplication"}, - {0x00280044, nullptr, "CloseLibraryApplet"}, - {0x00290044, nullptr, "CloseSystemApplet"}, - {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, - {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"}, - {0x002C0044, nullptr, "JumpToHomeMenu"}, - {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"}, - {0x002E0044, nullptr, "LeaveHomeMenu"}, - {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, - {0x00300044, nullptr, "LeaveResidentApplet"}, - {0x00310100, nullptr, "PrepareToDoApplicationJump"}, - {0x00320084, nullptr, "DoApplicationJump"}, - {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, - {0x00340084, nullptr, "SendDeliverArg"}, - {0x00350080, nullptr, "ReceiveDeliverArg"}, - {0x00360040, nullptr, "LoadSysMenuArg"}, - {0x00370042, nullptr, "StoreSysMenuArg"}, - {0x00380040, nullptr, "PreloadResidentApplet"}, - {0x00390040, nullptr, "PrepareToStartResidentApplet"}, - {0x003A0044, nullptr, "StartResidentApplet"}, - {0x003B0040, nullptr, "CancelLibraryApplet"}, - {0x003C0042, nullptr, "SendDspSleep"}, - {0x003D0042, nullptr, "SendDspWakeUp"}, - {0x003E0080, nullptr, "ReplySleepQuery"}, - {0x003F0040, nullptr, "ReplySleepNotificationComplete"}, - {0x00400042, nullptr, "SendCaptureBufferInfo"}, - {0x00410040, nullptr, "ReceiveCaptureBufferInfo"}, - {0x00420080, nullptr, "SleepSystem"}, - {0x00430040, NotifyToWait, "NotifyToWait"}, - {0x00440000, GetSharedFont, "GetSharedFont"}, - {0x00450040, nullptr, "GetWirelessRebootInfo"}, - {0x00460104, nullptr, "Wrap"}, - {0x00470104, nullptr, "Unwrap"}, - {0x00480100, nullptr, "GetProgramInfo"}, - {0x00490180, nullptr, "Reboot"}, - {0x004A0040, nullptr, "GetCaptureInfo"}, - {0x004B00C2, AppletUtility, "AppletUtility"}, - {0x004C0000, nullptr, "SetFatalErrDispMode"}, - {0x004D0080, nullptr, "GetAppletProgramInfo"}, - {0x004E0000, nullptr, "HardwareResetAsync"}, - {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, - {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, - {0x00510080, GetStartupArgument, "GetStartupArgument"}, - {0x00520104, nullptr, "Wrap1"}, - {0x00530104, nullptr, "Unwrap1"}, - {0x00550040, SetScreenCapPostPermission, "SetScreenCapPostPermission"}, - {0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"}, - {0x00580002, nullptr, "GetProgramID"}, - {0x01010000, CheckNew3DSApp, "CheckNew3DSApp"}, - {0x01020000, CheckNew3DS, "CheckNew3DS"} + {0x00010040, GetLockHandle, "GetLockHandle"}, + {0x00020080, Initialize, "Initialize"}, + {0x00030040, Enable, "Enable"}, + {0x00040040, nullptr, "Finalize"}, + {0x00050040, GetAppletManInfo, "GetAppletManInfo"}, + {0x00060040, GetAppletInfo, "GetAppletInfo"}, + {0x00070000, nullptr, "GetLastSignaledAppletId"}, + {0x00080000, nullptr, "CountRegisteredApplet"}, + {0x00090040, IsRegistered, "IsRegistered"}, + {0x000A0040, nullptr, "GetAttribute"}, + {0x000B0040, InquireNotification, "InquireNotification"}, + {0x000C0104, SendParameter, "SendParameter"}, + {0x000D0080, ReceiveParameter, "ReceiveParameter"}, + {0x000E0080, GlanceParameter, "GlanceParameter"}, + {0x000F0100, CancelParameter, "CancelParameter"}, + {0x001000C2, nullptr, "DebugFunc"}, + {0x001100C0, nullptr, "MapProgramIdForDebug"}, + {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"}, + {0x00130000, nullptr, "GetPreparationState"}, + {0x00140040, nullptr, "SetPreparationState"}, + {0x00150140, PrepareToStartApplication, "PrepareToStartApplication"}, + {0x00160040, PreloadLibraryApplet, "PreloadLibraryApplet"}, + {0x00170040, nullptr, "FinishPreloadingLibraryApplet"}, + {0x00180040, PrepareToStartLibraryApplet, "PrepareToStartLibraryApplet"}, + {0x00190040, nullptr, "PrepareToStartSystemApplet"}, + {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"}, + {0x001B00C4, nullptr, "StartApplication"}, + {0x001C0000, nullptr, "WakeupApplication"}, + {0x001D0000, nullptr, "CancelApplication"}, + {0x001E0084, StartLibraryApplet, "StartLibraryApplet"}, + {0x001F0084, nullptr, "StartSystemApplet"}, + {0x00200044, nullptr, "StartNewestHomeMenu"}, + {0x00210000, nullptr, "OrderToCloseApplication"}, + {0x00220040, nullptr, "PrepareToCloseApplication"}, + {0x00230040, nullptr, "PrepareToJumpToApplication"}, + {0x00240044, nullptr, "JumpToApplication"}, + {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"}, + {0x00260000, nullptr, "PrepareToCloseSystemApplet"}, + {0x00270044, nullptr, "CloseApplication"}, + {0x00280044, nullptr, "CloseLibraryApplet"}, + {0x00290044, nullptr, "CloseSystemApplet"}, + {0x002A0000, nullptr, "OrderToCloseSystemApplet"}, + {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"}, + {0x002C0044, nullptr, "JumpToHomeMenu"}, + {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"}, + {0x002E0044, nullptr, "LeaveHomeMenu"}, + {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"}, + {0x00300044, nullptr, "LeaveResidentApplet"}, + {0x00310100, nullptr, "PrepareToDoApplicationJump"}, + {0x00320084, nullptr, "DoApplicationJump"}, + {0x00330000, nullptr, "GetProgramIdOnApplicationJump"}, + {0x00340084, nullptr, "SendDeliverArg"}, + {0x00350080, nullptr, "ReceiveDeliverArg"}, + {0x00360040, nullptr, "LoadSysMenuArg"}, + {0x00370042, nullptr, "StoreSysMenuArg"}, + {0x00380040, nullptr, "PreloadResidentApplet"}, + {0x00390040, nullptr, "PrepareToStartResidentApplet"}, + {0x003A0044, nullptr, "StartResidentApplet"}, + {0x003B0040, nullptr, "CancelLibraryApplet"}, + {0x003C0042, nullptr, "SendDspSleep"}, + {0x003D0042, nullptr, "SendDspWakeUp"}, + {0x003E0080, nullptr, "ReplySleepQuery"}, + {0x003F0040, nullptr, "ReplySleepNotificationComplete"}, + {0x00400042, nullptr, "SendCaptureBufferInfo"}, + {0x00410040, nullptr, "ReceiveCaptureBufferInfo"}, + {0x00420080, nullptr, "SleepSystem"}, + {0x00430040, NotifyToWait, "NotifyToWait"}, + {0x00440000, GetSharedFont, "GetSharedFont"}, + {0x00450040, nullptr, "GetWirelessRebootInfo"}, + {0x00460104, nullptr, "Wrap"}, + {0x00470104, nullptr, "Unwrap"}, + {0x00480100, nullptr, "GetProgramInfo"}, + {0x00490180, nullptr, "Reboot"}, + {0x004A0040, nullptr, "GetCaptureInfo"}, + {0x004B00C2, AppletUtility, "AppletUtility"}, + {0x004C0000, nullptr, "SetFatalErrDispMode"}, + {0x004D0080, nullptr, "GetAppletProgramInfo"}, + {0x004E0000, nullptr, "HardwareResetAsync"}, + {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, + {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, + {0x00510080, GetStartupArgument, "GetStartupArgument"}, + {0x00520104, nullptr, "Wrap1"}, + {0x00530104, nullptr, "Unwrap1"}, + {0x00550040, SetScreenCapPostPermission, "SetScreenCapPostPermission"}, + {0x00560000, GetScreenCapPostPermission, "GetScreenCapPostPermission"}, + {0x00580002, nullptr, "GetProgramID"}, + {0x01010000, CheckNew3DSApp, "CheckNew3DSApp"}, + {0x01020000, CheckNew3DS, "CheckNew3DS"}, }; APT_U_Interface::APT_U_Interface() { diff --git a/src/core/hle/service/apt/bcfnt/bcfnt.h b/src/core/hle/service/apt/bcfnt/bcfnt.h index 8936dcf63..453bf7606 100644 --- a/src/core/hle/service/apt/bcfnt/bcfnt.h +++ b/src/core/hle/service/apt/bcfnt/bcfnt.h @@ -5,7 +5,6 @@ #pragma once #include "common/swap.h" - #include "core/hle/kernel/shared_memory.h" #include "core/hle/service/service.h" diff --git a/src/core/hle/service/boss/boss.cpp b/src/core/hle/service/boss/boss.cpp index 419ec976e..757a8c2c7 100644 --- a/src/core/hle/service/boss/boss.cpp +++ b/src/core/hle/service/boss/boss.cpp @@ -2,10 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/service.h" #include "core/hle/service/boss/boss.h" #include "core/hle/service/boss/boss_p.h" #include "core/hle/service/boss/boss_u.h" +#include "core/hle/service/service.h" namespace Service { namespace BOSS { @@ -17,8 +17,7 @@ void Init() { AddService(new BOSS_U_Interface); } -void Shutdown() { -} +void Shutdown() {} } // namespace BOSS diff --git a/src/core/hle/service/boss/boss_p.cpp b/src/core/hle/service/boss/boss_p.cpp index c498abe4e..dfee8d055 100644 --- a/src/core/hle/service/boss/boss_p.cpp +++ b/src/core/hle/service/boss/boss_p.cpp @@ -11,7 +11,7 @@ namespace BOSS { // const Interface::FunctionInfo FunctionTable[] = { }; BOSS_P_Interface::BOSS_P_Interface() { - //Register(FunctionTable); + // Register(FunctionTable); } } // namespace BOSS diff --git a/src/core/hle/service/boss/boss_u.cpp b/src/core/hle/service/boss/boss_u.cpp index d59babe71..6affa23b1 100644 --- a/src/core/hle/service/boss/boss_u.cpp +++ b/src/core/hle/service/boss/boss_u.cpp @@ -8,10 +8,10 @@ namespace Service { namespace BOSS { const Interface::FunctionInfo FunctionTable[] = { - {0x00020100, nullptr, "GetStorageInfo"}, - {0x000C0082, nullptr, "UnregisterTask"}, - {0x001E0042, nullptr, "CancelTask"}, - {0x00330042, nullptr, "StartBgImmediate"}, + {0x00020100, nullptr, "GetStorageInfo"}, + {0x000C0082, nullptr, "UnregisterTask"}, + {0x001E0042, nullptr, "CancelTask"}, + {0x00330042, nullptr, "StartBgImmediate"}, }; BOSS_U_Interface::BOSS_U_Interface() { diff --git a/src/core/hle/service/cam/cam.cpp b/src/core/hle/service/cam/cam.cpp index 6edcf9610..5594aedab 100644 --- a/src/core/hle/service/cam/cam.cpp +++ b/src/core/hle/service/cam/cam.cpp @@ -3,7 +3,6 @@ // Refer to the license.txt file included. #include "common/logging/log.h" - #include "core/hle/kernel/event.h" #include "core/hle/service/cam/cam.h" #include "core/hle/service/cam/cam_c.h" @@ -71,15 +70,15 @@ void GetBufferErrorInterruptEvent(Service::Interface* self) { } void SetReceiving(Service::Interface* self) { - u32* cmd_buff = Kernel::GetCommandBuffer(); + u32* cmd_buff = Kernel::GetCommandBuffer(); - VAddr dest = cmd_buff[1]; - u8 port = cmd_buff[2] & 0xFF; + VAddr dest = cmd_buff[1]; + u8 port = cmd_buff[2] & 0xFF; u32 image_size = cmd_buff[3]; u16 trans_unit = cmd_buff[4] & 0xFFFF; - Kernel::Event* completion_event = (Port)port == Port::Cam2 ? - completion_event_cam2.get() : completion_event_cam1.get(); + Kernel::Event* completion_event = + (Port)port == Port::Cam2 ? completion_event_cam2.get() : completion_event_cam1.get(); completion_event->Signal(); @@ -89,36 +88,36 @@ void SetReceiving(Service::Interface* self) { cmd_buff[3] = Kernel::g_handle_table.Create(completion_event).MoveFrom(); LOG_WARNING(Service_CAM, "(STUBBED) called, addr=0x%X, port=%d, image_size=%d, trans_unit=%d", - dest, port, image_size, trans_unit); + dest, port, image_size, trans_unit); } void SetTransferLines(Service::Interface* self) { - u32* cmd_buff = Kernel::GetCommandBuffer(); + u32* cmd_buff = Kernel::GetCommandBuffer(); - u8 port = cmd_buff[1] & 0xFF; + u8 port = cmd_buff[1] & 0xFF; u16 transfer_lines = cmd_buff[2] & 0xFFFF; - u16 width = cmd_buff[3] & 0xFFFF; - u16 height = cmd_buff[4] & 0xFFFF; + u16 width = cmd_buff[3] & 0xFFFF; + u16 height = cmd_buff[4] & 0xFFFF; cmd_buff[0] = IPC::MakeHeader(0x9, 1, 0); cmd_buff[1] = RESULT_SUCCESS.raw; - LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d, lines=%d, width=%d, height=%d", - port, transfer_lines, width, height); + LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d, lines=%d, width=%d, height=%d", port, + transfer_lines, width, height); } void GetMaxLines(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - u16 width = cmd_buff[1] & 0xFFFF; + u16 width = cmd_buff[1] & 0xFFFF; u16 height = cmd_buff[2] & 0xFFFF; cmd_buff[0] = IPC::MakeHeader(0xA, 2, 0); cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[2] = TRANSFER_BYTES / (2 * width); - LOG_WARNING(Service_CAM, "(STUBBED) called, width=%d, height=%d, lines = %d", - width, height, cmd_buff[2]); + LOG_WARNING(Service_CAM, "(STUBBED) called, width=%d, height=%d, lines = %d", width, height, + cmd_buff[2]); } void GetTransferBytes(Service::Interface* self) { @@ -136,7 +135,7 @@ void GetTransferBytes(Service::Interface* self) { void SetTrimming(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - u8 port = cmd_buff[1] & 0xFF; + u8 port = cmd_buff[1] & 0xFF; bool trim = (cmd_buff[2] & 0xFF) != 0; cmd_buff[0] = IPC::MakeHeader(0xE, 1, 0); @@ -148,17 +147,17 @@ void SetTrimming(Service::Interface* self) { void SetTrimmingParamsCenter(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - u8 port = cmd_buff[1] & 0xFF; + u8 port = cmd_buff[1] & 0xFF; s16 trimW = cmd_buff[2] & 0xFFFF; s16 trimH = cmd_buff[3] & 0xFFFF; - s16 camW = cmd_buff[4] & 0xFFFF; - s16 camH = cmd_buff[5] & 0xFFFF; + s16 camW = cmd_buff[4] & 0xFFFF; + s16 camH = cmd_buff[5] & 0xFFFF; cmd_buff[0] = IPC::MakeHeader(0x12, 1, 0); cmd_buff[1] = RESULT_SUCCESS.raw; LOG_WARNING(Service_CAM, "(STUBBED) called, port=%d, trimW=%d, trimH=%d, camW=%d, camH=%d", - port, trimW, trimH, camW, camH); + port, trimW, trimH, camW, camH); } void Activate(Service::Interface* self) { @@ -169,36 +168,35 @@ void Activate(Service::Interface* self) { cmd_buff[0] = IPC::MakeHeader(0x13, 1, 0); cmd_buff[1] = RESULT_SUCCESS.raw; - LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d", - cam_select); + LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d", cam_select); } void FlipImage(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u8 cam_select = cmd_buff[1] & 0xFF; - u8 flip = cmd_buff[2] & 0xFF; - u8 context = cmd_buff[3] & 0xFF; + u8 flip = cmd_buff[2] & 0xFF; + u8 context = cmd_buff[3] & 0xFF; cmd_buff[0] = IPC::MakeHeader(0x1D, 1, 0); cmd_buff[1] = RESULT_SUCCESS.raw; - LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d, flip=%d, context=%d", - cam_select, flip, context); + LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d, flip=%d, context=%d", cam_select, + flip, context); } void SetSize(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u8 cam_select = cmd_buff[1] & 0xFF; - u8 size = cmd_buff[2] & 0xFF; - u8 context = cmd_buff[3] & 0xFF; + u8 size = cmd_buff[2] & 0xFF; + u8 context = cmd_buff[3] & 0xFF; cmd_buff[0] = IPC::MakeHeader(0x1F, 1, 0); cmd_buff[1] = RESULT_SUCCESS.raw; - LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d, size=%d, context=%d", - cam_select, size, context); + LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d, size=%d, context=%d", cam_select, + size, context); } void SetFrameRate(Service::Interface* self) { @@ -210,8 +208,8 @@ void SetFrameRate(Service::Interface* self) { cmd_buff[0] = IPC::MakeHeader(0x20, 1, 0); cmd_buff[1] = RESULT_SUCCESS.raw; - LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d, frame_rate=%d", - cam_select, frame_rate); + LOG_WARNING(Service_CAM, "(STUBBED) called, cam_select=%d, frame_rate=%d", cam_select, + frame_rate); } void GetStereoCameraCalibrationData(Service::Interface* self) { @@ -293,10 +291,14 @@ void Init() { AddService(new CAM_S_Interface); AddService(new CAM_U_Interface); - completion_event_cam1 = Kernel::Event::Create(ResetType::OneShot, "CAM_U::completion_event_cam1"); - completion_event_cam2 = Kernel::Event::Create(ResetType::OneShot, "CAM_U::completion_event_cam2"); - interrupt_error_event = Kernel::Event::Create(ResetType::OneShot, "CAM_U::interrupt_error_event"); - vsync_interrupt_error_event = Kernel::Event::Create(ResetType::OneShot, "CAM_U::vsync_interrupt_error_event"); + completion_event_cam1 = + Kernel::Event::Create(ResetType::OneShot, "CAM_U::completion_event_cam1"); + completion_event_cam2 = + Kernel::Event::Create(ResetType::OneShot, "CAM_U::completion_event_cam2"); + interrupt_error_event = + Kernel::Event::Create(ResetType::OneShot, "CAM_U::interrupt_error_event"); + vsync_interrupt_error_event = + Kernel::Event::Create(ResetType::OneShot, "CAM_U::vsync_interrupt_error_event"); } void Shutdown() { diff --git a/src/core/hle/service/cam/cam.h b/src/core/hle/service/cam/cam.h index 2f4923728..c9b6f8acf 100644 --- a/src/core/hle/service/cam/cam.h +++ b/src/core/hle/service/cam/cam.h @@ -7,19 +7,13 @@ #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" - #include "core/hle/kernel/kernel.h" #include "core/hle/service/service.h" namespace Service { namespace CAM { -enum class Port : u8 { - None = 0, - Cam1 = 1, - Cam2 = 2, - Both = Cam1 | Cam2 -}; +enum class Port : u8 { None = 0, Cam1 = 1, Cam2 = 2, Both = Cam1 | Cam2 }; enum class CameraSelect : u8 { None = 0, @@ -29,7 +23,7 @@ enum class CameraSelect : u8 { In1Out1 = Out1 | In1, Out1Out2 = Out1 | Out2, In1Out2 = In1 | Out2, - All = Out1 | In1 | Out2 + All = Out1 | In1 | Out2, }; enum class Effect : u8 { @@ -38,21 +32,21 @@ enum class Effect : u8 { Sepia = 2, Negative = 3, Negafilm = 4, - Sepia01 = 5 + Sepia01 = 5, }; enum class Context : u8 { None = 0, A = 1, B = 2, - Both = A | B + Both = A | B, }; enum class Flip : u8 { None = 0, Horizontal = 1, Vertical = 2, - Reverse = 3 + Reverse = 3, }; enum class Size : u8 { @@ -64,7 +58,7 @@ enum class Size : u8 { DS_LCD = 5, DS_LCDx4 = 6, CTR_TOP_LCD = 7, - CTR_BOTTOM_LCD = QVGA + CTR_BOTTOM_LCD = QVGA, }; enum class FrameRate : u8 { @@ -80,13 +74,13 @@ enum class FrameRate : u8 { Rate_30_To_5 = 9, Rate_15_To_10 = 10, Rate_20_To_10 = 11, - Rate_30_To_10 = 12 + Rate_30_To_10 = 12, }; enum class ShutterSoundType : u8 { Normal = 0, Movie = 1, - MovieEnd = 2 + MovieEnd = 2, }; enum class WhiteBalance : u8 { @@ -103,7 +97,7 @@ enum class WhiteBalance : u8 { BalanceDaylight = Balance5200K, BalanceCloudy = Balance6000K, BalanceHorizon = Balance6000K, - BalanceShade = Balance7000K + BalanceShade = Balance7000K, }; enum class PhotoMode : u8 { @@ -111,7 +105,7 @@ enum class PhotoMode : u8 { Portrait = 1, Landscape = 2, Nightview = 3, - Letter0 = 4 + Letter0 = 4, }; enum class LensCorrection : u8 { @@ -120,7 +114,7 @@ enum class LensCorrection : u8 { On90 = 2, Dark = Off, Normal = On70, - Bright = On90 + Bright = On90, }; enum class Contrast : u8 { @@ -137,24 +131,24 @@ enum class Contrast : u8 { Pattern11 = 11, Low = Pattern05, Normal = Pattern06, - High = Pattern07 + High = Pattern07, }; enum class OutputFormat : u8 { YUV422 = 0, - RGB565 = 1 + RGB565 = 1, }; /// Stereo camera calibration data. struct StereoCameraCalibrationData { - u8 isValidRotationXY; ///< Bool indicating whether the X and Y rotation data is valid. + u8 isValidRotationXY; ///< Bool indicating whether the X and Y rotation data is valid. INSERT_PADDING_BYTES(3); - float_le scale; ///< Scale to match the left camera image with the right. - float_le rotationZ; ///< Z axis rotation to match the left camera image with the right. - float_le translationX; ///< X axis translation to match the left camera image with the right. - float_le translationY; ///< Y axis translation to match the left camera image with the right. - float_le rotationX; ///< X axis rotation to match the left camera image with the right. - float_le rotationY; ///< Y axis rotation to match the left camera image with the right. + float_le scale; ///< Scale to match the left camera image with the right. + float_le rotationZ; ///< Z axis rotation to match the left camera image with the right. + float_le translationX; ///< X axis translation to match the left camera image with the right. + float_le translationY; ///< Y axis translation to match the left camera image with the right. + float_le rotationX; ///< X axis rotation to match the left camera image with the right. + float_le rotationY; ///< Y axis rotation to match the left camera image with the right. float_le angleOfViewRight; ///< Right camera angle of view. float_le angleOfViewLeft; ///< Left camera angle of view. float_le distanceToChart; ///< Distance between cameras and measurement chart. @@ -163,7 +157,8 @@ struct StereoCameraCalibrationData { s16_le imageHeight; ///< Image height. INSERT_PADDING_BYTES(16); }; -static_assert(sizeof(StereoCameraCalibrationData) == 64, "StereoCameraCalibrationData structure size is wrong"); +static_assert(sizeof(StereoCameraCalibrationData) == 64, + "StereoCameraCalibrationData structure size is wrong"); struct PackageParameterCameraSelect { CameraSelect camera; @@ -188,7 +183,8 @@ struct PackageParameterCameraSelect { s16 auto_white_balance_window_height; }; -static_assert(sizeof(PackageParameterCameraSelect) == 28, "PackageParameterCameraSelect structure size is wrong"); +static_assert(sizeof(PackageParameterCameraSelect) == 28, + "PackageParameterCameraSelect structure size is wrong"); /** * Unknown diff --git a/src/core/hle/service/cam/cam_c.cpp b/src/core/hle/service/cam/cam_c.cpp index 8fa7abc85..93b047c1a 100644 --- a/src/core/hle/service/cam/cam_c.cpp +++ b/src/core/hle/service/cam/cam_c.cpp @@ -8,10 +8,10 @@ namespace Service { namespace CAM { // Empty arrays are illegal -- commented out until an entry is added. -//const Interface::FunctionInfo FunctionTable[] = { }; +// const Interface::FunctionInfo FunctionTable[] = { }; CAM_C_Interface::CAM_C_Interface() { - //Register(FunctionTable); + // Register(FunctionTable); } } // namespace CAM diff --git a/src/core/hle/service/cam/cam_q.cpp b/src/core/hle/service/cam/cam_q.cpp index d3ba91e9d..2ba853606 100644 --- a/src/core/hle/service/cam/cam_q.cpp +++ b/src/core/hle/service/cam/cam_q.cpp @@ -8,10 +8,10 @@ namespace Service { namespace CAM { // Empty arrays are illegal -- commented out until an entry is added. -//const Interface::FunctionInfo FunctionTable[] = { }; +// const Interface::FunctionInfo FunctionTable[] = { }; CAM_Q_Interface::CAM_Q_Interface() { - //Register(FunctionTable); + // Register(FunctionTable); } } // namespace CAM diff --git a/src/core/hle/service/cam/cam_s.cpp b/src/core/hle/service/cam/cam_s.cpp index 2a13984d8..f1c6da587 100644 --- a/src/core/hle/service/cam/cam_s.cpp +++ b/src/core/hle/service/cam/cam_s.cpp @@ -8,10 +8,10 @@ namespace Service { namespace CAM { // Empty arrays are illegal -- commented out until an entry is added. -//const Interface::FunctionInfo FunctionTable[] = { }; +// const Interface::FunctionInfo FunctionTable[] = { }; CAM_S_Interface::CAM_S_Interface() { - //Register(FunctionTable); + // Register(FunctionTable); } } // namespace CAM diff --git a/src/core/hle/service/cam/cam_u.cpp b/src/core/hle/service/cam/cam_u.cpp index a1070ebb2..af2123e5b 100644 --- a/src/core/hle/service/cam/cam_u.cpp +++ b/src/core/hle/service/cam/cam_u.cpp @@ -9,68 +9,68 @@ namespace Service { namespace CAM { const Interface::FunctionInfo FunctionTable[] = { - {0x00010040, StartCapture, "StartCapture"}, - {0x00020040, StopCapture, "StopCapture"}, - {0x00030040, nullptr, "IsBusy"}, - {0x00040040, nullptr, "ClearBuffer"}, - {0x00050040, GetVsyncInterruptEvent, "GetVsyncInterruptEvent"}, - {0x00060040, GetBufferErrorInterruptEvent, "GetBufferErrorInterruptEvent"}, - {0x00070102, SetReceiving, "SetReceiving"}, - {0x00080040, nullptr, "IsFinishedReceiving"}, - {0x00090100, SetTransferLines, "SetTransferLines"}, - {0x000A0080, GetMaxLines, "GetMaxLines"}, - {0x000B0100, nullptr, "SetTransferBytes"}, - {0x000C0040, GetTransferBytes, "GetTransferBytes"}, - {0x000D0080, nullptr, "GetMaxBytes"}, - {0x000E0080, SetTrimming, "SetTrimming"}, - {0x000F0040, nullptr, "IsTrimming"}, - {0x00100140, nullptr, "SetTrimmingParams"}, - {0x00110040, nullptr, "GetTrimmingParams"}, - {0x00120140, SetTrimmingParamsCenter, "SetTrimmingParamsCenter"}, - {0x00130040, Activate, "Activate"}, - {0x00140080, nullptr, "SwitchContext"}, - {0x00150080, nullptr, "SetExposure"}, - {0x00160080, nullptr, "SetWhiteBalance"}, - {0x00170080, nullptr, "SetWhiteBalanceWithoutBaseUp"}, - {0x00180080, nullptr, "SetSharpness"}, - {0x00190080, nullptr, "SetAutoExposure"}, - {0x001A0040, nullptr, "IsAutoExposure"}, - {0x001B0080, nullptr, "SetAutoWhiteBalance"}, - {0x001C0040, nullptr, "IsAutoWhiteBalance"}, - {0x001D00C0, FlipImage, "FlipImage"}, - {0x001E0200, nullptr, "SetDetailSize"}, - {0x001F00C0, SetSize, "SetSize"}, - {0x00200080, SetFrameRate, "SetFrameRate"}, - {0x00210080, nullptr, "SetPhotoMode"}, - {0x002200C0, nullptr, "SetEffect"}, - {0x00230080, nullptr, "SetContrast"}, - {0x00240080, nullptr, "SetLensCorrection"}, - {0x002500C0, nullptr, "SetOutputFormat"}, - {0x00260140, nullptr, "SetAutoExposureWindow"}, - {0x00270140, nullptr, "SetAutoWhiteBalanceWindow"}, - {0x00280080, nullptr, "SetNoiseFilter"}, - {0x00290080, nullptr, "SynchronizeVsyncTiming"}, - {0x002A0080, nullptr, "GetLatestVsyncTiming"}, - {0x002B0000, GetStereoCameraCalibrationData, "GetStereoCameraCalibrationData"}, - {0x002C0400, nullptr, "SetStereoCameraCalibrationData"}, - {0x002D00C0, nullptr, "WriteRegisterI2c"}, - {0x002E00C0, nullptr, "WriteMcuVariableI2c"}, - {0x002F0080, nullptr, "ReadRegisterI2cExclusive"}, - {0x00300080, nullptr, "ReadMcuVariableI2cExclusive"}, - {0x00310180, nullptr, "SetImageQualityCalibrationData"}, - {0x00320000, nullptr, "GetImageQualityCalibrationData"}, - {0x003302C0, nullptr, "SetPackageParameterWithoutContext"}, - {0x00340140, nullptr, "SetPackageParameterWithContext"}, - {0x003501C0, nullptr, "SetPackageParameterWithContextDetail"}, - {0x00360000, GetSuitableY2rStandardCoefficient, "GetSuitableY2rStandardCoefficient"}, - {0x00370202, nullptr, "PlayShutterSoundWithWave"}, - {0x00380040, PlayShutterSound, "PlayShutterSound"}, - {0x00390000, DriverInitialize, "DriverInitialize"}, - {0x003A0000, DriverFinalize, "DriverFinalize"}, - {0x003B0000, nullptr, "GetActivatedCamera"}, - {0x003C0000, nullptr, "GetSleepCamera"}, - {0x003D0040, nullptr, "SetSleepCamera"}, - {0x003E0040, nullptr, "SetBrightnessSynchronization"}, + {0x00010040, StartCapture, "StartCapture"}, + {0x00020040, StopCapture, "StopCapture"}, + {0x00030040, nullptr, "IsBusy"}, + {0x00040040, nullptr, "ClearBuffer"}, + {0x00050040, GetVsyncInterruptEvent, "GetVsyncInterruptEvent"}, + {0x00060040, GetBufferErrorInterruptEvent, "GetBufferErrorInterruptEvent"}, + {0x00070102, SetReceiving, "SetReceiving"}, + {0x00080040, nullptr, "IsFinishedReceiving"}, + {0x00090100, SetTransferLines, "SetTransferLines"}, + {0x000A0080, GetMaxLines, "GetMaxLines"}, + {0x000B0100, nullptr, "SetTransferBytes"}, + {0x000C0040, GetTransferBytes, "GetTransferBytes"}, + {0x000D0080, nullptr, "GetMaxBytes"}, + {0x000E0080, SetTrimming, "SetTrimming"}, + {0x000F0040, nullptr, "IsTrimming"}, + {0x00100140, nullptr, "SetTrimmingParams"}, + {0x00110040, nullptr, "GetTrimmingParams"}, + {0x00120140, SetTrimmingParamsCenter, "SetTrimmingParamsCenter"}, + {0x00130040, Activate, "Activate"}, + {0x00140080, nullptr, "SwitchContext"}, + {0x00150080, nullptr, "SetExposure"}, + {0x00160080, nullptr, "SetWhiteBalance"}, + {0x00170080, nullptr, "SetWhiteBalanceWithoutBaseUp"}, + {0x00180080, nullptr, "SetSharpness"}, + {0x00190080, nullptr, "SetAutoExposure"}, + {0x001A0040, nullptr, "IsAutoExposure"}, + {0x001B0080, nullptr, "SetAutoWhiteBalance"}, + {0x001C0040, nullptr, "IsAutoWhiteBalance"}, + {0x001D00C0, FlipImage, "FlipImage"}, + {0x001E0200, nullptr, "SetDetailSize"}, + {0x001F00C0, SetSize, "SetSize"}, + {0x00200080, SetFrameRate, "SetFrameRate"}, + {0x00210080, nullptr, "SetPhotoMode"}, + {0x002200C0, nullptr, "SetEffect"}, + {0x00230080, nullptr, "SetContrast"}, + {0x00240080, nullptr, "SetLensCorrection"}, + {0x002500C0, nullptr, "SetOutputFormat"}, + {0x00260140, nullptr, "SetAutoExposureWindow"}, + {0x00270140, nullptr, "SetAutoWhiteBalanceWindow"}, + {0x00280080, nullptr, "SetNoiseFilter"}, + {0x00290080, nullptr, "SynchronizeVsyncTiming"}, + {0x002A0080, nullptr, "GetLatestVsyncTiming"}, + {0x002B0000, GetStereoCameraCalibrationData, "GetStereoCameraCalibrationData"}, + {0x002C0400, nullptr, "SetStereoCameraCalibrationData"}, + {0x002D00C0, nullptr, "WriteRegisterI2c"}, + {0x002E00C0, nullptr, "WriteMcuVariableI2c"}, + {0x002F0080, nullptr, "ReadRegisterI2cExclusive"}, + {0x00300080, nullptr, "ReadMcuVariableI2cExclusive"}, + {0x00310180, nullptr, "SetImageQualityCalibrationData"}, + {0x00320000, nullptr, "GetImageQualityCalibrationData"}, + {0x003302C0, nullptr, "SetPackageParameterWithoutContext"}, + {0x00340140, nullptr, "SetPackageParameterWithContext"}, + {0x003501C0, nullptr, "SetPackageParameterWithContextDetail"}, + {0x00360000, GetSuitableY2rStandardCoefficient, "GetSuitableY2rStandardCoefficient"}, + {0x00370202, nullptr, "PlayShutterSoundWithWave"}, + {0x00380040, PlayShutterSound, "PlayShutterSound"}, + {0x00390000, DriverInitialize, "DriverInitialize"}, + {0x003A0000, DriverFinalize, "DriverFinalize"}, + {0x003B0000, nullptr, "GetActivatedCamera"}, + {0x003C0000, nullptr, "GetSleepCamera"}, + {0x003D0040, nullptr, "SetSleepCamera"}, + {0x003E0040, nullptr, "SetBrightnessSynchronization"}, }; CAM_U_Interface::CAM_U_Interface() { diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index 50c03495e..515b344e6 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp @@ -3,12 +3,11 @@ // Refer to the license.txt file included. #include "common/logging/log.h" - #include "core/hle/kernel/event.h" -#include "core/hle/service/service.h" #include "core/hle/service/cecd/cecd.h" #include "core/hle/service/cecd/cecd_s.h" #include "core/hle/service/cecd/cecd_u.h" +#include "core/hle/service/service.h" namespace Service { namespace CECD { @@ -28,7 +27,7 @@ void GetCecStateAbbreviated(Service::Interface* self) { void GetCecInfoEventHandle(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - cmd_buff[1] = RESULT_SUCCESS.raw; // No error + cmd_buff[1] = RESULT_SUCCESS.raw; // No error cmd_buff[3] = Kernel::g_handle_table.Create(cecinfo_event).MoveFrom(); // Event handle LOG_WARNING(Service_CECD, "(STUBBED) called"); @@ -37,7 +36,7 @@ void GetCecInfoEventHandle(Service::Interface* self) { void GetChangeStateEventHandle(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - cmd_buff[1] = RESULT_SUCCESS.raw; // No error + cmd_buff[1] = RESULT_SUCCESS.raw; // No error cmd_buff[3] = Kernel::g_handle_table.Create(change_state_event).MoveFrom(); // Event handle LOG_WARNING(Service_CECD, "(STUBBED) called"); @@ -48,7 +47,8 @@ void Init() { AddService(new CECD_U_Interface); cecinfo_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "CECD_U::cecinfo_event"); - change_state_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "CECD_U::change_state_event"); + change_state_event = + Kernel::Event::Create(Kernel::ResetType::OneShot, "CECD_U::change_state_event"); } void Shutdown() { diff --git a/src/core/hle/service/cecd/cecd.h b/src/core/hle/service/cecd/cecd.h index 435611363..ea97f9266 100644 --- a/src/core/hle/service/cecd/cecd.h +++ b/src/core/hle/service/cecd/cecd.h @@ -11,11 +11,13 @@ class Interface; namespace CECD { enum class CecStateAbbreviated { - CEC_STATE_ABBREV_IDLE = 1, ///< Corresponds to CEC_STATE_IDLE + CEC_STATE_ABBREV_IDLE = 1, ///< Corresponds to CEC_STATE_IDLE CEC_STATE_ABBREV_NOT_LOCAL = 2, ///< Corresponds to CEC_STATEs *FINISH*, *POST, and OVER_BOSS - CEC_STATE_ABBREV_SCANNING = 3, ///< Corresponds to CEC_STATE_SCANNING - CEC_STATE_ABBREV_WLREADY = 4, ///< Corresponds to CEC_STATE_WIRELESS_READY when some unknown bool is true - CEC_STATE_ABBREV_OTHER = 5, ///< Corresponds to CEC_STATEs besides *FINISH*, *POST, and OVER_BOSS and those listed here + CEC_STATE_ABBREV_SCANNING = 3, ///< Corresponds to CEC_STATE_SCANNING + CEC_STATE_ABBREV_WLREADY = + 4, ///< Corresponds to CEC_STATE_WIRELESS_READY when some unknown bool is true + CEC_STATE_ABBREV_OTHER = 5, ///< Corresponds to CEC_STATEs besides *FINISH*, *POST, and + /// OVER_BOSS and those listed here }; /** diff --git a/src/core/hle/service/cecd/cecd_s.cpp b/src/core/hle/service/cecd/cecd_s.cpp index bfd821c07..7477b9320 100644 --- a/src/core/hle/service/cecd/cecd_s.cpp +++ b/src/core/hle/service/cecd/cecd_s.cpp @@ -8,10 +8,10 @@ namespace Service { namespace CECD { // Empty arrays are illegal -- commented out until an entry is added. -//const Interface::FunctionInfo FunctionTable[] = { }; +// const Interface::FunctionInfo FunctionTable[] = { }; CECD_S_Interface::CECD_S_Interface() { - //Register(FunctionTable); + // Register(FunctionTable); } } // namespace CECD diff --git a/src/core/hle/service/cecd/cecd_u.cpp b/src/core/hle/service/cecd/cecd_u.cpp index be6d4d8f6..4b747de7b 100644 --- a/src/core/hle/service/cecd/cecd_u.cpp +++ b/src/core/hle/service/cecd/cecd_u.cpp @@ -9,10 +9,10 @@ namespace Service { namespace CECD { static const Interface::FunctionInfo FunctionTable[] = { - {0x000E0000, GetCecStateAbbreviated, "GetCecStateAbbreviated"}, - {0x000F0000, GetCecInfoEventHandle, "GetCecInfoEventHandle"}, + {0x000E0000, GetCecStateAbbreviated, "GetCecStateAbbreviated"}, + {0x000F0000, GetCecInfoEventHandle, "GetCecInfoEventHandle"}, {0x00100000, GetChangeStateEventHandle, "GetChangeStateEventHandle"}, - {0x00120104, nullptr, "ReadSavedData"}, + {0x00120104, nullptr, "ReadSavedData"}, }; CECD_U_Interface::CECD_U_Interface() { diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index a5dc47322..24eee6903 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp @@ -3,15 +3,12 @@ // Refer to the license.txt file included. #include <algorithm> - #include "common/file_util.h" #include "common/logging/log.h" #include "common/string_util.h" #include "common/swap.h" - #include "core/file_sys/archive_systemsavedata.h" #include "core/file_sys/file_backend.h" -#include "core/settings.h" #include "core/hle/result.h" #include "core/hle/service/cfg/cfg.h" #include "core/hle/service/cfg/cfg_i.h" @@ -19,6 +16,7 @@ #include "core/hle/service/cfg/cfg_u.h" #include "core/hle/service/fs/archive.h" #include "core/hle/service/service.h" +#include "core/settings.h" namespace Service { namespace CFG { @@ -33,25 +31,29 @@ namespace { * contains information about the blocks in the file */ struct SaveFileConfig { - u16 total_entries; ///< The total number of set entries in the config file - u16 data_entries_offset; ///< The offset where the data for the blocks start, this is hardcoded to 0x455C as per hardware - SaveConfigBlockEntry block_entries[CONFIG_FILE_MAX_BLOCK_ENTRIES]; ///< The block headers, the maximum possible value is 1479 as per hardware - u32 unknown; ///< This field is unknown, possibly padding, 0 has been observed in hardware + u16 total_entries; ///< The total number of set entries in the config file + u16 data_entries_offset; ///< The offset where the data for the blocks start, this is hardcoded + /// to 0x455C as per hardware + SaveConfigBlockEntry block_entries[CONFIG_FILE_MAX_BLOCK_ENTRIES]; ///< The block headers, the + /// maximum possible value is + /// 1479 as per hardware + u32 unknown; ///< This field is unknown, possibly padding, 0 has been observed in hardware }; -static_assert(sizeof(SaveFileConfig) == 0x455C, "SaveFileConfig header must be exactly 0x455C bytes"); +static_assert(sizeof(SaveFileConfig) == 0x455C, + "SaveFileConfig header must be exactly 0x455C bytes"); enum ConfigBlockID { StereoCameraSettingsBlockID = 0x00050005, - SoundOutputModeBlockID = 0x00070001, - ConsoleUniqueIDBlockID = 0x00090001, - UsernameBlockID = 0x000A0000, - BirthdayBlockID = 0x000A0001, - LanguageBlockID = 0x000A0002, - CountryInfoBlockID = 0x000B0000, - CountryNameBlockID = 0x000B0001, - StateNameBlockID = 0x000B0002, - EULAVersionBlockID = 0x000D0000, - ConsoleModelBlockID = 0x000F0004, + SoundOutputModeBlockID = 0x00070001, + ConsoleUniqueIDBlockID = 0x00090001, + UsernameBlockID = 0x000A0000, + BirthdayBlockID = 0x000A0001, + LanguageBlockID = 0x000A0002, + CountryInfoBlockID = 0x000B0000, + CountryNameBlockID = 0x000B0001, + StateNameBlockID = 0x000B0002, + EULAVersionBlockID = 0x000D0000, + ConsoleModelBlockID = 0x000F0004, }; struct UsernameBlock { @@ -68,8 +70,8 @@ struct BirthdayBlock { static_assert(sizeof(BirthdayBlock) == 2, "BirthdayBlock must be exactly 2 bytes"); struct ConsoleModelInfo { - u8 model; ///< The console model (3DS, 2DS, etc) - u8 unknown[3]; ///< Unknown data + u8 model; ///< The console model (3DS, 2DS, etc) + u8 unknown[3]; ///< Unknown data }; static_assert(sizeof(ConsoleModelInfo) == 4, "ConsoleModelInfo must be exactly 4 bytes"); @@ -78,36 +80,38 @@ struct ConsoleCountryInfo { u8 country_code; ///< The country code of the console }; static_assert(sizeof(ConsoleCountryInfo) == 4, "ConsoleCountryInfo must be exactly 4 bytes"); - } static const u64 CFG_SAVE_ID = 0x00010017; static const u64 CONSOLE_UNIQUE_ID = 0xDEADC0DE; -static const ConsoleModelInfo CONSOLE_MODEL = { NINTENDO_3DS_XL, { 0, 0, 0 } }; +static const ConsoleModelInfo CONSOLE_MODEL = {NINTENDO_3DS_XL, {0, 0, 0}}; static const u8 CONSOLE_LANGUAGE = LANGUAGE_EN; -static const UsernameBlock CONSOLE_USERNAME_BLOCK = { u"CITRA", 0, 0 }; -static const BirthdayBlock PROFILE_BIRTHDAY = { 3, 25 }; // March 25th, 2014 +static const UsernameBlock CONSOLE_USERNAME_BLOCK = {u"CITRA", 0, 0}; +static const BirthdayBlock PROFILE_BIRTHDAY = {3, 25}; // March 25th, 2014 static const u8 SOUND_OUTPUT_MODE = SOUND_SURROUND; static const u8 UNITED_STATES_COUNTRY_ID = 49; /// TODO(Subv): Find what the other bytes are -static const ConsoleCountryInfo COUNTRY_INFO = { { 0, 0, 0 }, UNITED_STATES_COUNTRY_ID }; +static const ConsoleCountryInfo COUNTRY_INFO = {{0, 0, 0}, UNITED_STATES_COUNTRY_ID}; /** * TODO(Subv): Find out what this actually is, these values fix some NaN uniforms in some games, * for example Nintendo Zone * Thanks Normmatt for providing this information */ -static const std::array<float, 8> STEREO_CAMERA_SETTINGS = {{ +static const std::array<float, 8> STEREO_CAMERA_SETTINGS = { 62.0f, 289.0f, 76.80000305175781f, 46.08000183105469f, - 10.0f, 5.0f, 55.58000183105469f, 21.56999969482422f -}}; -static_assert(sizeof(STEREO_CAMERA_SETTINGS) == 0x20, "STEREO_CAMERA_SETTINGS must be exactly 0x20 bytes"); + 10.0f, 5.0f, 55.58000183105469f, 21.56999969482422f, +}; +static_assert(sizeof(STEREO_CAMERA_SETTINGS) == 0x20, + "STEREO_CAMERA_SETTINGS must be exactly 0x20 bytes"); static const u32 CONFIG_SAVEFILE_SIZE = 0x8000; static std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer; static Service::FS::ArchiveHandle cfg_system_save_data_archive; -static const std::vector<u8> cfg_system_savedata_id = { 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x01, 0x00 }; +static const std::vector<u8> cfg_system_savedata_id = { + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x01, 0x00, +}; void GetCountryCodeString(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); @@ -115,7 +119,9 @@ void GetCountryCodeString(Service::Interface* self) { if (country_code_id >= country_codes.size() || 0 == country_codes[country_code_id]) { LOG_ERROR(Service_CFG, "requested country code id=%d is invalid", country_code_id); - cmd_buff[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw; + cmd_buff[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Config, + ErrorSummary::WrongArgument, ErrorLevel::Permanent) + .raw; return; } @@ -139,8 +145,11 @@ void GetCountryCodeID(Service::Interface* self) { } if (0 == country_code_id) { - LOG_ERROR(Service_CFG, "requested country code name=%c%c is invalid", country_code & 0xff, country_code >> 8); - cmd_buff[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw; + LOG_ERROR(Service_CFG, "requested country code name=%c%c is invalid", country_code & 0xff, + country_code >> 8); + cmd_buff[1] = ResultCode(ErrorDescription::NotFound, ErrorModule::Config, + ErrorSummary::WrongArgument, ErrorLevel::Permanent) + .raw; cmd_buff[2] = 0xFFFF; return; } @@ -185,8 +194,8 @@ void GetSystemModel(Service::Interface* self) { u32 data; // TODO(Subv): Find out the correct error codes - cmd_buff[1] = Service::CFG::GetConfigInfoBlock(0x000F0004, 4, 0x8, - reinterpret_cast<u8*>(&data)).raw; + cmd_buff[1] = + Service::CFG::GetConfigInfoBlock(0x000F0004, 4, 0x8, reinterpret_cast<u8*>(&data)).raw; cmd_buff[2] = data & 0xFF; } @@ -195,8 +204,8 @@ void GetModelNintendo2DS(Service::Interface* self) { u32 data; // TODO(Subv): Find out the correct error codes - cmd_buff[1] = Service::CFG::GetConfigInfoBlock(0x000F0004, 4, 0x8, - reinterpret_cast<u8*>(&data)).raw; + cmd_buff[1] = + Service::CFG::GetConfigInfoBlock(0x000F0004, 4, 0x8, reinterpret_cast<u8*>(&data)).raw; u8 model = data & 0xFF; if (model == Service::CFG::NINTENDO_2DS) @@ -267,24 +276,29 @@ static ResultVal<void*> GetConfigInfoBlockPointer(u32 block_id, u32 size, u32 fl // Read the header SaveFileConfig* config = reinterpret_cast<SaveFileConfig*>(cfg_config_file_buffer.data()); - auto itr = std::find_if(std::begin(config->block_entries), std::end(config->block_entries), - [&](const SaveConfigBlockEntry& entry) { - return entry.block_id == block_id; - }); + auto itr = + std::find_if(std::begin(config->block_entries), std::end(config->block_entries), + [&](const SaveConfigBlockEntry& entry) { return entry.block_id == block_id; }); if (itr == std::end(config->block_entries)) { - LOG_ERROR(Service_CFG, "Config block 0x%X with flags %u and size %u was not found", block_id, flag, size); - return ResultCode(ErrorDescription::NotFound, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent); + LOG_ERROR(Service_CFG, "Config block 0x%X with flags %u and size %u was not found", + block_id, flag, size); + return ResultCode(ErrorDescription::NotFound, ErrorModule::Config, + ErrorSummary::WrongArgument, ErrorLevel::Permanent); } if ((itr->flags & flag) == 0) { - LOG_ERROR(Service_CFG, "Invalid flag %u for config block 0x%X with size %u", flag, block_id, size); - return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent); + LOG_ERROR(Service_CFG, "Invalid flag %u for config block 0x%X with size %u", flag, block_id, + size); + return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::Config, + ErrorSummary::WrongArgument, ErrorLevel::Permanent); } if (itr->size != size) { - LOG_ERROR(Service_CFG, "Invalid size %u for config block 0x%X with flags %u", size, block_id, flag); - return ResultCode(ErrorDescription::InvalidSize, ErrorModule::Config, ErrorSummary::WrongArgument, ErrorLevel::Permanent); + LOG_ERROR(Service_CFG, "Invalid size %u for config block 0x%X with flags %u", size, + block_id, flag); + return ResultCode(ErrorDescription::InvalidSize, ErrorModule::Config, + ErrorSummary::WrongArgument, ErrorLevel::Permanent); } void* pointer; @@ -318,7 +332,7 @@ ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const void* da return ResultCode(-1); // TODO(Subv): Find the right error code // Insert the block header with offset 0 for now - config->block_entries[config->total_entries] = { block_id, 0, size, flags }; + config->block_entries[config->total_entries] = {block_id, 0, size, flags}; if (size > 4) { u32 offset = config->data_entries_offset; // Perform a search to locate the next offset for the new data @@ -326,8 +340,7 @@ ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const void* da for (int i = config->total_entries - 1; i >= 0; --i) { // Ignore the blocks that don't have a separate data offset if (config->block_entries[i].size > 4) { - offset = config->block_entries[i].offset_or_data + - config->block_entries[i].size; + offset = config->block_entries[i].offset_or_data + config->block_entries[i].size; break; } } @@ -336,8 +349,7 @@ ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const void* da // Write the data at the new offset memcpy(&cfg_config_file_buffer[offset], data, size); - } - else { + } else { // The offset_or_data field in the header contains the data itself if it's 4 bytes or less memcpy(&config->block_entries[config->total_entries].offset_or_data, data, size); } @@ -384,28 +396,40 @@ ResultCode FormatConfig() { // 0x00030001 - Unknown res = CreateConfigInfoBlk(0x00030001, 0x8, 0xE, zero_buffer); - if (!res.IsSuccess()) return res; + if (!res.IsSuccess()) + return res; - res = CreateConfigInfoBlk(StereoCameraSettingsBlockID, sizeof(STEREO_CAMERA_SETTINGS), 0xE, STEREO_CAMERA_SETTINGS.data()); - if (!res.IsSuccess()) return res; + res = CreateConfigInfoBlk(StereoCameraSettingsBlockID, sizeof(STEREO_CAMERA_SETTINGS), 0xE, + STEREO_CAMERA_SETTINGS.data()); + if (!res.IsSuccess()) + return res; - res = CreateConfigInfoBlk(SoundOutputModeBlockID, sizeof(SOUND_OUTPUT_MODE), 0xE, &SOUND_OUTPUT_MODE); - if (!res.IsSuccess()) return res; + res = CreateConfigInfoBlk(SoundOutputModeBlockID, sizeof(SOUND_OUTPUT_MODE), 0xE, + &SOUND_OUTPUT_MODE); + if (!res.IsSuccess()) + return res; - res = CreateConfigInfoBlk(ConsoleUniqueIDBlockID, sizeof(CONSOLE_UNIQUE_ID), 0xE, &CONSOLE_UNIQUE_ID); - if (!res.IsSuccess()) return res; + res = CreateConfigInfoBlk(ConsoleUniqueIDBlockID, sizeof(CONSOLE_UNIQUE_ID), 0xE, + &CONSOLE_UNIQUE_ID); + if (!res.IsSuccess()) + return res; - res = CreateConfigInfoBlk(UsernameBlockID, sizeof(CONSOLE_USERNAME_BLOCK), 0xE, &CONSOLE_USERNAME_BLOCK); - if (!res.IsSuccess()) return res; + res = CreateConfigInfoBlk(UsernameBlockID, sizeof(CONSOLE_USERNAME_BLOCK), 0xE, + &CONSOLE_USERNAME_BLOCK); + if (!res.IsSuccess()) + return res; res = CreateConfigInfoBlk(BirthdayBlockID, sizeof(PROFILE_BIRTHDAY), 0xE, &PROFILE_BIRTHDAY); - if (!res.IsSuccess()) return res; + if (!res.IsSuccess()) + return res; res = CreateConfigInfoBlk(LanguageBlockID, sizeof(CONSOLE_LANGUAGE), 0xE, &CONSOLE_LANGUAGE); - if (!res.IsSuccess()) return res; + if (!res.IsSuccess()) + return res; res = CreateConfigInfoBlk(CountryInfoBlockID, sizeof(COUNTRY_INFO), 0xE, &COUNTRY_INFO); - if (!res.IsSuccess()) return res; + if (!res.IsSuccess()) + return res; u16_le country_name_buffer[16][0x40] = {}; std::u16string region_name = Common::UTF8ToUTF16("Gensokyo"); @@ -413,34 +437,44 @@ ResultCode FormatConfig() { std::copy(region_name.cbegin(), region_name.cend(), country_name_buffer[i]); } // 0x000B0001 - Localized names for the profile Country - res = CreateConfigInfoBlk(CountryNameBlockID, sizeof(country_name_buffer), 0xE, country_name_buffer); - if (!res.IsSuccess()) return res; + res = CreateConfigInfoBlk(CountryNameBlockID, sizeof(country_name_buffer), 0xE, + country_name_buffer); + if (!res.IsSuccess()) + return res; // 0x000B0002 - Localized names for the profile State/Province - res = CreateConfigInfoBlk(StateNameBlockID, sizeof(country_name_buffer), 0xE, country_name_buffer); - if (!res.IsSuccess()) return res; + res = CreateConfigInfoBlk(StateNameBlockID, sizeof(country_name_buffer), 0xE, + country_name_buffer); + if (!res.IsSuccess()) + return res; // 0x000B0003 - Unknown, related to country/address (zip code?) res = CreateConfigInfoBlk(0x000B0003, 0x4, 0xE, zero_buffer); - if (!res.IsSuccess()) return res; + if (!res.IsSuccess()) + return res; // 0x000C0000 - Unknown res = CreateConfigInfoBlk(0x000C0000, 0xC0, 0xE, zero_buffer); - if (!res.IsSuccess()) return res; + if (!res.IsSuccess()) + return res; // 0x000C0001 - Unknown res = CreateConfigInfoBlk(0x000C0001, 0x14, 0xE, zero_buffer); - if (!res.IsSuccess()) return res; + if (!res.IsSuccess()) + return res; // 0x000D0000 - Accepted EULA version res = CreateConfigInfoBlk(EULAVersionBlockID, 0x4, 0xE, zero_buffer); - if (!res.IsSuccess()) return res; + if (!res.IsSuccess()) + return res; res = CreateConfigInfoBlk(ConsoleModelBlockID, sizeof(CONSOLE_MODEL), 0xC, &CONSOLE_MODEL); - if (!res.IsSuccess()) return res; + if (!res.IsSuccess()) + return res; // 0x00170000 - Unknown res = CreateConfigInfoBlk(0x00170000, 0x4, 0xE, zero_buffer); - if (!res.IsSuccess()) return res; + if (!res.IsSuccess()) + return res; // Save the buffer to the file res = UpdateConfigNANDSavegame(); @@ -452,15 +486,18 @@ ResultCode FormatConfig() { ResultCode LoadConfigNANDSaveFile() { // Open the SystemSaveData archive 0x00010017 FileSys::Path archive_path(cfg_system_savedata_id); - auto archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path); + auto archive_result = + Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path); // If the archive didn't exist, create the files inside if (archive_result.Code().description == ErrorDescription::FS_NotFormatted) { // Format the archive to create the directories - Service::FS::FormatArchive(Service::FS::ArchiveIdCode::SystemSaveData, FileSys::ArchiveFormatInfo(), archive_path); + Service::FS::FormatArchive(Service::FS::ArchiveIdCode::SystemSaveData, + FileSys::ArchiveFormatInfo(), archive_path); // Open it again to get a valid archive now that the folder exists - archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path); + archive_result = + Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path); } ASSERT_MSG(archive_result.Succeeded(), "Could not open the CFG SystemSaveData archive!"); @@ -491,8 +528,7 @@ void Init() { LoadConfigNANDSaveFile(); } -void Shutdown() { -} +void Shutdown() {} void SetUsername(const std::u16string& name) { ASSERT(name.size() <= 10); @@ -515,7 +551,7 @@ std::u16string GetUsername() { } void SetBirthday(u8 month, u8 day) { - BirthdayBlock block = { month, day }; + BirthdayBlock block = {month, day}; SetConfigInfoBlock(BirthdayBlockID, sizeof(block), 4, &block); } diff --git a/src/core/hle/service/cfg/cfg.h b/src/core/hle/service/cfg/cfg.h index 18f60f4ca..fb47c2aa5 100644 --- a/src/core/hle/service/cfg/cfg.h +++ b/src/core/hle/service/cfg/cfg.h @@ -6,7 +6,6 @@ #include <array> #include <string> - #include "common/common_types.h" union ResultCode; @@ -40,16 +39,13 @@ enum SystemLanguage { LANGUAGE_TW = 11 }; -enum SoundOutputMode { - SOUND_MONO = 0, - SOUND_STEREO = 1, - SOUND_SURROUND = 2 -}; +enum SoundOutputMode { SOUND_MONO = 0, SOUND_STEREO = 1, SOUND_SURROUND = 2 }; /// Block header in the config savedata file struct SaveConfigBlockEntry { u32 block_id; ///< The id of the current block - u32 offset_or_data; ///< This is the absolute offset to the block data if the size is greater than 4 bytes, otherwise it contains the data itself + u32 offset_or_data; ///< This is the absolute offset to the block data if the size is greater + /// than 4 bytes, otherwise it contains the data itself u16 size; ///< The size of the block u16 flags; ///< The flags of the block, possibly used for access control }; @@ -82,7 +78,7 @@ static const std::array<u16, 187> country_codes = {{ C("CN"), 0, 0, 0, 0, 0, 0, 0, // 160-167 C("AE"), C("IN"), C("EG"), C("OM"), C("QA"), C("KW"), C("SA"), C("SY"), // 168-175 C("BH"), C("JO"), 0, 0, 0, 0, 0, 0, // 176-183 - C("SM"), C("VA"), C("BM") // 184-186 + C("SM"), C("VA"), C("BM"), // 184-186 }}; /** @@ -221,8 +217,9 @@ void FormatConfig(Service::Interface* self); /** * Reads a block with the specified id and flag from the Config savegame buffer - * and writes the output to output. - * The input size must match exactly the size of the requested block + * and writes the output to output. The input size must match exactly the size of the requested + * block. + * * @param block_id The id of the block we want to read * @param size The size of the block we want to read * @param flag The requested block must have this flag set @@ -233,8 +230,8 @@ ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, void* output); /** * Reads data from input and writes to a block with the specified id and flag - * in the Config savegame buffer. - * The input size must match exactly the size of the target block + * in the Config savegame buffer. The input size must match exactly the size of the target block. + * * @param block_id The id of the block we want to write * @param size The size of the block we want to write * @param flag The target block must have this flag set @@ -244,8 +241,9 @@ ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, void* output); ResultCode SetConfigInfoBlock(u32 block_id, u32 size, u32 flag, const void* input); /** - * Creates a block with the specified id and writes the input data to the cfg savegame buffer in memory. - * The config savegame file in the filesystem is not updated. + * Creates a block with the specified id and writes the input data to the cfg savegame buffer in + * memory. The config savegame file in the filesystem is not updated. + * * @param block_id The id of the block we want to create * @param size The size of the block we want to create * @param flags The flags of the new block diff --git a/src/core/hle/service/cfg/cfg_i.cpp b/src/core/hle/service/cfg/cfg_i.cpp index 8b0db785f..2ff52c8b8 100644 --- a/src/core/hle/service/cfg/cfg_i.cpp +++ b/src/core/hle/service/cfg/cfg_i.cpp @@ -10,49 +10,49 @@ namespace CFG { const Interface::FunctionInfo FunctionTable[] = { // cfg common - {0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"}, - {0x00020000, SecureInfoGetRegion, "SecureInfoGetRegion"}, - {0x00030040, GenHashConsoleUnique, "GenHashConsoleUnique"}, - {0x00040000, GetRegionCanadaUSA, "GetRegionCanadaUSA"}, - {0x00050000, GetSystemModel, "GetSystemModel"}, - {0x00060000, GetModelNintendo2DS, "GetModelNintendo2DS"}, - {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"}, - {0x00080080, nullptr, "GoThroughTable"}, - {0x00090040, GetCountryCodeString, "GetCountryCodeString"}, - {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, + {0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"}, + {0x00020000, SecureInfoGetRegion, "SecureInfoGetRegion"}, + {0x00030040, GenHashConsoleUnique, "GenHashConsoleUnique"}, + {0x00040000, GetRegionCanadaUSA, "GetRegionCanadaUSA"}, + {0x00050000, GetSystemModel, "GetSystemModel"}, + {0x00060000, GetModelNintendo2DS, "GetModelNintendo2DS"}, + {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"}, + {0x00080080, nullptr, "GoThroughTable"}, + {0x00090040, GetCountryCodeString, "GetCountryCodeString"}, + {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, // cfg:i - {0x04010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, - {0x04020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"}, - {0x04030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, - {0x04040042, nullptr, "GetLocalFriendCodeSeedData"}, - {0x04050000, nullptr, "GetLocalFriendCodeSeed"}, - {0x04060000, SecureInfoGetRegion, "SecureInfoGetRegion"}, - {0x04070000, nullptr, "SecureInfoGetByte101"}, - {0x04080042, nullptr, "SecureInfoGetSerialNo"}, - {0x04090000, nullptr, "UpdateConfigBlk00040003"}, - {0x08010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, - {0x08020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"}, - {0x08030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, - {0x080400C2, nullptr, "CreateConfigInfoBlk"}, - {0x08050000, nullptr, "DeleteConfigNANDSavefile"}, - {0x08060000, FormatConfig, "FormatConfig"}, - {0x08080000, nullptr, "UpdateConfigBlk1"}, - {0x08090000, nullptr, "UpdateConfigBlk2"}, - {0x080A0000, nullptr, "UpdateConfigBlk3"}, - {0x080B0082, nullptr, "SetGetLocalFriendCodeSeedData"}, - {0x080C0042, nullptr, "SetLocalFriendCodeSeedSignature"}, - {0x080D0000, nullptr, "DeleteCreateNANDLocalFriendCodeSeed"}, - {0x080E0000, nullptr, "VerifySigLocalFriendCodeSeed"}, - {0x080F0042, nullptr, "GetLocalFriendCodeSeedData"}, - {0x08100000, nullptr, "GetLocalFriendCodeSeed"}, - {0x08110084, nullptr, "SetSecureInfo"}, - {0x08120000, nullptr, "DeleteCreateNANDSecureInfo"}, - {0x08130000, nullptr, "VerifySigSecureInfo"}, - {0x08140042, nullptr, "SecureInfoGetData"}, - {0x08150042, nullptr, "SecureInfoGetSignature"}, - {0x08160000, SecureInfoGetRegion, "SecureInfoGetRegion"}, - {0x08170000, nullptr, "SecureInfoGetByte101"}, - {0x08180042, nullptr, "SecureInfoGetSerialNo"}, + {0x04010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, + {0x04020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"}, + {0x04030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, + {0x04040042, nullptr, "GetLocalFriendCodeSeedData"}, + {0x04050000, nullptr, "GetLocalFriendCodeSeed"}, + {0x04060000, SecureInfoGetRegion, "SecureInfoGetRegion"}, + {0x04070000, nullptr, "SecureInfoGetByte101"}, + {0x04080042, nullptr, "SecureInfoGetSerialNo"}, + {0x04090000, nullptr, "UpdateConfigBlk00040003"}, + {0x08010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, + {0x08020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"}, + {0x08030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, + {0x080400C2, nullptr, "CreateConfigInfoBlk"}, + {0x08050000, nullptr, "DeleteConfigNANDSavefile"}, + {0x08060000, FormatConfig, "FormatConfig"}, + {0x08080000, nullptr, "UpdateConfigBlk1"}, + {0x08090000, nullptr, "UpdateConfigBlk2"}, + {0x080A0000, nullptr, "UpdateConfigBlk3"}, + {0x080B0082, nullptr, "SetGetLocalFriendCodeSeedData"}, + {0x080C0042, nullptr, "SetLocalFriendCodeSeedSignature"}, + {0x080D0000, nullptr, "DeleteCreateNANDLocalFriendCodeSeed"}, + {0x080E0000, nullptr, "VerifySigLocalFriendCodeSeed"}, + {0x080F0042, nullptr, "GetLocalFriendCodeSeedData"}, + {0x08100000, nullptr, "GetLocalFriendCodeSeed"}, + {0x08110084, nullptr, "SetSecureInfo"}, + {0x08120000, nullptr, "DeleteCreateNANDSecureInfo"}, + {0x08130000, nullptr, "VerifySigSecureInfo"}, + {0x08140042, nullptr, "SecureInfoGetData"}, + {0x08150042, nullptr, "SecureInfoGetSignature"}, + {0x08160000, SecureInfoGetRegion, "SecureInfoGetRegion"}, + {0x08170000, nullptr, "SecureInfoGetByte101"}, + {0x08180042, nullptr, "SecureInfoGetSerialNo"}, }; CFG_I_Interface::CFG_I_Interface() { diff --git a/src/core/hle/service/cfg/cfg_s.cpp b/src/core/hle/service/cfg/cfg_s.cpp index 12b458783..eed26dec7 100644 --- a/src/core/hle/service/cfg/cfg_s.cpp +++ b/src/core/hle/service/cfg/cfg_s.cpp @@ -10,26 +10,26 @@ namespace CFG { const Interface::FunctionInfo FunctionTable[] = { // cfg common - {0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"}, - {0x00020000, SecureInfoGetRegion, "SecureInfoGetRegion"}, - {0x00030040, GenHashConsoleUnique, "GenHashConsoleUnique"}, - {0x00040000, GetRegionCanadaUSA, "GetRegionCanadaUSA"}, - {0x00050000, GetSystemModel, "GetSystemModel"}, - {0x00060000, GetModelNintendo2DS, "GetModelNintendo2DS"}, - {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"}, - {0x00080080, nullptr, "GoThroughTable"}, - {0x00090040, GetCountryCodeString, "GetCountryCodeString"}, - {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, + {0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"}, + {0x00020000, SecureInfoGetRegion, "SecureInfoGetRegion"}, + {0x00030040, GenHashConsoleUnique, "GenHashConsoleUnique"}, + {0x00040000, GetRegionCanadaUSA, "GetRegionCanadaUSA"}, + {0x00050000, GetSystemModel, "GetSystemModel"}, + {0x00060000, GetModelNintendo2DS, "GetModelNintendo2DS"}, + {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"}, + {0x00080080, nullptr, "GoThroughTable"}, + {0x00090040, GetCountryCodeString, "GetCountryCodeString"}, + {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, // cfg:s - {0x04010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, - {0x04020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"}, - {0x04030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, - {0x04040042, nullptr, "GetLocalFriendCodeSeedData"}, - {0x04050000, nullptr, "GetLocalFriendCodeSeed"}, - {0x04060000, nullptr, "SecureInfoGetRegion"}, - {0x04070000, nullptr, "SecureInfoGetByte101"}, - {0x04080042, nullptr, "SecureInfoGetSerialNo"}, - {0x04090000, nullptr, "UpdateConfigBlk00040003"}, + {0x04010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"}, + {0x04020082, SetConfigInfoBlk4, "SetConfigInfoBlk4"}, + {0x04030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"}, + {0x04040042, nullptr, "GetLocalFriendCodeSeedData"}, + {0x04050000, nullptr, "GetLocalFriendCodeSeed"}, + {0x04060000, nullptr, "SecureInfoGetRegion"}, + {0x04070000, nullptr, "SecureInfoGetByte101"}, + {0x04080042, nullptr, "SecureInfoGetSerialNo"}, + {0x04090000, nullptr, "UpdateConfigBlk00040003"}, }; CFG_S_Interface::CFG_S_Interface() { diff --git a/src/core/hle/service/cfg/cfg_u.cpp b/src/core/hle/service/cfg/cfg_u.cpp index 606f7b2eb..f28217134 100644 --- a/src/core/hle/service/cfg/cfg_u.cpp +++ b/src/core/hle/service/cfg/cfg_u.cpp @@ -10,16 +10,16 @@ namespace CFG { const Interface::FunctionInfo FunctionTable[] = { // cfg common - {0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"}, - {0x00020000, SecureInfoGetRegion, "SecureInfoGetRegion"}, - {0x00030040, GenHashConsoleUnique, "GenHashConsoleUnique"}, - {0x00040000, GetRegionCanadaUSA, "GetRegionCanadaUSA"}, - {0x00050000, GetSystemModel, "GetSystemModel"}, - {0x00060000, GetModelNintendo2DS, "GetModelNintendo2DS"}, - {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"}, - {0x00080080, nullptr, "GoThroughTable"}, - {0x00090040, GetCountryCodeString, "GetCountryCodeString"}, - {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, + {0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"}, + {0x00020000, SecureInfoGetRegion, "SecureInfoGetRegion"}, + {0x00030040, GenHashConsoleUnique, "GenHashConsoleUnique"}, + {0x00040000, GetRegionCanadaUSA, "GetRegionCanadaUSA"}, + {0x00050000, GetSystemModel, "GetSystemModel"}, + {0x00060000, GetModelNintendo2DS, "GetModelNintendo2DS"}, + {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"}, + {0x00080080, nullptr, "GoThroughTable"}, + {0x00090040, GetCountryCodeString, "GetCountryCodeString"}, + {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, }; CFG_U_Interface::CFG_U_Interface() { diff --git a/src/core/hle/service/csnd_snd.cpp b/src/core/hle/service/csnd_snd.cpp index 913c8dc09..20c759ad7 100644 --- a/src/core/hle/service/csnd_snd.cpp +++ b/src/core/hle/service/csnd_snd.cpp @@ -15,18 +15,18 @@ namespace CSND_SND { const Interface::FunctionInfo FunctionTable[] = { - {0x00010140, Initialize, "Initialize"}, - {0x00020000, Shutdown, "Shutdown"}, - {0x00030040, ExecuteType0Commands, "ExecuteType0Commands"}, - {0x00040080, nullptr, "ExecuteType1Commands"}, - {0x00050000, AcquireSoundChannels, "AcquireSoundChannels"}, - {0x00060000, nullptr, "ReleaseSoundChannels"}, - {0x00070000, nullptr, "AcquireCaptureDevice"}, - {0x00080040, nullptr, "ReleaseCaptureDevice"}, - {0x00090082, nullptr, "FlushDataCache"}, - {0x000A0082, nullptr, "StoreDataCache"}, - {0x000B0082, nullptr, "InvalidateDataCache"}, - {0x000C0000, nullptr, "Reset"}, + {0x00010140, Initialize, "Initialize"}, + {0x00020000, Shutdown, "Shutdown"}, + {0x00030040, ExecuteType0Commands, "ExecuteType0Commands"}, + {0x00040080, nullptr, "ExecuteType1Commands"}, + {0x00050000, AcquireSoundChannels, "AcquireSoundChannels"}, + {0x00060000, nullptr, "ReleaseSoundChannels"}, + {0x00070000, nullptr, "AcquireCaptureDevice"}, + {0x00080040, nullptr, "ReleaseCaptureDevice"}, + {0x00090082, nullptr, "FlushDataCache"}, + {0x000A0082, nullptr, "StoreDataCache"}, + {0x000B0082, nullptr, "InvalidateDataCache"}, + {0x000C0000, nullptr, "Reset"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -44,9 +44,9 @@ void Initialize(Service::Interface* self) { u32 size = Common::AlignUp(cmd_buff[1], Memory::PAGE_SIZE); using Kernel::MemoryPermission; - shared_memory = Kernel::SharedMemory::Create(nullptr, size, - MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, - 0, Kernel::MemoryRegion::BASE, "CSND:SharedMemory"); + shared_memory = Kernel::SharedMemory::Create(nullptr, size, MemoryPermission::ReadWrite, + MemoryPermission::ReadWrite, 0, + Kernel::MemoryRegion::BASE, "CSND:SharedMemory"); mutex = Kernel::Mutex::Create(false); @@ -58,7 +58,7 @@ void Initialize(Service::Interface* self) { void ExecuteType0Commands(Service::Interface* self) { u32* const cmd_buff = Kernel::GetCommandBuffer(); - u8* const ptr = shared_memory->GetPointer(cmd_buff[1]); + u8* const ptr = shared_memory->GetPointer(cmd_buff[1]); if (shared_memory != nullptr && ptr != nullptr) { Type0Command command; diff --git a/src/core/hle/service/csnd_snd.h b/src/core/hle/service/csnd_snd.h index e861f3327..a146d116b 100644 --- a/src/core/hle/service/csnd_snd.h +++ b/src/core/hle/service/csnd_snd.h @@ -25,7 +25,7 @@ struct Type0Command { u32 command_id; u32 finished; u32 flags; - u8 parameters[20]; + u8 parameters[20]; }; void Initialize(Service::Interface* self); diff --git a/src/core/hle/service/dlp/dlp.cpp b/src/core/hle/service/dlp/dlp.cpp index 7c8db794b..8f4b67a5d 100644 --- a/src/core/hle/service/dlp/dlp.cpp +++ b/src/core/hle/service/dlp/dlp.cpp @@ -2,11 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "core/hle/service/service.h" #include "core/hle/service/dlp/dlp.h" #include "core/hle/service/dlp/dlp_clnt.h" #include "core/hle/service/dlp/dlp_fkcl.h" #include "core/hle/service/dlp/dlp_srvr.h" +#include "core/hle/service/service.h" namespace Service { namespace DLP { @@ -17,8 +17,7 @@ void Init() { AddService(new DLP_SRVR_Interface); } -void Shutdown() { -} +void Shutdown() {} } // namespace DLP } // namespace Service diff --git a/src/core/hle/service/dlp/dlp_clnt.cpp b/src/core/hle/service/dlp/dlp_clnt.cpp index 0b31d47df..56f934b3f 100644 --- a/src/core/hle/service/dlp/dlp_clnt.cpp +++ b/src/core/hle/service/dlp/dlp_clnt.cpp @@ -8,8 +8,7 @@ namespace Service { namespace DLP { const Interface::FunctionInfo FunctionTable[] = { - {0x000100C3, nullptr, "Initialize"}, - {0x00110000, nullptr, "GetWirelessRebootPassphrase"}, + {0x000100C3, nullptr, "Initialize"}, {0x00110000, nullptr, "GetWirelessRebootPassphrase"}, }; DLP_CLNT_Interface::DLP_CLNT_Interface() { diff --git a/src/core/hle/service/dlp/dlp_fkcl.cpp b/src/core/hle/service/dlp/dlp_fkcl.cpp index a845260e5..29b9d52e0 100644 --- a/src/core/hle/service/dlp/dlp_fkcl.cpp +++ b/src/core/hle/service/dlp/dlp_fkcl.cpp @@ -8,8 +8,7 @@ namespace Service { namespace DLP { const Interface::FunctionInfo FunctionTable[] = { - {0x00010083, nullptr, "Initialize"}, - {0x000F0000, nullptr, "GetWirelessRebootPassphrase"}, + {0x00010083, nullptr, "Initialize"}, {0x000F0000, nullptr, "GetWirelessRebootPassphrase"}, }; DLP_FKCL_Interface::DLP_FKCL_Interface() { diff --git a/src/core/hle/service/dlp/dlp_srvr.cpp b/src/core/hle/service/dlp/dlp_srvr.cpp index da9b30f56..49d5b8d1c 100644 --- a/src/core/hle/service/dlp/dlp_srvr.cpp +++ b/src/core/hle/service/dlp/dlp_srvr.cpp @@ -20,10 +20,10 @@ static void unk_0x000E0040(Interface* self) { } const Interface::FunctionInfo FunctionTable[] = { - {0x00010183, nullptr, "Initialize"}, - {0x00020000, nullptr, "Finalize"}, - {0x000800C0, nullptr, "SendWirelessRebootPassphrase"}, - {0x000E0040, unk_0x000E0040, "unk_0x000E0040"}, + {0x00010183, nullptr, "Initialize"}, + {0x00020000, nullptr, "Finalize"}, + {0x000800C0, nullptr, "SendWirelessRebootPassphrase"}, + {0x000E0040, unk_0x000E0040, "unk_0x000E0040"}, }; DLP_SRVR_Interface::DLP_SRVR_Interface() { diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp index c8aadd9db..a15aa3696 100644 --- a/src/core/hle/service/dsp_dsp.cpp +++ b/src/core/hle/service/dsp_dsp.cpp @@ -4,12 +4,9 @@ #include <algorithm> #include <cinttypes> - #include "audio_core/hle/pipe.h" - #include "common/hash.h" #include "common/logging/log.h" - #include "core/hle/kernel/event.h" #include "core/hle/service/dsp_dsp.h" @@ -23,9 +20,7 @@ namespace DSP_DSP { static Kernel::SharedPtr<Kernel::Event> semaphore_event; /// There are three types of interrupts -enum class InterruptType { - Zero, One, Pipe -}; +enum class InterruptType { Zero, One, Pipe }; constexpr size_t NUM_INTERRUPT_TYPE = 3; class InterruptEvents final { @@ -57,9 +52,8 @@ public: // Actual service implementation only has 6 'slots' for interrupts. constexpr size_t max_number_of_interrupt_events = 6; - size_t number = std::count_if(pipe.begin(), pipe.end(), [](const auto& evt) { - return evt != nullptr; - }); + size_t number = + std::count_if(pipe.begin(), pipe.end(), [](const auto& evt) { return evt != nullptr; }); if (zero != nullptr) number++; @@ -105,7 +99,8 @@ static void ConvertProcessAddressFromDspDram(Service::Interface* self) { cmd_buff[0] = IPC::MakeHeader(0xC, 2, 0); cmd_buff[1] = RESULT_SUCCESS.raw; // No error - // TODO(merry): There is a per-region offset missing in this calculation (that seems to be always zero). + // TODO(merry): There is a per-region offset missing in this calculation (that seems to be + // always zero). cmd_buff[2] = (addr << 1) + (Memory::DSP_RAM_VADDR + 0x40000); LOG_DEBUG(Service_DSP, "addr=0x%08X", addr); @@ -126,15 +121,15 @@ static void ConvertProcessAddressFromDspDram(Service::Interface* self) { static void LoadComponent(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - u32 size = cmd_buff[1]; - u32 prog_mask = cmd_buff[2]; - u32 data_mask = cmd_buff[3]; - u32 desc = cmd_buff[4]; - u32 buffer = cmd_buff[5]; + u32 size = cmd_buff[1]; + u32 prog_mask = cmd_buff[2]; + u32 data_mask = cmd_buff[3]; + u32 desc = cmd_buff[4]; + u32 buffer = cmd_buff[5]; cmd_buff[0] = IPC::MakeHeader(0x11, 2, 2); cmd_buff[1] = RESULT_SUCCESS.raw; // No error - cmd_buff[2] = 1; // Pretend that we actually loaded the DSP firmware + cmd_buff[2] = 1; // Pretend that we actually loaded the DSP firmware cmd_buff[3] = desc; cmd_buff[4] = buffer; @@ -145,12 +140,15 @@ static void LoadComponent(Service::Interface* self) { std::vector<u8> component_data(size); Memory::ReadBlock(buffer, component_data.data(), component_data.size()); - LOG_INFO(Service_DSP, "Firmware hash: %#" PRIx64, Common::ComputeHash64(component_data.data(), component_data.size())); + LOG_INFO(Service_DSP, "Firmware hash: %#" PRIx64, + Common::ComputeHash64(component_data.data(), component_data.size())); // Some versions of the firmware have the location of DSP structures listed here. ASSERT(size > 0x37C); - LOG_INFO(Service_DSP, "Structures hash: %#" PRIx64, Common::ComputeHash64(component_data.data() + 0x340, 60)); + LOG_INFO(Service_DSP, "Structures hash: %#" PRIx64, + Common::ComputeHash64(component_data.data() + 0x340, 60)); - LOG_WARNING(Service_DSP, "(STUBBED) called size=0x%X, prog_mask=0x%08X, data_mask=0x%08X, buffer=0x%08X", + LOG_WARNING(Service_DSP, + "(STUBBED) called size=0x%X, prog_mask=0x%08X, data_mask=0x%08X, buffer=0x%08X", size, prog_mask, data_mask, buffer); } @@ -187,13 +185,14 @@ static void GetSemaphoreEventHandle(Service::Interface* self) { static void FlushDataCache(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 address = cmd_buff[1]; - u32 size = cmd_buff[2]; + u32 size = cmd_buff[2]; u32 process = cmd_buff[4]; cmd_buff[0] = IPC::MakeHeader(0x13, 1, 0); cmd_buff[1] = RESULT_SUCCESS.raw; // No error - LOG_TRACE(Service_DSP, "called address=0x%08X, size=0x%X, process=0x%08X", address, size, process); + LOG_TRACE(Service_DSP, "called address=0x%08X, size=0x%X, process=0x%08X", address, size, + process); } /** @@ -224,23 +223,29 @@ static void RegisterInterruptEvents(Service::Interface* self) { auto evt = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[4]); if (!evt) { - LOG_INFO(Service_DSP, "Invalid event handle! type=%u, pipe=%u, event_handle=0x%08X", type_index, pipe_index, event_handle); + LOG_INFO(Service_DSP, "Invalid event handle! type=%u, pipe=%u, event_handle=0x%08X", + type_index, pipe_index, event_handle); ASSERT(false); // TODO: This should really be handled at an IPC translation layer. } if (interrupt_events.HasTooManyEventsRegistered()) { - LOG_INFO(Service_DSP, "Ran out of space to register interrupts (Attempted to register type=%u, pipe=%u, event_handle=0x%08X)", + LOG_INFO(Service_DSP, "Ran out of space to register interrupts (Attempted to register " + "type=%u, pipe=%u, event_handle=0x%08X)", type_index, pipe_index, event_handle); - cmd_buff[1] = ResultCode(ErrorDescription::InvalidResultValue, ErrorModule::DSP, ErrorSummary::OutOfResource, ErrorLevel::Status).raw; + cmd_buff[1] = ResultCode(ErrorDescription::InvalidResultValue, ErrorModule::DSP, + ErrorSummary::OutOfResource, ErrorLevel::Status) + .raw; return; } interrupt_events.Get(type, pipe) = evt; - LOG_INFO(Service_DSP, "Registered type=%u, pipe=%u, event_handle=0x%08X", type_index, pipe_index, event_handle); + LOG_INFO(Service_DSP, "Registered type=%u, pipe=%u, event_handle=0x%08X", type_index, + pipe_index, event_handle); cmd_buff[1] = RESULT_SUCCESS.raw; } else { interrupt_events.Get(type, pipe) = nullptr; - LOG_INFO(Service_DSP, "Unregistered interrupt=%u, channel=%u, event_handle=0x%08X", type_index, pipe_index, event_handle); + LOG_INFO(Service_DSP, "Unregistered interrupt=%u, channel=%u, event_handle=0x%08X", + type_index, pipe_index, event_handle); cmd_buff[1] = RESULT_SUCCESS.raw; } } @@ -282,13 +287,18 @@ static void WriteProcessPipe(Service::Interface* self) { DSP::HLE::DspPipe pipe = static_cast<DSP::HLE::DspPipe>(pipe_index); if (IPC::StaticBufferDesc(size, 1) != cmd_buff[3]) { - LOG_ERROR(Service_DSP, "IPC static buffer descriptor failed validation (0x%X). pipe=%u, size=0x%X, buffer=0x%08X", cmd_buff[3], pipe_index, size, buffer); + LOG_ERROR(Service_DSP, "IPC static buffer descriptor failed validation (0x%X). pipe=%u, " + "size=0x%X, buffer=0x%08X", + cmd_buff[3], pipe_index, size, buffer); cmd_buff[0] = IPC::MakeHeader(0, 1, 0); - cmd_buff[1] = ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS, ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw; + cmd_buff[1] = ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS, + ErrorSummary::WrongArgument, ErrorLevel::Permanent) + .raw; return; } - ASSERT_MSG(Memory::IsValidVirtualAddress(buffer), "Invalid Buffer: pipe=%u, size=0x%X, buffer=0x%08X", pipe, size, buffer); + ASSERT_MSG(Memory::IsValidVirtualAddress(buffer), + "Invalid Buffer: pipe=%u, size=0x%X, buffer=0x%08X", pipe, size, buffer); std::vector<u8> message(size); for (u32 i = 0; i < size; i++) { @@ -327,7 +337,9 @@ static void ReadPipeIfPossible(Service::Interface* self) { DSP::HLE::DspPipe pipe = static_cast<DSP::HLE::DspPipe>(pipe_index); - ASSERT_MSG(Memory::IsValidVirtualAddress(addr), "Invalid addr: pipe=0x%08X, unknown=0x%08X, size=0x%X, buffer=0x%08X", pipe, unknown, size, addr); + ASSERT_MSG(Memory::IsValidVirtualAddress(addr), + "Invalid addr: pipe=0x%08X, unknown=0x%08X, size=0x%X, buffer=0x%08X", pipe, unknown, + size, addr); cmd_buff[0] = IPC::MakeHeader(0x10, 1, 2); cmd_buff[1] = RESULT_SUCCESS.raw; // No error @@ -343,7 +355,9 @@ static void ReadPipeIfPossible(Service::Interface* self) { cmd_buff[3] = IPC::StaticBufferDesc(size, 0); cmd_buff[4] = addr; - LOG_DEBUG(Service_DSP, "pipe=%u, unknown=0x%08X, size=0x%X, buffer=0x%08X, return cmd_buff[2]=0x%08X", pipe_index, unknown, size, addr, cmd_buff[2]); + LOG_DEBUG(Service_DSP, + "pipe=%u, unknown=0x%08X, size=0x%X, buffer=0x%08X, return cmd_buff[2]=0x%08X", + pipe_index, unknown, size, addr, cmd_buff[2]); } /** @@ -367,7 +381,9 @@ static void ReadPipe(Service::Interface* self) { DSP::HLE::DspPipe pipe = static_cast<DSP::HLE::DspPipe>(pipe_index); - ASSERT_MSG(Memory::IsValidVirtualAddress(addr), "Invalid addr: pipe=0x%08X, unknown=0x%08X, size=0x%X, buffer=0x%08X", pipe, unknown, size, addr); + ASSERT_MSG(Memory::IsValidVirtualAddress(addr), + "Invalid addr: pipe=0x%08X, unknown=0x%08X, size=0x%X, buffer=0x%08X", pipe, unknown, + size, addr); if (DSP::HLE::GetPipeReadableSize(pipe) >= size) { std::vector<u8> response = DSP::HLE::PipeRead(pipe, size); @@ -384,7 +400,9 @@ static void ReadPipe(Service::Interface* self) { UNREACHABLE(); } - LOG_DEBUG(Service_DSP, "pipe=%u, unknown=0x%08X, size=0x%X, buffer=0x%08X, return cmd_buff[2]=0x%08X", pipe_index, unknown, size, addr, cmd_buff[2]); + LOG_DEBUG(Service_DSP, + "pipe=%u, unknown=0x%08X, size=0x%X, buffer=0x%08X, return cmd_buff[2]=0x%08X", + pipe_index, unknown, size, addr, cmd_buff[2]); } /** @@ -408,7 +426,8 @@ static void GetPipeReadableSize(Service::Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; // No error cmd_buff[2] = static_cast<u32>(DSP::HLE::GetPipeReadableSize(pipe)); - LOG_DEBUG(Service_DSP, "pipe=%u, unknown=0x%08X, return cmd_buff[2]=0x%08X", pipe_index, unknown, cmd_buff[2]); + LOG_DEBUG(Service_DSP, "pipe=%u, unknown=0x%08X, return cmd_buff[2]=0x%08X", pipe_index, + unknown, cmd_buff[2]); } /** @@ -443,7 +462,7 @@ static void GetHeadphoneStatus(Service::Interface* self) { cmd_buff[0] = IPC::MakeHeader(0x1F, 2, 0); cmd_buff[1] = RESULT_SUCCESS.raw; // No error - cmd_buff[2] = 0; // Not using headphones + cmd_buff[2] = 0; // Not using headphones LOG_DEBUG(Service_DSP, "called"); } @@ -466,7 +485,8 @@ static void RecvData(Service::Interface* self) { ASSERT_MSG(register_number == 0, "Unknown register_number %u", register_number); - // Application reads this after requesting DSP shutdown, to verify the DSP has indeed shutdown or slept. + // Application reads this after requesting DSP shutdown, to verify the DSP has indeed shutdown + // or slept. cmd_buff[0] = IPC::MakeHeader(0x1, 2, 0); cmd_buff[1] = RESULT_SUCCESS.raw; @@ -512,39 +532,39 @@ static void RecvDataIsReady(Service::Interface* self) { } const Interface::FunctionInfo FunctionTable[] = { - {0x00010040, RecvData, "RecvData"}, - {0x00020040, RecvDataIsReady, "RecvDataIsReady"}, - {0x00030080, nullptr, "SendData"}, - {0x00040040, nullptr, "SendDataIsEmpty"}, - {0x000500C2, nullptr, "SendFifoEx"}, - {0x000600C0, nullptr, "RecvFifoEx"}, - {0x00070040, SetSemaphore, "SetSemaphore"}, - {0x00080000, nullptr, "GetSemaphore"}, - {0x00090040, nullptr, "ClearSemaphore"}, - {0x000A0040, nullptr, "MaskSemaphore"}, - {0x000B0000, nullptr, "CheckSemaphoreRequest"}, + {0x00010040, RecvData, "RecvData"}, + {0x00020040, RecvDataIsReady, "RecvDataIsReady"}, + {0x00030080, nullptr, "SendData"}, + {0x00040040, nullptr, "SendDataIsEmpty"}, + {0x000500C2, nullptr, "SendFifoEx"}, + {0x000600C0, nullptr, "RecvFifoEx"}, + {0x00070040, SetSemaphore, "SetSemaphore"}, + {0x00080000, nullptr, "GetSemaphore"}, + {0x00090040, nullptr, "ClearSemaphore"}, + {0x000A0040, nullptr, "MaskSemaphore"}, + {0x000B0000, nullptr, "CheckSemaphoreRequest"}, {0x000C0040, ConvertProcessAddressFromDspDram, "ConvertProcessAddressFromDspDram"}, - {0x000D0082, WriteProcessPipe, "WriteProcessPipe"}, - {0x000E00C0, ReadPipe, "ReadPipe"}, - {0x000F0080, GetPipeReadableSize, "GetPipeReadableSize"}, - {0x001000C0, ReadPipeIfPossible, "ReadPipeIfPossible"}, - {0x001100C2, LoadComponent, "LoadComponent"}, - {0x00120000, nullptr, "UnloadComponent"}, - {0x00130082, FlushDataCache, "FlushDataCache"}, - {0x00140082, nullptr, "InvalidateDCache"}, - {0x00150082, RegisterInterruptEvents, "RegisterInterruptEvents"}, - {0x00160000, GetSemaphoreEventHandle, "GetSemaphoreEventHandle"}, - {0x00170040, SetSemaphoreMask, "SetSemaphoreMask"}, - {0x00180040, nullptr, "GetPhysicalAddress"}, - {0x00190040, nullptr, "GetVirtualAddress"}, - {0x001A0042, nullptr, "SetIirFilterI2S1_cmd1"}, - {0x001B0042, nullptr, "SetIirFilterI2S1_cmd2"}, - {0x001C0082, nullptr, "SetIirFilterEQ"}, - {0x001D00C0, nullptr, "ReadMultiEx_SPI2"}, - {0x001E00C2, nullptr, "WriteMultiEx_SPI2"}, - {0x001F0000, GetHeadphoneStatus, "GetHeadphoneStatus"}, - {0x00200040, nullptr, "ForceHeadphoneOut"}, - {0x00210000, nullptr, "GetIsDspOccupied"}, + {0x000D0082, WriteProcessPipe, "WriteProcessPipe"}, + {0x000E00C0, ReadPipe, "ReadPipe"}, + {0x000F0080, GetPipeReadableSize, "GetPipeReadableSize"}, + {0x001000C0, ReadPipeIfPossible, "ReadPipeIfPossible"}, + {0x001100C2, LoadComponent, "LoadComponent"}, + {0x00120000, nullptr, "UnloadComponent"}, + {0x00130082, FlushDataCache, "FlushDataCache"}, + {0x00140082, nullptr, "InvalidateDCache"}, + {0x00150082, RegisterInterruptEvents, "RegisterInterruptEvents"}, + {0x00160000, GetSemaphoreEventHandle, "GetSemaphoreEventHandle"}, + {0x00170040, SetSemaphoreMask, "SetSemaphoreMask"}, + {0x00180040, nullptr, "GetPhysicalAddress"}, + {0x00190040, nullptr, "GetVirtualAddress"}, + {0x001A0042, nullptr, "SetIirFilterI2S1_cmd1"}, + {0x001B0042, nullptr, "SetIirFilterI2S1_cmd2"}, + {0x001C0082, nullptr, "SetIirFilterEQ"}, + {0x001D00C0, nullptr, "ReadMultiEx_SPI2"}, + {0x001E00C2, nullptr, "WriteMultiEx_SPI2"}, + {0x001F0000, GetHeadphoneStatus, "GetHeadphoneStatus"}, + {0x00200040, nullptr, "ForceHeadphoneOut"}, + {0x00210000, nullptr, "GetIsDspOccupied"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/dsp_dsp.h b/src/core/hle/service/dsp_dsp.h index 22f6687cc..3e97da6eb 100644 --- a/src/core/hle/service/dsp_dsp.h +++ b/src/core/hle/service/dsp_dsp.h @@ -5,7 +5,6 @@ #pragma once #include <string> - #include "core/hle/service/service.h" namespace DSP { diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp index 5f9cf6e94..3ca4f98de 100644 --- a/src/core/hle/service/err_f.cpp +++ b/src/core/hle/service/err_f.cpp @@ -5,7 +5,6 @@ #include "common/bit_field.h" #include "common/common_types.h" #include "common/logging/log.h" - #include "core/hle/service/err_f.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -35,70 +34,70 @@ union ErrInfo { u8 specifier; struct { - u8 specifier; // 0x0 - u8 rev_high; // 0x1 - u16 rev_low; // 0x2 - RSL result_code; // 0x4 - u32 address; // 0x8 - INSERT_PADDING_BYTES(4); // 0xC - u32 pid_low; // 0x10 - u32 pid_high; // 0x14 - u32 aid_low; // 0x18 - u32 aid_high; // 0x1C + u8 specifier; // 0x0 + u8 rev_high; // 0x1 + u16 rev_low; // 0x2 + RSL result_code; // 0x4 + u32 address; // 0x8 + INSERT_PADDING_BYTES(4); // 0xC + u32 pid_low; // 0x10 + u32 pid_high; // 0x14 + u32 aid_low; // 0x18 + u32 aid_high; // 0x1C } errtype1; struct { - u8 specifier; // 0x0 - u8 rev_high; // 0x1 - u16 rev_low; // 0x2 - INSERT_PADDING_BYTES(0xC); // 0x4 - u32 pid_low; // 0x10 - u32 pid_high; // 0x14 - u32 aid_low; // 0x18 - u32 aid_high; // 0x1C - u8 error_type; // 0x20 - INSERT_PADDING_BYTES(3); // 0x21 - u32 fault_status_reg; // 0x24 - u32 fault_addr; // 0x28 - u32 fpexc; // 0x2C - u32 finst; // 0x30 - u32 finst2; // 0x34 - INSERT_PADDING_BYTES(0x34); // 0x38 - u32 sp; // 0x6C - u32 pc; // 0x70 - u32 lr; // 0x74 - u32 cpsr; // 0x78 + u8 specifier; // 0x0 + u8 rev_high; // 0x1 + u16 rev_low; // 0x2 + INSERT_PADDING_BYTES(0xC); // 0x4 + u32 pid_low; // 0x10 + u32 pid_high; // 0x14 + u32 aid_low; // 0x18 + u32 aid_high; // 0x1C + u8 error_type; // 0x20 + INSERT_PADDING_BYTES(3); // 0x21 + u32 fault_status_reg; // 0x24 + u32 fault_addr; // 0x28 + u32 fpexc; // 0x2C + u32 finst; // 0x30 + u32 finst2; // 0x34 + INSERT_PADDING_BYTES(0x34); // 0x38 + u32 sp; // 0x6C + u32 pc; // 0x70 + u32 lr; // 0x74 + u32 cpsr; // 0x78 } errtype3; struct { - u8 specifier; // 0x0 - u8 rev_high; // 0x1 - u16 rev_low; // 0x2 - RSL result_code; // 0x4 - INSERT_PADDING_BYTES(8); // 0x8 - u32 pid_low; // 0x10 - u32 pid_high; // 0x14 - u32 aid_low; // 0x18 - u32 aid_high; // 0x1C - char debug_string1[0x2E]; // 0x20 - char debug_string2[0x2E]; // 0x4E + u8 specifier; // 0x0 + u8 rev_high; // 0x1 + u16 rev_low; // 0x2 + RSL result_code; // 0x4 + INSERT_PADDING_BYTES(8); // 0x8 + u32 pid_low; // 0x10 + u32 pid_high; // 0x14 + u32 aid_low; // 0x18 + u32 aid_high; // 0x1C + char debug_string1[0x2E]; // 0x20 + char debug_string2[0x2E]; // 0x4E } errtype4; }; -enum { - PrefetchAbort = 0, - DataAbort = 1, - UndefInstr = 2, - VectorFP = 3 -}; +enum { PrefetchAbort = 0, DataAbort = 1, UndefInstr = 2, VectorFP = 3 }; static std::string GetErrInfo3Type(u8 type_code) { switch (type_code) { - case PrefetchAbort: return "Prefetch Abort"; - case DataAbort: return "Data Abort"; - case UndefInstr: return "Undefined Instruction"; - case VectorFP: return "Vector Floating Point"; - default: return "unknown"; + case PrefetchAbort: + return "Prefetch Abort"; + case DataAbort: + return "Data Abort"; + case UndefInstr: + return "Undefined Instruction"; + case VectorFP: + return "Vector Floating Point"; + default: + return "unknown"; } } @@ -110,8 +109,7 @@ static void ThrowFatalError(Service::Interface* self) { switch (errinfo->specifier) { case ErrSpecifier0: - case ErrSpecifier1: - { + case ErrSpecifier1: { const auto& errtype = errinfo->errtype1; LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high); LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16)); @@ -119,15 +117,14 @@ static void ThrowFatalError(Service::Interface* self) { LOG_CRITICAL(Service_ERR, "ADR: 0x%08X", errtype.address); LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", errtype.result_code.raw); - LOG_CRITICAL(Service_ERR, " Level: %u", errtype.result_code.level.Value()); + LOG_CRITICAL(Service_ERR, " Level: %u", errtype.result_code.level.Value()); LOG_CRITICAL(Service_ERR, " Summary: %u", errtype.result_code.summary.Value()); - LOG_CRITICAL(Service_ERR, " Module: %u", errtype.result_code.module.Value()); - LOG_CRITICAL(Service_ERR, " Desc: %u", errtype.result_code.description.Value()); + LOG_CRITICAL(Service_ERR, " Module: %u", errtype.result_code.module.Value()); + LOG_CRITICAL(Service_ERR, " Desc: %u", errtype.result_code.description.Value()); break; } - case ErrSpecifier3: - { + case ErrSpecifier3: { const auto& errtype = errinfo->errtype3; LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high); LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16)); @@ -154,18 +151,17 @@ static void ThrowFatalError(Service::Interface* self) { break; } - case ErrSpecifier4: - { + case ErrSpecifier4: { const auto& errtype = errinfo->errtype4; LOG_CRITICAL(Service_ERR, "PID: 0x%08X_0x%08X", errtype.pid_low, errtype.pid_high); LOG_CRITICAL(Service_ERR, "REV: %d", errtype.rev_low | (errtype.rev_high << 16)); LOG_CRITICAL(Service_ERR, "AID: 0x%08X_0x%08X", errtype.aid_low, errtype.aid_high); LOG_CRITICAL(Service_ERR, "RSL: 0x%08X", errtype.result_code.raw); - LOG_CRITICAL(Service_ERR, " Level: %u", errtype.result_code.level.Value()); + LOG_CRITICAL(Service_ERR, " Level: %u", errtype.result_code.level.Value()); LOG_CRITICAL(Service_ERR, " Summary: %u", errtype.result_code.summary.Value()); - LOG_CRITICAL(Service_ERR, " Module: %u", errtype.result_code.module.Value()); - LOG_CRITICAL(Service_ERR, " Desc: %u", errtype.result_code.description.Value()); + LOG_CRITICAL(Service_ERR, " Module: %u", errtype.result_code.module.Value()); + LOG_CRITICAL(Service_ERR, " Desc: %u", errtype.result_code.description.Value()); LOG_CRITICAL(Service_ERR, "%s", errtype.debug_string1); LOG_CRITICAL(Service_ERR, "%s", errtype.debug_string2); @@ -177,7 +173,7 @@ static void ThrowFatalError(Service::Interface* self) { } const Interface::FunctionInfo FunctionTable[] = { - {0x00010800, ThrowFatalError, "ThrowFatalError"} + {0x00010800, ThrowFatalError, "ThrowFatalError"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/frd/frd.cpp b/src/core/hle/service/frd/frd.cpp index 29d144365..fa5080535 100644 --- a/src/core/hle/service/frd/frd.cpp +++ b/src/core/hle/service/frd/frd.cpp @@ -3,11 +3,10 @@ // Refer to the license.txt file included. #include "common/string_util.h" - -#include "core/hle/service/service.h" #include "core/hle/service/frd/frd.h" #include "core/hle/service/frd/frd_a.h" #include "core/hle/service/frd/frd_u.h" +#include "core/hle/service/service.h" namespace Service { namespace FRD { @@ -43,7 +42,7 @@ void GetFriendKeyList(Service::Interface* self) { } cmd_buff[1] = RESULT_SUCCESS.raw; // No error - cmd_buff[2] = 0; // 0 friends + cmd_buff[2] = 0; // 0 friends LOG_WARNING(Service_FRD, "(STUBBED) called, unknown=%d, frd_count=%d, frd_key_addr=0x%08X", unknown, frd_count, frd_key_addr); } @@ -61,25 +60,27 @@ void GetFriendProfile(Service::Interface* self) { } cmd_buff[1] = RESULT_SUCCESS.raw; // No error - LOG_WARNING(Service_FRD, "(STUBBED) called, count=%d, frd_key_addr=0x%08X, profiles_addr=0x%08X", - count, frd_key_addr, profiles_addr); + LOG_WARNING(Service_FRD, + "(STUBBED) called, count=%d, frd_key_addr=0x%08X, profiles_addr=0x%08X", count, + frd_key_addr, profiles_addr); } void GetFriendAttributeFlags(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - u32 count = cmd_buff[1]; - u32 frd_key_addr = cmd_buff[3]; + u32 count = cmd_buff[1]; + u32 frd_key_addr = cmd_buff[3]; u32 attr_flags_addr = cmd_buff[65]; for (u32 i = 0; i < count; ++i) { - //TODO:(mailwl) figure out AttributeFlag size and zero all buffer. Assume 1 byte + // TODO:(mailwl) figure out AttributeFlag size and zero all buffer. Assume 1 byte Memory::Write8(attr_flags_addr + i, 0); } cmd_buff[1] = RESULT_SUCCESS.raw; // No error - LOG_WARNING(Service_FRD, "(STUBBED) called, count=%d, frd_key_addr=0x%08X, attr_flags_addr=0x%08X", - count, frd_key_addr, attr_flags_addr); + LOG_WARNING(Service_FRD, + "(STUBBED) called, count=%d, frd_key_addr=0x%08X, attr_flags_addr=0x%08X", count, + frd_key_addr, attr_flags_addr); } void GetMyFriendKey(Service::Interface* self) { @@ -106,8 +107,7 @@ void Init() { AddService(new FRD_U_Interface); } -void Shutdown() { -} +void Shutdown() {} } // namespace FRD diff --git a/src/core/hle/service/frd/frd_a.cpp b/src/core/hle/service/frd/frd_a.cpp index 818d610f3..cfc37210b 100644 --- a/src/core/hle/service/frd/frd_a.cpp +++ b/src/core/hle/service/frd/frd_a.cpp @@ -11,7 +11,7 @@ namespace FRD { // const Interface::FunctionInfo FunctionTable[] = { }; FRD_A_Interface::FRD_A_Interface() { - //Register(FunctionTable); + // Register(FunctionTable); } } // namespace FRD diff --git a/src/core/hle/service/frd/frd_u.cpp b/src/core/hle/service/frd/frd_u.cpp index db8666416..bd1c9c16b 100644 --- a/src/core/hle/service/frd/frd_u.cpp +++ b/src/core/hle/service/frd/frd_u.cpp @@ -9,59 +9,59 @@ namespace Service { namespace FRD { const Interface::FunctionInfo FunctionTable[] = { - {0x00010000, nullptr, "HasLoggedIn"}, - {0x00020000, nullptr, "IsOnline"}, - {0x00030000, nullptr, "Login"}, - {0x00040000, nullptr, "Logout"}, - {0x00050000, GetMyFriendKey, "GetMyFriendKey"}, - {0x00060000, nullptr, "GetMyPreference"}, - {0x00070000, nullptr, "GetMyProfile"}, - {0x00080000, GetMyPresence, "GetMyPresence"}, - {0x00090000, GetMyScreenName, "GetMyScreenName"}, - {0x000A0000, nullptr, "GetMyMii"}, - {0x000B0000, nullptr, "GetMyLocalAccountId"}, - {0x000C0000, nullptr, "GetMyPlayingGame"}, - {0x000D0000, nullptr, "GetMyFavoriteGame"}, - {0x000E0000, nullptr, "GetMyNcPrincipalId"}, - {0x000F0000, nullptr, "GetMyComment"}, - {0x00100040, nullptr, "GetMyPassword"}, - {0x00110080, GetFriendKeyList, "GetFriendKeyList"}, - {0x00120042, nullptr, "GetFriendPresence"}, - {0x00130142, nullptr, "GetFriendScreenName"}, - {0x00140044, nullptr, "GetFriendMii"}, - {0x00150042, GetFriendProfile, "GetFriendProfile"}, - {0x00160042, nullptr, "GetFriendRelationship"}, + {0x00010000, nullptr, "HasLoggedIn"}, + {0x00020000, nullptr, "IsOnline"}, + {0x00030000, nullptr, "Login"}, + {0x00040000, nullptr, "Logout"}, + {0x00050000, GetMyFriendKey, "GetMyFriendKey"}, + {0x00060000, nullptr, "GetMyPreference"}, + {0x00070000, nullptr, "GetMyProfile"}, + {0x00080000, GetMyPresence, "GetMyPresence"}, + {0x00090000, GetMyScreenName, "GetMyScreenName"}, + {0x000A0000, nullptr, "GetMyMii"}, + {0x000B0000, nullptr, "GetMyLocalAccountId"}, + {0x000C0000, nullptr, "GetMyPlayingGame"}, + {0x000D0000, nullptr, "GetMyFavoriteGame"}, + {0x000E0000, nullptr, "GetMyNcPrincipalId"}, + {0x000F0000, nullptr, "GetMyComment"}, + {0x00100040, nullptr, "GetMyPassword"}, + {0x00110080, GetFriendKeyList, "GetFriendKeyList"}, + {0x00120042, nullptr, "GetFriendPresence"}, + {0x00130142, nullptr, "GetFriendScreenName"}, + {0x00140044, nullptr, "GetFriendMii"}, + {0x00150042, GetFriendProfile, "GetFriendProfile"}, + {0x00160042, nullptr, "GetFriendRelationship"}, {0x00170042, GetFriendAttributeFlags, "GetFriendAttributeFlags"}, - {0x00180044, nullptr, "GetFriendPlayingGame"}, - {0x00190042, nullptr, "GetFriendFavoriteGame"}, - {0x001A00C4, nullptr, "GetFriendInfo"}, - {0x001B0080, nullptr, "IsIncludedInFriendList"}, - {0x001C0042, nullptr, "UnscrambleLocalFriendCode"}, - {0x001D0002, nullptr, "UpdateGameModeDescription"}, - {0x001E02C2, nullptr, "UpdateGameMode"}, - {0x001F0042, nullptr, "SendInvitation"}, - {0x00200002, nullptr, "AttachToEventNotification"}, - {0x00210040, nullptr, "SetNotificationMask"}, - {0x00220040, nullptr, "GetEventNotification"}, - {0x00230000, nullptr, "GetLastResponseResult"}, - {0x00240040, nullptr, "PrincipalIdToFriendCode"}, - {0x00250080, nullptr, "FriendCodeToPrincipalId"}, - {0x00260080, nullptr, "IsValidFriendCode"}, - {0x00270040, nullptr, "ResultToErrorCode"}, - {0x00280244, nullptr, "RequestGameAuthentication"}, - {0x00290000, nullptr, "GetGameAuthenticationData"}, - {0x002A0204, nullptr, "RequestServiceLocator"}, - {0x002B0000, nullptr, "GetServiceLocatorData"}, - {0x002C0002, nullptr, "DetectNatProperties"}, - {0x002D0000, nullptr, "GetNatProperties"}, - {0x002E0000, nullptr, "GetServerTimeInterval"}, - {0x002F0040, nullptr, "AllowHalfAwake"}, - {0x00300000, nullptr, "GetServerTypes"}, - {0x00310082, nullptr, "GetFriendComment"}, - {0x00320042, nullptr, "SetClientSdkVersion"}, - {0x00330000, nullptr, "GetMyApproachContext"}, - {0x00340046, nullptr, "AddFriendWithApproach"}, - {0x00350082, nullptr, "DecryptApproachContext"}, + {0x00180044, nullptr, "GetFriendPlayingGame"}, + {0x00190042, nullptr, "GetFriendFavoriteGame"}, + {0x001A00C4, nullptr, "GetFriendInfo"}, + {0x001B0080, nullptr, "IsIncludedInFriendList"}, + {0x001C0042, nullptr, "UnscrambleLocalFriendCode"}, + {0x001D0002, nullptr, "UpdateGameModeDescription"}, + {0x001E02C2, nullptr, "UpdateGameMode"}, + {0x001F0042, nullptr, "SendInvitation"}, + {0x00200002, nullptr, "AttachToEventNotification"}, + {0x00210040, nullptr, "SetNotificationMask"}, + {0x00220040, nullptr, "GetEventNotification"}, + {0x00230000, nullptr, "GetLastResponseResult"}, + {0x00240040, nullptr, "PrincipalIdToFriendCode"}, + {0x00250080, nullptr, "FriendCodeToPrincipalId"}, + {0x00260080, nullptr, "IsValidFriendCode"}, + {0x00270040, nullptr, "ResultToErrorCode"}, + {0x00280244, nullptr, "RequestGameAuthentication"}, + {0x00290000, nullptr, "GetGameAuthenticationData"}, + {0x002A0204, nullptr, "RequestServiceLocator"}, + {0x002B0000, nullptr, "GetServiceLocatorData"}, + {0x002C0002, nullptr, "DetectNatProperties"}, + {0x002D0000, nullptr, "GetNatProperties"}, + {0x002E0000, nullptr, "GetServerTimeInterval"}, + {0x002F0040, nullptr, "AllowHalfAwake"}, + {0x00300000, nullptr, "GetServerTypes"}, + {0x00310082, nullptr, "GetFriendComment"}, + {0x00320042, nullptr, "SetClientSdkVersion"}, + {0x00330000, nullptr, "GetMyApproachContext"}, + {0x00340046, nullptr, "AddFriendWithApproach"}, + {0x00350082, nullptr, "DecryptApproachContext"}, }; FRD_U_Interface::FRD_U_Interface() { diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 4c7aaa7f2..4dc7e1e3c 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -3,19 +3,16 @@ // Refer to the license.txt file included. #include <cstddef> +#include <memory> #include <system_error> #include <type_traits> -#include <memory> #include <unordered_map> #include <utility> - #include <boost/container/flat_map.hpp> - #include "common/assert.h" #include "common/common_types.h" #include "common/file_util.h" #include "common/logging/log.h" - #include "core/file_sys/archive_backend.h" #include "core/file_sys/archive_extsavedata.h" #include "core/file_sys/archive_savedata.h" @@ -25,25 +22,25 @@ #include "core/file_sys/directory_backend.h" #include "core/file_sys/file_backend.h" #include "core/hle/hle.h" -#include "core/hle/service/service.h" +#include "core/hle/result.h" #include "core/hle/service/fs/archive.h" #include "core/hle/service/fs/fs_user.h" -#include "core/hle/result.h" +#include "core/hle/service/service.h" #include "core/memory.h" // Specializes std::hash for ArchiveIdCode, so that we can use it in std::unordered_map. // Workaroung for libstdc++ bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60970 namespace std { - template <> - struct hash<Service::FS::ArchiveIdCode> { - typedef Service::FS::ArchiveIdCode argument_type; - typedef std::size_t result_type; - - result_type operator()(const argument_type& id_code) const { - typedef std::underlying_type<argument_type>::type Type; - return std::hash<Type>()(static_cast<Type>(id_code)); - } - }; +template <> +struct hash<Service::FS::ArchiveIdCode> { + typedef Service::FS::ArchiveIdCode argument_type; + typedef std::size_t result_type; + + result_type operator()(const argument_type& id_code) const { + typedef std::underlying_type<argument_type>::type Type; + return std::hash<Type>()(static_cast<Type>(id_code)); + } +}; } /// TODO(Subv): Confirm length of these strings @@ -56,39 +53,40 @@ namespace FS { // TODO: Verify code /// Returned when a function is passed an invalid handle. const ResultCode ERR_INVALID_HANDLE(ErrorDescription::InvalidHandle, ErrorModule::FS, - ErrorSummary::InvalidArgument, ErrorLevel::Permanent); + ErrorSummary::InvalidArgument, ErrorLevel::Permanent); /// Returned when a function is passed an invalid archive handle. const ResultCode ERR_INVALID_ARCHIVE_HANDLE(ErrorDescription::FS_ArchiveNotMounted, ErrorModule::FS, - ErrorSummary::NotFound, ErrorLevel::Status); // 0xC8804465 + ErrorSummary::NotFound, + ErrorLevel::Status); // 0xC8804465 // Command to access archive file enum class FileCommand : u32 { - Dummy1 = 0x000100C6, - Control = 0x040100C4, - OpenSubFile = 0x08010100, - Read = 0x080200C2, - Write = 0x08030102, - GetSize = 0x08040000, - SetSize = 0x08050080, - GetAttributes = 0x08060000, - SetAttributes = 0x08070040, - Close = 0x08080000, - Flush = 0x08090000, - SetPriority = 0x080A0040, - GetPriority = 0x080B0000, - OpenLinkFile = 0x080C0000, + Dummy1 = 0x000100C6, + Control = 0x040100C4, + OpenSubFile = 0x08010100, + Read = 0x080200C2, + Write = 0x08030102, + GetSize = 0x08040000, + SetSize = 0x08050080, + GetAttributes = 0x08060000, + SetAttributes = 0x08070040, + Close = 0x08080000, + Flush = 0x08090000, + SetPriority = 0x080A0040, + GetPriority = 0x080B0000, + OpenLinkFile = 0x080C0000, }; // Command to access directory enum class DirectoryCommand : u32 { - Dummy1 = 0x000100C6, - Control = 0x040100C4, - Read = 0x08010042, - Close = 0x08020000, + Dummy1 = 0x000100C6, + Control = 0x040100C4, + Read = 0x08010042, + Close = 0x08020000, }; -File::File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path & path) +File::File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path) : path(path), priority(0), backend(std::move(backend)) {} File::~File() {} @@ -98,117 +96,110 @@ ResultVal<bool> File::SyncRequest() { FileCommand cmd = static_cast<FileCommand>(cmd_buff[0]); switch (cmd) { - // Read from file... - case FileCommand::Read: - { - u64 offset = cmd_buff[1] | ((u64)cmd_buff[2]) << 32; - u32 length = cmd_buff[3]; - u32 address = cmd_buff[5]; - LOG_TRACE(Service_FS, "Read %s %s: offset=0x%llx length=%d address=0x%x", - GetTypeName().c_str(), GetName().c_str(), offset, length, address); - - if (offset + length > backend->GetSize()) { - LOG_ERROR(Service_FS, "Reading from out of bounds offset=0x%llX length=0x%08X file_size=0x%llX", - offset, length, backend->GetSize()); - } - - std::vector<u8> data(length); - ResultVal<size_t> read = backend->Read(offset, data.size(), data.data()); - if (read.Failed()) { - cmd_buff[1] = read.Code().raw; - return read.Code(); - } - Memory::WriteBlock(address, data.data(), *read); - cmd_buff[2] = static_cast<u32>(*read); - break; + // Read from file... + case FileCommand::Read: { + u64 offset = cmd_buff[1] | ((u64)cmd_buff[2]) << 32; + u32 length = cmd_buff[3]; + u32 address = cmd_buff[5]; + LOG_TRACE(Service_FS, "Read %s %s: offset=0x%llx length=%d address=0x%x", + GetTypeName().c_str(), GetName().c_str(), offset, length, address); + + if (offset + length > backend->GetSize()) { + LOG_ERROR(Service_FS, + "Reading from out of bounds offset=0x%llX length=0x%08X file_size=0x%llX", + offset, length, backend->GetSize()); } - // Write to file... - case FileCommand::Write: - { - u64 offset = cmd_buff[1] | ((u64)cmd_buff[2]) << 32; - u32 length = cmd_buff[3]; - u32 flush = cmd_buff[4]; - u32 address = cmd_buff[6]; - LOG_TRACE(Service_FS, "Write %s %s: offset=0x%llx length=%d address=0x%x, flush=0x%x", - GetTypeName().c_str(), GetName().c_str(), offset, length, address, flush); - - std::vector<u8> data(length); - Memory::ReadBlock(address, data.data(), data.size()); - ResultVal<size_t> written = backend->Write(offset, data.size(), flush != 0, data.data()); - if (written.Failed()) { - cmd_buff[1] = written.Code().raw; - return written.Code(); - } - cmd_buff[2] = static_cast<u32>(*written); - break; + std::vector<u8> data(length); + ResultVal<size_t> read = backend->Read(offset, data.size(), data.data()); + if (read.Failed()) { + cmd_buff[1] = read.Code().raw; + return read.Code(); } + Memory::WriteBlock(address, data.data(), *read); + cmd_buff[2] = static_cast<u32>(*read); + break; + } - case FileCommand::GetSize: - { - LOG_TRACE(Service_FS, "GetSize %s %s", GetTypeName().c_str(), GetName().c_str()); - u64 size = backend->GetSize(); - cmd_buff[2] = (u32)size; - cmd_buff[3] = size >> 32; - break; + // Write to file... + case FileCommand::Write: { + u64 offset = cmd_buff[1] | ((u64)cmd_buff[2]) << 32; + u32 length = cmd_buff[3]; + u32 flush = cmd_buff[4]; + u32 address = cmd_buff[6]; + LOG_TRACE(Service_FS, "Write %s %s: offset=0x%llx length=%d address=0x%x, flush=0x%x", + GetTypeName().c_str(), GetName().c_str(), offset, length, address, flush); + + std::vector<u8> data(length); + Memory::ReadBlock(address, data.data(), data.size()); + ResultVal<size_t> written = backend->Write(offset, data.size(), flush != 0, data.data()); + if (written.Failed()) { + cmd_buff[1] = written.Code().raw; + return written.Code(); } + cmd_buff[2] = static_cast<u32>(*written); + break; + } - case FileCommand::SetSize: - { - u64 size = cmd_buff[1] | ((u64)cmd_buff[2] << 32); - LOG_TRACE(Service_FS, "SetSize %s %s size=%llu", - GetTypeName().c_str(), GetName().c_str(), size); - backend->SetSize(size); - break; - } + case FileCommand::GetSize: { + LOG_TRACE(Service_FS, "GetSize %s %s", GetTypeName().c_str(), GetName().c_str()); + u64 size = backend->GetSize(); + cmd_buff[2] = (u32)size; + cmd_buff[3] = size >> 32; + break; + } - case FileCommand::Close: - { - LOG_TRACE(Service_FS, "Close %s %s", GetTypeName().c_str(), GetName().c_str()); - backend->Close(); - break; - } + case FileCommand::SetSize: { + u64 size = cmd_buff[1] | ((u64)cmd_buff[2] << 32); + LOG_TRACE(Service_FS, "SetSize %s %s size=%llu", GetTypeName().c_str(), GetName().c_str(), + size); + backend->SetSize(size); + break; + } - case FileCommand::Flush: - { - LOG_TRACE(Service_FS, "Flush"); - backend->Flush(); - break; - } + case FileCommand::Close: { + LOG_TRACE(Service_FS, "Close %s %s", GetTypeName().c_str(), GetName().c_str()); + backend->Close(); + break; + } - case FileCommand::OpenLinkFile: - { - LOG_WARNING(Service_FS, "(STUBBED) File command OpenLinkFile %s", GetName().c_str()); - cmd_buff[3] = Kernel::g_handle_table.Create(this).ValueOr(INVALID_HANDLE); - break; - } + case FileCommand::Flush: { + LOG_TRACE(Service_FS, "Flush"); + backend->Flush(); + break; + } - case FileCommand::SetPriority: - { - priority = cmd_buff[1]; - LOG_TRACE(Service_FS, "SetPriority %u", priority); - break; - } + case FileCommand::OpenLinkFile: { + LOG_WARNING(Service_FS, "(STUBBED) File command OpenLinkFile %s", GetName().c_str()); + cmd_buff[3] = Kernel::g_handle_table.Create(this).ValueOr(INVALID_HANDLE); + break; + } - case FileCommand::GetPriority: - { - cmd_buff[2] = priority; - LOG_TRACE(Service_FS, "GetPriority"); - break; - } + case FileCommand::SetPriority: { + priority = cmd_buff[1]; + LOG_TRACE(Service_FS, "SetPriority %u", priority); + break; + } + + case FileCommand::GetPriority: { + cmd_buff[2] = priority; + LOG_TRACE(Service_FS, "GetPriority"); + break; + } - // Unknown command... - default: - LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd); - ResultCode error = UnimplementedFunction(ErrorModule::FS); - cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that. - return error; + // Unknown command... + default: + LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd); + ResultCode error = UnimplementedFunction(ErrorModule::FS); + cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that. + return error; } cmd_buff[1] = RESULT_SUCCESS.raw; // No error return MakeResult<bool>(false); } -Directory::Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path & path) +Directory::Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, + const FileSys::Path& path) : path(path), backend(std::move(backend)) {} Directory::~Directory() {} @@ -218,35 +209,33 @@ ResultVal<bool> Directory::SyncRequest() { DirectoryCommand cmd = static_cast<DirectoryCommand>(cmd_buff[0]); switch (cmd) { - // Read from directory... - case DirectoryCommand::Read: - { - u32 count = cmd_buff[1]; - u32 address = cmd_buff[3]; - std::vector<FileSys::Entry> entries(count); - LOG_TRACE(Service_FS, "Read %s %s: count=%d", - GetTypeName().c_str(), GetName().c_str(), count); - - // Number of entries actually read - u32 read = backend->Read(entries.size(), entries.data()); - cmd_buff[2] = read; - Memory::WriteBlock(address, entries.data(), read * sizeof(FileSys::Entry)); - break; - } + // Read from directory... + case DirectoryCommand::Read: { + u32 count = cmd_buff[1]; + u32 address = cmd_buff[3]; + std::vector<FileSys::Entry> entries(count); + LOG_TRACE(Service_FS, "Read %s %s: count=%d", GetTypeName().c_str(), GetName().c_str(), + count); + + // Number of entries actually read + u32 read = backend->Read(entries.size(), entries.data()); + cmd_buff[2] = read; + Memory::WriteBlock(address, entries.data(), read * sizeof(FileSys::Entry)); + break; + } - case DirectoryCommand::Close: - { - LOG_TRACE(Service_FS, "Close %s %s", GetTypeName().c_str(), GetName().c_str()); - backend->Close(); - break; - } + case DirectoryCommand::Close: { + LOG_TRACE(Service_FS, "Close %s %s", GetTypeName().c_str(), GetName().c_str()); + backend->Close(); + break; + } - // Unknown command... - default: - LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd); - ResultCode error = UnimplementedFunction(ErrorModule::FS); - cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that. - return MakeResult<bool>(false); + // Unknown command... + default: + LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd); + ResultCode error = UnimplementedFunction(ErrorModule::FS); + cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that. + return MakeResult<bool>(false); } cmd_buff[1] = RESULT_SUCCESS.raw; // No error return MakeResult<bool>(false); @@ -280,8 +269,8 @@ ResultVal<ArchiveHandle> OpenArchive(ArchiveIdCode id_code, FileSys::Path& archi auto itr = id_code_map.find(id_code); if (itr == id_code_map.end()) { // TODO: Verify error against hardware - return ResultCode(ErrorDescription::NotFound, ErrorModule::FS, - ErrorSummary::NotFound, ErrorLevel::Permanent); + return ResultCode(ErrorDescription::NotFound, ErrorModule::FS, ErrorSummary::NotFound, + ErrorLevel::Permanent); } CASCADE_RESULT(std::unique_ptr<ArchiveBackend> res, itr->second->Open(archive_path)); @@ -303,19 +292,22 @@ ResultCode CloseArchive(ArchiveHandle handle) { // TODO(yuriks): This might be what the fs:REG service is for. See the Register/Unregister calls in // http://3dbrew.org/wiki/Filesystem_services#ProgramRegistry_service_.22fs:REG.22 -ResultCode RegisterArchiveType(std::unique_ptr<FileSys::ArchiveFactory>&& factory, ArchiveIdCode id_code) { +ResultCode RegisterArchiveType(std::unique_ptr<FileSys::ArchiveFactory>&& factory, + ArchiveIdCode id_code) { auto result = id_code_map.emplace(id_code, std::move(factory)); bool inserted = result.second; ASSERT_MSG(inserted, "Tried to register more than one archive with same id code"); auto& archive = result.first->second; - LOG_DEBUG(Service_FS, "Registered archive %s with id code 0x%08X", archive->GetName().c_str(), id_code); + LOG_DEBUG(Service_FS, "Registered archive %s with id code 0x%08X", archive->GetName().c_str(), + id_code); return RESULT_SUCCESS; } ResultVal<Kernel::SharedPtr<File>> OpenFileFromArchive(ArchiveHandle archive_handle, - const FileSys::Path& path, const FileSys::Mode mode) { + const FileSys::Path& path, + const FileSys::Mode mode) { ArchiveBackend* archive = GetArchive(archive_handle); if (archive == nullptr) return ERR_INVALID_ARCHIVE_HANDLE; @@ -336,8 +328,10 @@ ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Pa return archive->DeleteFile(path); } -ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, - ArchiveHandle dest_archive_handle, const FileSys::Path& dest_path) { +ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, + const FileSys::Path& src_path, + ArchiveHandle dest_archive_handle, + const FileSys::Path& dest_path) { ArchiveBackend* src_archive = GetArchive(src_archive_handle); ArchiveBackend* dest_archive = GetArchive(dest_archive_handle); if (src_archive == nullptr || dest_archive == nullptr) @@ -368,7 +362,8 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy ErrorSummary::Canceled, ErrorLevel::Status); } -ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u64 file_size) { +ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, + u64 file_size) { ArchiveBackend* archive = GetArchive(archive_handle); if (archive == nullptr) return ERR_INVALID_ARCHIVE_HANDLE; @@ -387,8 +382,10 @@ ResultCode CreateDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy ErrorSummary::Canceled, ErrorLevel::Status); } -ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, - ArchiveHandle dest_archive_handle, const FileSys::Path& dest_path) { +ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, + const FileSys::Path& src_path, + ArchiveHandle dest_archive_handle, + const FileSys::Path& dest_path) { ArchiveBackend* src_archive = GetArchive(src_archive_handle); ArchiveBackend* dest_archive = GetArchive(dest_archive_handle); if (src_archive == nullptr || dest_archive == nullptr) @@ -409,15 +406,15 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, cons } ResultVal<Kernel::SharedPtr<Directory>> OpenDirectoryFromArchive(ArchiveHandle archive_handle, - const FileSys::Path& path) { + const FileSys::Path& path) { ArchiveBackend* archive = GetArchive(archive_handle); if (archive == nullptr) return ERR_INVALID_ARCHIVE_HANDLE; std::unique_ptr<FileSys::DirectoryBackend> backend = archive->OpenDirectory(path); if (backend == nullptr) { - return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, - ErrorSummary::NotFound, ErrorLevel::Permanent); + return ResultCode(ErrorDescription::FS_NotFound, ErrorModule::FS, ErrorSummary::NotFound, + ErrorLevel::Permanent); } auto directory = Kernel::SharedPtr<Directory>(new Directory(std::move(backend), path)); @@ -431,7 +428,8 @@ ResultVal<u64> GetFreeBytesInArchive(ArchiveHandle archive_handle) { return MakeResult<u64>(archive->GetFreeBytes()); } -ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo& format_info, const FileSys::Path& path) { +ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo& format_info, + const FileSys::Path& path) { auto archive_itr = id_code_map.find(id_code); if (archive_itr == id_code_map.end()) { return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error @@ -440,7 +438,8 @@ ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo return archive_itr->second->Format(path, format_info); } -ResultVal<FileSys::ArchiveFormatInfo> GetArchiveFormatInfo(ArchiveIdCode id_code, FileSys::Path& archive_path) { +ResultVal<FileSys::ArchiveFormatInfo> GetArchiveFormatInfo(ArchiveIdCode id_code, + FileSys::Path& archive_path) { auto archive = id_code_map.find(id_code); if (archive == id_code_map.end()) { return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error @@ -449,11 +448,14 @@ ResultVal<FileSys::ArchiveFormatInfo> GetArchiveFormatInfo(ArchiveIdCode id_code return archive->second->GetFormatInfo(archive_path); } -ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, VAddr icon_buffer, u32 icon_size, const FileSys::ArchiveFormatInfo& format_info) { +ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, VAddr icon_buffer, + u32 icon_size, const FileSys::ArchiveFormatInfo& format_info) { // Construct the binary path to the archive first - FileSys::Path path = FileSys::ConstructExtDataBinaryPath(static_cast<u32>(media_type), high, low); + FileSys::Path path = + FileSys::ConstructExtDataBinaryPath(static_cast<u32>(media_type), high, low); - auto archive = id_code_map.find(media_type == MediaType::NAND ? ArchiveIdCode::SharedExtSaveData : ArchiveIdCode::ExtSaveData); + auto archive = id_code_map.find(media_type == MediaType::NAND ? ArchiveIdCode::SharedExtSaveData + : ArchiveIdCode::ExtSaveData); if (archive == id_code_map.end()) { return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error @@ -476,7 +478,8 @@ ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, VAddr icon ResultCode DeleteExtSaveData(MediaType media_type, u32 high, u32 low) { // Construct the binary path to the archive first - FileSys::Path path = FileSys::ConstructExtDataBinaryPath(static_cast<u32>(media_type), high, low); + FileSys::Path path = + FileSys::ConstructExtDataBinaryPath(static_cast<u32>(media_type), high, low); std::string media_type_directory; if (media_type == MediaType::NAND) { @@ -489,7 +492,8 @@ ResultCode DeleteExtSaveData(MediaType media_type, u32 high, u32 low) { } // Delete all directories (/user, /boss) and the icon file. - std::string base_path = FileSys::GetExtDataContainerPath(media_type_directory, media_type == MediaType::NAND); + std::string base_path = + FileSys::GetExtDataContainerPath(media_type_directory, media_type == MediaType::NAND); std::string extsavedata_path = FileSys::GetExtSaveDataPath(base_path, path); if (FileUtil::Exists(extsavedata_path) && !FileUtil::DeleteDirRecursively(extsavedata_path)) return ResultCode(-1); // TODO(Subv): Find the right error code @@ -530,30 +534,36 @@ void RegisterArchiveTypes() { if (sdmc_factory->Initialize()) RegisterArchiveType(std::move(sdmc_factory), ArchiveIdCode::SDMC); else - LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", sdmc_directory.c_str()); + LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", + sdmc_directory.c_str()); // Create the SaveData archive auto savedata_factory = std::make_unique<FileSys::ArchiveFactory_SaveData>(sdmc_directory); RegisterArchiveType(std::move(savedata_factory), ArchiveIdCode::SaveData); - auto extsavedata_factory = std::make_unique<FileSys::ArchiveFactory_ExtSaveData>(sdmc_directory, false); + auto extsavedata_factory = + std::make_unique<FileSys::ArchiveFactory_ExtSaveData>(sdmc_directory, false); if (extsavedata_factory->Initialize()) RegisterArchiveType(std::move(extsavedata_factory), ArchiveIdCode::ExtSaveData); else - LOG_ERROR(Service_FS, "Can't instantiate ExtSaveData archive with path %s", extsavedata_factory->GetMountPoint().c_str()); + LOG_ERROR(Service_FS, "Can't instantiate ExtSaveData archive with path %s", + extsavedata_factory->GetMountPoint().c_str()); - auto sharedextsavedata_factory = std::make_unique<FileSys::ArchiveFactory_ExtSaveData>(nand_directory, true); + auto sharedextsavedata_factory = + std::make_unique<FileSys::ArchiveFactory_ExtSaveData>(nand_directory, true); if (sharedextsavedata_factory->Initialize()) RegisterArchiveType(std::move(sharedextsavedata_factory), ArchiveIdCode::SharedExtSaveData); else LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s", - sharedextsavedata_factory->GetMountPoint().c_str()); + sharedextsavedata_factory->GetMountPoint().c_str()); // Create the SaveDataCheck archive, basically a small variation of the RomFS archive - auto savedatacheck_factory = std::make_unique<FileSys::ArchiveFactory_SaveDataCheck>(nand_directory); + auto savedatacheck_factory = + std::make_unique<FileSys::ArchiveFactory_SaveDataCheck>(nand_directory); RegisterArchiveType(std::move(savedatacheck_factory), ArchiveIdCode::SaveDataCheck); - auto systemsavedata_factory = std::make_unique<FileSys::ArchiveFactory_SystemSaveData>(nand_directory); + auto systemsavedata_factory = + std::make_unique<FileSys::ArchiveFactory_SystemSaveData>(nand_directory); RegisterArchiveType(std::move(systemsavedata_factory), ArchiveIdCode::SystemSaveData); } diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index f7a50a3a7..533be34a4 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -6,9 +6,7 @@ #include <memory> #include <string> - #include "common/common_types.h" - #include "core/file_sys/archive_backend.h" #include "core/hle/kernel/session.h" #include "core/hle/result.h" @@ -28,21 +26,18 @@ namespace FS { /// Supported archive types enum class ArchiveIdCode : u32 { - RomFS = 0x00000003, - SaveData = 0x00000004, - ExtSaveData = 0x00000006, - SharedExtSaveData = 0x00000007, - SystemSaveData = 0x00000008, - SDMC = 0x00000009, - SDMCWriteOnly = 0x0000000A, - SaveDataCheck = 0x2345678A, + RomFS = 0x00000003, + SaveData = 0x00000004, + ExtSaveData = 0x00000006, + SharedExtSaveData = 0x00000007, + SystemSaveData = 0x00000008, + SDMC = 0x00000009, + SDMCWriteOnly = 0x0000000A, + SaveDataCheck = 0x2345678A, }; /// Media types for the archives -enum class MediaType : u32 { - NAND = 0, - SDMC = 1 -}; +enum class MediaType : u32 { NAND = 0, SDMC = 1 }; typedef u64 ArchiveHandle; @@ -51,11 +46,13 @@ public: File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path); ~File(); - std::string GetName() const override { return "Path: " + path.DebugStr(); } + std::string GetName() const override { + return "Path: " + path.DebugStr(); + } ResultVal<bool> SyncRequest() override; FileSys::Path path; ///< Path of the file - u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means + u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface }; @@ -64,10 +61,12 @@ public: Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path); ~Directory(); - std::string GetName() const override { return "Directory: " + path.DebugStr(); } + std::string GetName() const override { + return "Directory: " + path.DebugStr(); + } ResultVal<bool> SyncRequest() override; - FileSys::Path path; ///< Path of the directory + FileSys::Path path; ///< Path of the directory std::unique_ptr<FileSys::DirectoryBackend> backend; ///< File backend interface }; @@ -90,7 +89,8 @@ ResultCode CloseArchive(ArchiveHandle handle); * @param factory File system backend interface to the archive * @param id_code Id code used to access this type of archive */ -ResultCode RegisterArchiveType(std::unique_ptr<FileSys::ArchiveFactory>&& factory, ArchiveIdCode id_code); +ResultCode RegisterArchiveType(std::unique_ptr<FileSys::ArchiveFactory>&& factory, + ArchiveIdCode id_code); /** * Open a File from an Archive @@ -100,7 +100,8 @@ ResultCode RegisterArchiveType(std::unique_ptr<FileSys::ArchiveFactory>&& factor * @return The opened File object as a Session */ ResultVal<Kernel::SharedPtr<File>> OpenFileFromArchive(ArchiveHandle archive_handle, - const FileSys::Path& path, const FileSys::Mode mode); + const FileSys::Path& path, + const FileSys::Mode mode); /** * Delete a File from an Archive @@ -118,8 +119,10 @@ ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Pa * @param dest_path Path to the File inside of the destination Archive * @return Whether rename succeeded */ -ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, - ArchiveHandle dest_archive_handle, const FileSys::Path& dest_path); +ResultCode RenameFileBetweenArchives(ArchiveHandle src_archive_handle, + const FileSys::Path& src_path, + ArchiveHandle dest_archive_handle, + const FileSys::Path& dest_path); /** * Delete a Directory from an Archive @@ -136,7 +139,8 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy * @param file_size The size of the new file, filled with zeroes * @return File creation result code */ -ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u64 file_size); +ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, + u64 file_size); /** * Create a Directory from an Archive @@ -154,8 +158,10 @@ ResultCode CreateDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy * @param dest_path Path to the Directory inside of the destination Archive * @return Whether rename succeeded */ -ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, const FileSys::Path& src_path, - ArchiveHandle dest_archive_handle, const FileSys::Path& dest_path); +ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, + const FileSys::Path& src_path, + ArchiveHandle dest_archive_handle, + const FileSys::Path& dest_path); /** * Open a Directory from an Archive @@ -164,7 +170,7 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, cons * @return The opened Directory object as a Session */ ResultVal<Kernel::SharedPtr<Directory>> OpenDirectoryFromArchive(ArchiveHandle archive_handle, - const FileSys::Path& path); + const FileSys::Path& path); /** * Get the free space in an Archive @@ -181,7 +187,8 @@ ResultVal<u64> GetFreeBytesInArchive(ArchiveHandle archive_handle); * @param path The path to the archive, if relevant. * @return ResultCode 0 on success or the corresponding code on error */ -ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo& format_info, const FileSys::Path& path = FileSys::Path()); +ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo& format_info, + const FileSys::Path& path = FileSys::Path()); /** * Retrieves the format info about the archive of the specified type and path. @@ -190,7 +197,8 @@ ResultCode FormatArchive(ArchiveIdCode id_code, const FileSys::ArchiveFormatInfo * @param archive_path The path of the archive, if relevant * @return The format info of the archive, or the corresponding error code if failed. */ -ResultVal<FileSys::ArchiveFormatInfo> GetArchiveFormatInfo(ArchiveIdCode id_code, FileSys::Path& archive_path); +ResultVal<FileSys::ArchiveFormatInfo> GetArchiveFormatInfo(ArchiveIdCode id_code, + FileSys::Path& archive_path); /** * Creates a blank SharedExtSaveData archive for the specified extdata ID @@ -202,7 +210,8 @@ ResultVal<FileSys::ArchiveFormatInfo> GetArchiveFormatInfo(ArchiveIdCode id_code * @param format_info Format information about the new archive * @return ResultCode 0 on success or the corresponding code on error */ -ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, VAddr icon_buffer, u32 icon_size, const FileSys::ArchiveFormatInfo& format_info); +ResultCode CreateExtSaveData(MediaType media_type, u32 high, u32 low, VAddr icon_buffer, + u32 icon_size, const FileSys::ArchiveFormatInfo& format_info); /** * Deletes the SharedExtSaveData archive for the specified extdata ID diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index 937868747..94f053dc2 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -8,7 +8,6 @@ #include "common/logging/log.h" #include "common/scope_exit.h" #include "common/string_util.h" - #include "core/hle/result.h" #include "core/hle/service/fs/archive.h" #include "core/hle/service/fs/fs_user.h" @@ -57,14 +56,16 @@ static void OpenFile(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); ArchiveHandle archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]); - auto filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); - u32 filename_size = cmd_buff[5]; - FileSys::Mode mode; mode.hex = cmd_buff[6]; - u32 attributes = cmd_buff[7]; // TODO(Link Mauve): do something with those attributes. - u32 filename_ptr = cmd_buff[9]; + auto filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); + u32 filename_size = cmd_buff[5]; + FileSys::Mode mode; + mode.hex = cmd_buff[6]; + u32 attributes = cmd_buff[7]; // TODO(Link Mauve): do something with those attributes. + u32 filename_ptr = cmd_buff[9]; FileSys::Path file_path(filename_type, filename_size, filename_ptr); - LOG_DEBUG(Service_FS, "path=%s, mode=%d attrs=%u", file_path.DebugStr().c_str(), mode.hex, attributes); + LOG_DEBUG(Service_FS, "path=%s, mode=%d attrs=%u", file_path.DebugStr().c_str(), mode.hex, + attributes); ResultVal<SharedPtr<File>> file_res = OpenFileFromArchive(archive_handle, file_path, mode); cmd_buff[1] = file_res.Code().raw; @@ -98,24 +99,27 @@ static void OpenFile(Service::Interface* self) { static void OpenFileDirectly(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - auto archive_id = static_cast<FS::ArchiveIdCode>(cmd_buff[2]); + auto archive_id = static_cast<FS::ArchiveIdCode>(cmd_buff[2]); auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[3]); - u32 archivename_size = cmd_buff[4]; - auto filename_type = static_cast<FileSys::LowPathType>(cmd_buff[5]); - u32 filename_size = cmd_buff[6]; - FileSys::Mode mode; mode.hex = cmd_buff[7]; - u32 attributes = cmd_buff[8]; // TODO(Link Mauve): do something with those attributes. - u32 archivename_ptr = cmd_buff[10]; - u32 filename_ptr = cmd_buff[12]; + u32 archivename_size = cmd_buff[4]; + auto filename_type = static_cast<FileSys::LowPathType>(cmd_buff[5]); + u32 filename_size = cmd_buff[6]; + FileSys::Mode mode; + mode.hex = cmd_buff[7]; + u32 attributes = cmd_buff[8]; // TODO(Link Mauve): do something with those attributes. + u32 archivename_ptr = cmd_buff[10]; + u32 filename_ptr = cmd_buff[12]; FileSys::Path archive_path(archivename_type, archivename_size, archivename_ptr); FileSys::Path file_path(filename_type, filename_size, filename_ptr); LOG_DEBUG(Service_FS, "archive_id=0x%08X archive_path=%s file_path=%s, mode=%u attributes=%d", - archive_id, archive_path.DebugStr().c_str(), file_path.DebugStr().c_str(), mode.hex, attributes); + archive_id, archive_path.DebugStr().c_str(), file_path.DebugStr().c_str(), mode.hex, + attributes); ResultVal<ArchiveHandle> archive_handle = OpenArchive(archive_id, archive_path); if (archive_handle.Failed()) { - LOG_ERROR(Service_FS, "failed to get a handle for archive archive_id=0x%08X archive_path=%s", + LOG_ERROR(Service_FS, + "failed to get a handle for archive archive_id=0x%08X archive_path=%s", archive_id, archive_path.DebugStr().c_str()); cmd_buff[1] = archive_handle.Code().raw; cmd_buff[3] = 0; @@ -149,14 +153,14 @@ static void DeleteFile(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); ArchiveHandle archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]); - auto filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); - u32 filename_size = cmd_buff[5]; - u32 filename_ptr = cmd_buff[7]; + auto filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); + u32 filename_size = cmd_buff[5]; + u32 filename_ptr = cmd_buff[7]; FileSys::Path file_path(filename_type, filename_size, filename_ptr); - LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", - filename_type, filename_size, file_path.DebugStr().c_str()); + LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", filename_type, filename_size, + file_path.DebugStr().c_str()); cmd_buff[1] = DeleteFileFromArchive(archive_handle, file_path).raw; } @@ -181,22 +185,26 @@ static void RenameFile(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); ArchiveHandle src_archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]); - auto src_filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); - u32 src_filename_size = cmd_buff[5]; - ArchiveHandle dest_archive_handle = MakeArchiveHandle(cmd_buff[6], cmd_buff[7]);; - auto dest_filename_type = static_cast<FileSys::LowPathType>(cmd_buff[8]); - u32 dest_filename_size = cmd_buff[9]; - u32 src_filename_ptr = cmd_buff[11]; - u32 dest_filename_ptr = cmd_buff[13]; + auto src_filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); + u32 src_filename_size = cmd_buff[5]; + ArchiveHandle dest_archive_handle = MakeArchiveHandle(cmd_buff[6], cmd_buff[7]); + ; + auto dest_filename_type = static_cast<FileSys::LowPathType>(cmd_buff[8]); + u32 dest_filename_size = cmd_buff[9]; + u32 src_filename_ptr = cmd_buff[11]; + u32 dest_filename_ptr = cmd_buff[13]; FileSys::Path src_file_path(src_filename_type, src_filename_size, src_filename_ptr); FileSys::Path dest_file_path(dest_filename_type, dest_filename_size, dest_filename_ptr); - LOG_DEBUG(Service_FS, "src_type=%d src_size=%d src_data=%s dest_type=%d dest_size=%d dest_data=%s", + LOG_DEBUG(Service_FS, + "src_type=%d src_size=%d src_data=%s dest_type=%d dest_size=%d dest_data=%s", src_filename_type, src_filename_size, src_file_path.DebugStr().c_str(), dest_filename_type, dest_filename_size, dest_file_path.DebugStr().c_str()); - cmd_buff[1] = RenameFileBetweenArchives(src_archive_handle, src_file_path, dest_archive_handle, dest_file_path).raw; + cmd_buff[1] = RenameFileBetweenArchives(src_archive_handle, src_file_path, dest_archive_handle, + dest_file_path) + .raw; } /* @@ -214,14 +222,14 @@ static void DeleteDirectory(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); ArchiveHandle archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]); - auto dirname_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); - u32 dirname_size = cmd_buff[5]; - u32 dirname_ptr = cmd_buff[7]; + auto dirname_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); + u32 dirname_size = cmd_buff[5]; + u32 dirname_ptr = cmd_buff[7]; FileSys::Path dir_path(dirname_type, dirname_size, dirname_ptr); - LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", - dirname_type, dirname_size, dir_path.DebugStr().c_str()); + LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", dirname_type, dirname_size, + dir_path.DebugStr().c_str()); cmd_buff[1] = DeleteDirectoryFromArchive(archive_handle, dir_path).raw; } @@ -243,14 +251,15 @@ static void CreateFile(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); ArchiveHandle archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]); - auto filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); - u32 filename_size = cmd_buff[5]; - u64 file_size = ((u64)cmd_buff[8] << 32) | cmd_buff[7]; - u32 filename_ptr = cmd_buff[10]; + auto filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); + u32 filename_size = cmd_buff[5]; + u64 file_size = ((u64)cmd_buff[8] << 32) | cmd_buff[7]; + u32 filename_ptr = cmd_buff[10]; FileSys::Path file_path(filename_type, filename_size, filename_ptr); - LOG_DEBUG(Service_FS, "type=%d size=%llu data=%s", filename_type, file_size, file_path.DebugStr().c_str()); + LOG_DEBUG(Service_FS, "type=%d size=%llu data=%s", filename_type, file_size, + file_path.DebugStr().c_str()); cmd_buff[1] = CreateFileInArchive(archive_handle, file_path, file_size).raw; } @@ -276,7 +285,8 @@ static void CreateDirectory(Service::Interface* self) { FileSys::Path dir_path(dirname_type, dirname_size, dirname_ptr); - LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_path.DebugStr().c_str()); + LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", dirname_type, dirname_size, + dir_path.DebugStr().c_str()); cmd_buff[1] = CreateDirectoryFromArchive(archive_handle, dir_path).raw; } @@ -301,22 +311,25 @@ static void RenameDirectory(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); ArchiveHandle src_archive_handle = MakeArchiveHandle(cmd_buff[2], cmd_buff[3]); - auto src_dirname_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); - u32 src_dirname_size = cmd_buff[5]; + auto src_dirname_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); + u32 src_dirname_size = cmd_buff[5]; ArchiveHandle dest_archive_handle = MakeArchiveHandle(cmd_buff[6], cmd_buff[7]); - auto dest_dirname_type = static_cast<FileSys::LowPathType>(cmd_buff[8]); - u32 dest_dirname_size = cmd_buff[9]; - u32 src_dirname_ptr = cmd_buff[11]; - u32 dest_dirname_ptr = cmd_buff[13]; + auto dest_dirname_type = static_cast<FileSys::LowPathType>(cmd_buff[8]); + u32 dest_dirname_size = cmd_buff[9]; + u32 src_dirname_ptr = cmd_buff[11]; + u32 dest_dirname_ptr = cmd_buff[13]; FileSys::Path src_dir_path(src_dirname_type, src_dirname_size, src_dirname_ptr); FileSys::Path dest_dir_path(dest_dirname_type, dest_dirname_size, dest_dirname_ptr); - LOG_DEBUG(Service_FS, "src_type=%d src_size=%d src_data=%s dest_type=%d dest_size=%d dest_data=%s", + LOG_DEBUG(Service_FS, + "src_type=%d src_size=%d src_data=%s dest_type=%d dest_size=%d dest_data=%s", src_dirname_type, src_dirname_size, src_dir_path.DebugStr().c_str(), dest_dirname_type, dest_dirname_size, dest_dir_path.DebugStr().c_str()); - cmd_buff[1] = RenameDirectoryBetweenArchives(src_archive_handle, src_dir_path, dest_archive_handle, dest_dir_path).raw; + cmd_buff[1] = RenameDirectoryBetweenArchives(src_archive_handle, src_dir_path, + dest_archive_handle, dest_dir_path) + .raw; } /** @@ -342,7 +355,8 @@ static void OpenDirectory(Service::Interface* self) { FileSys::Path dir_path(dirname_type, dirname_size, dirname_ptr); - LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_path.DebugStr().c_str()); + LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", dirname_type, dirname_size, + dir_path.DebugStr().c_str()); ResultVal<SharedPtr<Directory>> dir_res = OpenDirectoryFromArchive(archive_handle, dir_path); cmd_buff[1] = dir_res.Code().raw; @@ -370,13 +384,14 @@ static void OpenDirectory(Service::Interface* self) { static void OpenArchive(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - auto archive_id = static_cast<FS::ArchiveIdCode>(cmd_buff[1]); + auto archive_id = static_cast<FS::ArchiveIdCode>(cmd_buff[1]); auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[2]); - u32 archivename_size = cmd_buff[3]; - u32 archivename_ptr = cmd_buff[5]; + u32 archivename_size = cmd_buff[3]; + u32 archivename_ptr = cmd_buff[5]; FileSys::Path archive_path(archivename_type, archivename_size, archivename_ptr); - LOG_DEBUG(Service_FS, "archive_id=0x%08X archive_path=%s", archive_id, archive_path.DebugStr().c_str()); + LOG_DEBUG(Service_FS, "archive_id=0x%08X archive_path=%s", archive_id, + archive_path.DebugStr().c_str()); ResultVal<ArchiveHandle> handle = OpenArchive(archive_id, archive_path); cmd_buff[1] = handle.Code().raw; @@ -385,7 +400,8 @@ static void OpenArchive(Service::Interface* self) { cmd_buff[3] = (*handle >> 32) & 0xFFFFFFFF; } else { cmd_buff[2] = cmd_buff[3] = 0; - LOG_ERROR(Service_FS, "failed to get a handle for archive archive_id=0x%08X archive_path=%s", + LOG_ERROR(Service_FS, + "failed to get a handle for archive archive_id=0x%08X archive_path=%s", archive_id, archive_path.DebugStr().c_str()); } } @@ -471,7 +487,8 @@ static void FormatSaveData(Service::Interface* self) { if (archive_id != FS::ArchiveIdCode::SaveData) { LOG_ERROR(Service_FS, "tried to format an archive different than SaveData, %u", archive_id); cmd_buff[1] = ResultCode(ErrorDescription::FS_InvalidPath, ErrorModule::FS, - ErrorSummary::InvalidArgument, ErrorLevel::Usage).raw; + ErrorSummary::InvalidArgument, ErrorLevel::Usage) + .raw; return; } @@ -571,18 +588,21 @@ static void CreateExtSaveData(Service::Interface* self) { u32 icon_size = cmd_buff[9]; VAddr icon_buffer = cmd_buff[11]; - LOG_WARNING(Service_FS, "(STUBBED) savedata_high=%08X savedata_low=%08X cmd_buff[3]=%08X " - "cmd_buff[4]=%08X cmd_buff[5]=%08X cmd_buff[6]=%08X cmd_buff[7]=%08X cmd_buff[8]=%08X " - "icon_size=%08X icon_descriptor=%08X icon_buffer=%08X", save_high, save_low, - cmd_buff[3], cmd_buff[4], cmd_buff[5], cmd_buff[6], cmd_buff[7], cmd_buff[8], icon_size, - cmd_buff[10], icon_buffer); + LOG_WARNING( + Service_FS, + "(STUBBED) savedata_high=%08X savedata_low=%08X cmd_buff[3]=%08X " + "cmd_buff[4]=%08X cmd_buff[5]=%08X cmd_buff[6]=%08X cmd_buff[7]=%08X cmd_buff[8]=%08X " + "icon_size=%08X icon_descriptor=%08X icon_buffer=%08X", + save_high, save_low, cmd_buff[3], cmd_buff[4], cmd_buff[5], cmd_buff[6], cmd_buff[7], + cmd_buff[8], icon_size, cmd_buff[10], icon_buffer); FileSys::ArchiveFormatInfo format_info; format_info.number_directories = cmd_buff[5]; format_info.number_files = cmd_buff[6]; format_info.duplicate_data = false; format_info.total_size = 0; - cmd_buff[1] = CreateExtSaveData(media_type, save_high, save_low, icon_buffer, icon_size, format_info).raw; + cmd_buff[1] = + CreateExtSaveData(media_type, save_high, save_low, icon_buffer, icon_size, format_info).raw; } /** @@ -604,7 +624,7 @@ static void DeleteExtSaveData(Service::Interface* self) { u32 unknown = cmd_buff[4]; // TODO(Subv): Figure out what this is LOG_WARNING(Service_FS, "(STUBBED) save_low=%08X save_high=%08X media_type=%08X unknown=%08X", - save_low, save_high, cmd_buff[1] & 0xFF, unknown); + save_low, save_high, cmd_buff[1] & 0xFF, unknown); cmd_buff[1] = DeleteExtSaveData(media_type, save_high, save_low).raw; } @@ -662,10 +682,13 @@ static void CreateSystemSaveData(Service::Interface* self) { u32 savedata_high = cmd_buff[1]; u32 savedata_low = cmd_buff[2]; - LOG_WARNING(Service_FS, "(STUBBED) savedata_high=%08X savedata_low=%08X cmd_buff[3]=%08X " - "cmd_buff[4]=%08X cmd_buff[5]=%08X cmd_buff[6]=%08X cmd_buff[7]=%08X cmd_buff[8]=%08X " - "cmd_buff[9]=%08X", savedata_high, savedata_low, cmd_buff[3], cmd_buff[4], cmd_buff[5], - cmd_buff[6], cmd_buff[7], cmd_buff[8], cmd_buff[9]); + LOG_WARNING( + Service_FS, + "(STUBBED) savedata_high=%08X savedata_low=%08X cmd_buff[3]=%08X " + "cmd_buff[4]=%08X cmd_buff[5]=%08X cmd_buff[6]=%08X cmd_buff[7]=%08X cmd_buff[8]=%08X " + "cmd_buff[9]=%08X", + savedata_high, savedata_low, cmd_buff[3], cmd_buff[4], cmd_buff[5], cmd_buff[6], + cmd_buff[7], cmd_buff[8], cmd_buff[9]); cmd_buff[1] = CreateSystemSaveData(savedata_high, savedata_low).raw; } @@ -692,10 +715,13 @@ static void CreateLegacySystemSaveData(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 savedata_id = cmd_buff[1]; - LOG_WARNING(Service_FS, "(STUBBED) savedata_id=%08X cmd_buff[3]=%08X " - "cmd_buff[4]=%08X cmd_buff[5]=%08X cmd_buff[6]=%08X cmd_buff[7]=%08X cmd_buff[8]=%08X " - "cmd_buff[9]=%08X", savedata_id, cmd_buff[3], cmd_buff[4], cmd_buff[5], - cmd_buff[6], cmd_buff[7], cmd_buff[8], cmd_buff[9]); + LOG_WARNING( + Service_FS, + "(STUBBED) savedata_id=%08X cmd_buff[3]=%08X " + "cmd_buff[4]=%08X cmd_buff[5]=%08X cmd_buff[6]=%08X cmd_buff[7]=%08X cmd_buff[8]=%08X " + "cmd_buff[9]=%08X", + savedata_id, cmd_buff[3], cmd_buff[4], cmd_buff[5], cmd_buff[6], cmd_buff[7], cmd_buff[8], + cmd_buff[9]); cmd_buff[0] = IPC::MakeHeader(0x810, 0x1, 0); // With this command, the SystemSaveData always has save_high = 0 (Always created in the NAND) @@ -721,8 +747,8 @@ static void InitializeWithSdkVersion(Service::Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; - LOG_WARNING(Service_FS, "(STUBBED) called unk1=0x%08X, unk2=0x%08X, unk3=0x%08X", - unk1, unk2, unk3); + LOG_WARNING(Service_FS, "(STUBBED) called unk1=0x%08X, unk2=0x%08X, unk3=0x%08X", unk1, unk2, + unk3); } /** @@ -834,114 +860,114 @@ static void GetFormatInfo(Service::Interface* self) { } const Interface::FunctionInfo FunctionTable[] = { - {0x000100C6, nullptr, "Dummy1"}, - {0x040100C4, nullptr, "Control"}, - {0x08010002, Initialize, "Initialize"}, - {0x080201C2, OpenFile, "OpenFile"}, - {0x08030204, OpenFileDirectly, "OpenFileDirectly"}, - {0x08040142, DeleteFile, "DeleteFile"}, - {0x08050244, RenameFile, "RenameFile"}, - {0x08060142, DeleteDirectory, "DeleteDirectory"}, - {0x08070142, nullptr, "DeleteDirectoryRecursively"}, - {0x08080202, CreateFile, "CreateFile"}, - {0x08090182, CreateDirectory, "CreateDirectory"}, - {0x080A0244, RenameDirectory, "RenameDirectory"}, - {0x080B0102, OpenDirectory, "OpenDirectory"}, - {0x080C00C2, OpenArchive, "OpenArchive"}, - {0x080D0144, nullptr, "ControlArchive"}, - {0x080E0080, CloseArchive, "CloseArchive"}, - {0x080F0180, FormatThisUserSaveData, "FormatThisUserSaveData"}, + {0x000100C6, nullptr, "Dummy1"}, + {0x040100C4, nullptr, "Control"}, + {0x08010002, Initialize, "Initialize"}, + {0x080201C2, OpenFile, "OpenFile"}, + {0x08030204, OpenFileDirectly, "OpenFileDirectly"}, + {0x08040142, DeleteFile, "DeleteFile"}, + {0x08050244, RenameFile, "RenameFile"}, + {0x08060142, DeleteDirectory, "DeleteDirectory"}, + {0x08070142, nullptr, "DeleteDirectoryRecursively"}, + {0x08080202, CreateFile, "CreateFile"}, + {0x08090182, CreateDirectory, "CreateDirectory"}, + {0x080A0244, RenameDirectory, "RenameDirectory"}, + {0x080B0102, OpenDirectory, "OpenDirectory"}, + {0x080C00C2, OpenArchive, "OpenArchive"}, + {0x080D0144, nullptr, "ControlArchive"}, + {0x080E0080, CloseArchive, "CloseArchive"}, + {0x080F0180, FormatThisUserSaveData, "FormatThisUserSaveData"}, {0x08100200, CreateLegacySystemSaveData, "CreateLegacySystemSaveData"}, - {0x08110040, nullptr, "DeleteSystemSaveData"}, - {0x08120080, GetFreeBytes, "GetFreeBytes"}, - {0x08130000, nullptr, "GetCardType"}, - {0x08140000, nullptr, "GetSdmcArchiveResource"}, - {0x08150000, nullptr, "GetNandArchiveResource"}, - {0x08160000, nullptr, "GetSdmcFatfsError"}, - {0x08170000, IsSdmcDetected, "IsSdmcDetected"}, - {0x08180000, IsSdmcWriteable, "IsSdmcWritable"}, - {0x08190042, nullptr, "GetSdmcCid"}, - {0x081A0042, nullptr, "GetNandCid"}, - {0x081B0000, nullptr, "GetSdmcSpeedInfo"}, - {0x081C0000, nullptr, "GetNandSpeedInfo"}, - {0x081D0042, nullptr, "GetSdmcLog"}, - {0x081E0042, nullptr, "GetNandLog"}, - {0x081F0000, nullptr, "ClearSdmcLog"}, - {0x08200000, nullptr, "ClearNandLog"}, - {0x08210000, CardSlotIsInserted, "CardSlotIsInserted"}, - {0x08220000, nullptr, "CardSlotPowerOn"}, - {0x08230000, nullptr, "CardSlotPowerOff"}, - {0x08240000, nullptr, "CardSlotGetCardIFPowerStatus"}, - {0x08250040, nullptr, "CardNorDirectCommand"}, - {0x08260080, nullptr, "CardNorDirectCommandWithAddress"}, - {0x08270082, nullptr, "CardNorDirectRead"}, - {0x082800C2, nullptr, "CardNorDirectReadWithAddress"}, - {0x08290082, nullptr, "CardNorDirectWrite"}, - {0x082A00C2, nullptr, "CardNorDirectWriteWithAddress"}, - {0x082B00C2, nullptr, "CardNorDirectRead_4xIO"}, - {0x082C0082, nullptr, "CardNorDirectCpuWriteWithoutVerify"}, - {0x082D0040, nullptr, "CardNorDirectSectorEraseWithoutVerify"}, - {0x082E0040, nullptr, "GetProductInfo"}, - {0x082F0040, nullptr, "GetProgramLaunchInfo"}, - {0x08300182, nullptr, "CreateExtSaveData"}, - {0x08310180, nullptr, "CreateSharedExtSaveData"}, - {0x08320102, nullptr, "ReadExtSaveDataIcon"}, - {0x08330082, nullptr, "EnumerateExtSaveData"}, - {0x08340082, nullptr, "EnumerateSharedExtSaveData"}, - {0x08350080, nullptr, "DeleteExtSaveData"}, - {0x08360080, nullptr, "DeleteSharedExtSaveData"}, - {0x08370040, nullptr, "SetCardSpiBaudRate"}, - {0x08380040, nullptr, "SetCardSpiBusMode"}, - {0x08390000, nullptr, "SendInitializeInfoTo9"}, - {0x083A0100, nullptr, "GetSpecialContentIndex"}, - {0x083B00C2, nullptr, "GetLegacyRomHeader"}, - {0x083C00C2, nullptr, "GetLegacyBannerData"}, - {0x083D0100, nullptr, "CheckAuthorityToAccessExtSaveData"}, - {0x083E00C2, nullptr, "QueryTotalQuotaSize"}, - {0x083F00C0, nullptr, "GetExtDataBlockSize"}, - {0x08400040, nullptr, "AbnegateAccessRight"}, - {0x08410000, nullptr, "DeleteSdmcRoot"}, - {0x08420040, nullptr, "DeleteAllExtSaveDataOnNand"}, - {0x08430000, nullptr, "InitializeCtrFileSystem"}, - {0x08440000, nullptr, "CreateSeed"}, - {0x084500C2, GetFormatInfo, "GetFormatInfo"}, - {0x08460102, nullptr, "GetLegacyRomHeader2"}, - {0x08470180, nullptr, "FormatCtrCardUserSaveData"}, - {0x08480042, nullptr, "GetSdmcCtrRootPath"}, - {0x08490040, GetArchiveResource, "GetArchiveResource"}, - {0x084A0002, nullptr, "ExportIntegrityVerificationSeed"}, - {0x084B0002, nullptr, "ImportIntegrityVerificationSeed"}, - {0x084C0242, FormatSaveData, "FormatSaveData"}, - {0x084D0102, nullptr, "GetLegacySubBannerData"}, - {0x084E0342, nullptr, "UpdateSha256Context"}, - {0x084F0102, nullptr, "ReadSpecialFile"}, - {0x08500040, nullptr, "GetSpecialFileSize"}, - {0x08510242, CreateExtSaveData, "CreateExtSaveData"}, - {0x08520100, DeleteExtSaveData, "DeleteExtSaveData"}, - {0x08530142, nullptr, "ReadExtSaveDataIcon"}, - {0x085400C0, nullptr, "GetExtDataBlockSize"}, - {0x08550102, nullptr, "EnumerateExtSaveData"}, - {0x08560240, CreateSystemSaveData, "CreateSystemSaveData"}, - {0x08570080, DeleteSystemSaveData, "DeleteSystemSaveData"}, - {0x08580000, nullptr, "StartDeviceMoveAsSource"}, - {0x08590200, nullptr, "StartDeviceMoveAsDestination"}, - {0x085A00C0, nullptr, "SetArchivePriority"}, - {0x085B0080, nullptr, "GetArchivePriority"}, - {0x085C00C0, nullptr, "SetCtrCardLatencyParameter"}, - {0x085D01C0, nullptr, "SetFsCompatibilityInfo"}, - {0x085E0040, nullptr, "ResetCardCompatibilityParameter"}, - {0x085F0040, nullptr, "SwitchCleanupInvalidSaveData"}, - {0x08600042, nullptr, "EnumerateSystemSaveData"}, + {0x08110040, nullptr, "DeleteSystemSaveData"}, + {0x08120080, GetFreeBytes, "GetFreeBytes"}, + {0x08130000, nullptr, "GetCardType"}, + {0x08140000, nullptr, "GetSdmcArchiveResource"}, + {0x08150000, nullptr, "GetNandArchiveResource"}, + {0x08160000, nullptr, "GetSdmcFatfsError"}, + {0x08170000, IsSdmcDetected, "IsSdmcDetected"}, + {0x08180000, IsSdmcWriteable, "IsSdmcWritable"}, + {0x08190042, nullptr, "GetSdmcCid"}, + {0x081A0042, nullptr, "GetNandCid"}, + {0x081B0000, nullptr, "GetSdmcSpeedInfo"}, + {0x081C0000, nullptr, "GetNandSpeedInfo"}, + {0x081D0042, nullptr, "GetSdmcLog"}, + {0x081E0042, nullptr, "GetNandLog"}, + {0x081F0000, nullptr, "ClearSdmcLog"}, + {0x08200000, nullptr, "ClearNandLog"}, + {0x08210000, CardSlotIsInserted, "CardSlotIsInserted"}, + {0x08220000, nullptr, "CardSlotPowerOn"}, + {0x08230000, nullptr, "CardSlotPowerOff"}, + {0x08240000, nullptr, "CardSlotGetCardIFPowerStatus"}, + {0x08250040, nullptr, "CardNorDirectCommand"}, + {0x08260080, nullptr, "CardNorDirectCommandWithAddress"}, + {0x08270082, nullptr, "CardNorDirectRead"}, + {0x082800C2, nullptr, "CardNorDirectReadWithAddress"}, + {0x08290082, nullptr, "CardNorDirectWrite"}, + {0x082A00C2, nullptr, "CardNorDirectWriteWithAddress"}, + {0x082B00C2, nullptr, "CardNorDirectRead_4xIO"}, + {0x082C0082, nullptr, "CardNorDirectCpuWriteWithoutVerify"}, + {0x082D0040, nullptr, "CardNorDirectSectorEraseWithoutVerify"}, + {0x082E0040, nullptr, "GetProductInfo"}, + {0x082F0040, nullptr, "GetProgramLaunchInfo"}, + {0x08300182, nullptr, "CreateExtSaveData"}, + {0x08310180, nullptr, "CreateSharedExtSaveData"}, + {0x08320102, nullptr, "ReadExtSaveDataIcon"}, + {0x08330082, nullptr, "EnumerateExtSaveData"}, + {0x08340082, nullptr, "EnumerateSharedExtSaveData"}, + {0x08350080, nullptr, "DeleteExtSaveData"}, + {0x08360080, nullptr, "DeleteSharedExtSaveData"}, + {0x08370040, nullptr, "SetCardSpiBaudRate"}, + {0x08380040, nullptr, "SetCardSpiBusMode"}, + {0x08390000, nullptr, "SendInitializeInfoTo9"}, + {0x083A0100, nullptr, "GetSpecialContentIndex"}, + {0x083B00C2, nullptr, "GetLegacyRomHeader"}, + {0x083C00C2, nullptr, "GetLegacyBannerData"}, + {0x083D0100, nullptr, "CheckAuthorityToAccessExtSaveData"}, + {0x083E00C2, nullptr, "QueryTotalQuotaSize"}, + {0x083F00C0, nullptr, "GetExtDataBlockSize"}, + {0x08400040, nullptr, "AbnegateAccessRight"}, + {0x08410000, nullptr, "DeleteSdmcRoot"}, + {0x08420040, nullptr, "DeleteAllExtSaveDataOnNand"}, + {0x08430000, nullptr, "InitializeCtrFileSystem"}, + {0x08440000, nullptr, "CreateSeed"}, + {0x084500C2, GetFormatInfo, "GetFormatInfo"}, + {0x08460102, nullptr, "GetLegacyRomHeader2"}, + {0x08470180, nullptr, "FormatCtrCardUserSaveData"}, + {0x08480042, nullptr, "GetSdmcCtrRootPath"}, + {0x08490040, GetArchiveResource, "GetArchiveResource"}, + {0x084A0002, nullptr, "ExportIntegrityVerificationSeed"}, + {0x084B0002, nullptr, "ImportIntegrityVerificationSeed"}, + {0x084C0242, FormatSaveData, "FormatSaveData"}, + {0x084D0102, nullptr, "GetLegacySubBannerData"}, + {0x084E0342, nullptr, "UpdateSha256Context"}, + {0x084F0102, nullptr, "ReadSpecialFile"}, + {0x08500040, nullptr, "GetSpecialFileSize"}, + {0x08510242, CreateExtSaveData, "CreateExtSaveData"}, + {0x08520100, DeleteExtSaveData, "DeleteExtSaveData"}, + {0x08530142, nullptr, "ReadExtSaveDataIcon"}, + {0x085400C0, nullptr, "GetExtDataBlockSize"}, + {0x08550102, nullptr, "EnumerateExtSaveData"}, + {0x08560240, CreateSystemSaveData, "CreateSystemSaveData"}, + {0x08570080, DeleteSystemSaveData, "DeleteSystemSaveData"}, + {0x08580000, nullptr, "StartDeviceMoveAsSource"}, + {0x08590200, nullptr, "StartDeviceMoveAsDestination"}, + {0x085A00C0, nullptr, "SetArchivePriority"}, + {0x085B0080, nullptr, "GetArchivePriority"}, + {0x085C00C0, nullptr, "SetCtrCardLatencyParameter"}, + {0x085D01C0, nullptr, "SetFsCompatibilityInfo"}, + {0x085E0040, nullptr, "ResetCardCompatibilityParameter"}, + {0x085F0040, nullptr, "SwitchCleanupInvalidSaveData"}, + {0x08600042, nullptr, "EnumerateSystemSaveData"}, {0x08610042, InitializeWithSdkVersion, "InitializeWithSdkVersion"}, - {0x08620040, SetPriority, "SetPriority"}, - {0x08630000, GetPriority, "GetPriority"}, - {0x08640000, nullptr, "GetNandInfo"}, - {0x08650140, nullptr, "SetSaveDataSecureValue"}, - {0x086600C0, nullptr, "GetSaveDataSecureValue"}, - {0x086700C4, nullptr, "ControlSecureSave"}, - {0x08680000, nullptr, "GetMediaType"}, - {0x08690000, nullptr, "GetNandEraseCount"}, - {0x086A0082, nullptr, "ReadNandReport"} + {0x08620040, SetPriority, "SetPriority"}, + {0x08630000, GetPriority, "GetPriority"}, + {0x08640000, nullptr, "GetNandInfo"}, + {0x08650140, nullptr, "SetSaveDataSecureValue"}, + {0x086600C0, nullptr, "GetSaveDataSecureValue"}, + {0x086700C4, nullptr, "ControlSecureSave"}, + {0x08680000, nullptr, "GetMediaType"}, + {0x08690000, nullptr, "GetNandEraseCount"}, + {0x086A0082, nullptr, "ReadNandReport"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp index ec565f46d..710e0e485 100644 --- a/src/core/hle/service/gsp_gpu.cpp +++ b/src/core/hle/service/gsp_gpu.cpp @@ -4,19 +4,16 @@ #include "common/bit_field.h" #include "common/microprofile.h" - -#include "core/memory.h" #include "core/hle/kernel/event.h" #include "core/hle/kernel/shared_memory.h" #include "core/hle/result.h" -#include "core/hw/hw.h" #include "core/hw/gpu.h" +#include "core/hw/hw.h" #include "core/hw/lcd.h" - -#include "video_core/gpu_debugger.h" -#include "video_core/debug_utils/debug_utils.h" - +#include "core/memory.h" #include "gsp_gpu.h" +#include "video_core/debug_utils/debug_utils.h" +#include "video_core/gpu_debugger.h" // Main graphics debugger object - TODO: Here is probably not the best place for this GraphicsDebugger g_debugger; @@ -29,12 +26,15 @@ const static u32 REGS_BEGIN = 0x1EB00000; namespace GSP_GPU { -const ResultCode ERR_GSP_REGS_OUTOFRANGE_OR_MISALIGNED(ErrorDescription::OutofRangeOrMisalignedAddress, ErrorModule::GX, - ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E02A01 +const ResultCode ERR_GSP_REGS_OUTOFRANGE_OR_MISALIGNED( + ErrorDescription::OutofRangeOrMisalignedAddress, ErrorModule::GX, ErrorSummary::InvalidArgument, + ErrorLevel::Usage); // 0xE0E02A01 const ResultCode ERR_GSP_REGS_MISALIGNED(ErrorDescription::MisalignedSize, ErrorModule::GX, - ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E02BF2 + ErrorSummary::InvalidArgument, + ErrorLevel::Usage); // 0xE0E02BF2 const ResultCode ERR_GSP_REGS_INVALID_SIZE(ErrorDescription::InvalidSize, ErrorModule::GX, - ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E02BEC + ErrorSummary::InvalidArgument, + ErrorLevel::Usage); // 0xE0E02BEC /// Event triggered when GSP interrupt has been signalled Kernel::SharedPtr<Kernel::Event> g_interrupt_event; @@ -73,7 +73,8 @@ static inline InterruptRelayQueue* GetInterruptRelayQueue(u32 thread_id) { * @param data Data to be written */ static void WriteSingleHWReg(u32 base_address, u32 data) { - DEBUG_ASSERT_MSG((base_address & 3) == 0 && base_address < 0x420000, "Write address out of range or misaligned"); + DEBUG_ASSERT_MSG((base_address & 3) == 0 && base_address < 0x420000, + "Write address out of range or misaligned"); HW::Write<u32>(base_address + REGS_BEGIN, data); } @@ -90,7 +91,8 @@ static ResultCode WriteHWRegs(u32 base_address, u32 size_in_bytes, VAddr data_va const u32 max_size_in_bytes = 0x80; if (base_address & 3 || base_address >= 0x420000) { - LOG_ERROR(Service_GSP, "Write address was out of range or misaligned! (address=0x%08x, size=0x%08x)", + LOG_ERROR(Service_GSP, + "Write address was out of range or misaligned! (address=0x%08x, size=0x%08x)", base_address, size_in_bytes); return ERR_GSP_REGS_OUTOFRANGE_OR_MISALIGNED; } else if (size_in_bytes <= max_size_in_bytes) { @@ -124,12 +126,14 @@ static ResultCode WriteHWRegs(u32 base_address, u32 size_in_bytes, VAddr data_va * @param masks A pointer to the masks * @return RESULT_SUCCESS if the parameters are valid, error code otherwise */ -static ResultCode WriteHWRegsWithMask(u32 base_address, u32 size_in_bytes, VAddr data_vaddr, VAddr masks_vaddr) { +static ResultCode WriteHWRegsWithMask(u32 base_address, u32 size_in_bytes, VAddr data_vaddr, + VAddr masks_vaddr) { // This magic number is verified to be done by the gsp module const u32 max_size_in_bytes = 0x80; if (base_address & 3 || base_address >= 0x420000) { - LOG_ERROR(Service_GSP, "Write address was out of range or misaligned! (address=0x%08x, size=0x%08x)", + LOG_ERROR(Service_GSP, + "Write address was out of range or misaligned! (address=0x%08x, size=0x%08x)", base_address, size_in_bytes); return ERR_GSP_REGS_OUTOFRANGE_OR_MISALIGNED; } else if (size_in_bytes <= max_size_in_bytes) { @@ -214,7 +218,8 @@ static void ReadHWRegs(Service::Interface* self) { // TODO: Return proper error codes if (reg_addr + size >= 0x420000) { - LOG_ERROR(Service_GSP, "Read address out of range! (address=0x%08x, size=0x%08x)", reg_addr, size); + LOG_ERROR(Service_GSP, "Read address out of range! (address=0x%08x, size=0x%08x)", reg_addr, + size); return; } @@ -243,22 +248,34 @@ ResultCode SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) { PAddr phys_address_left = Memory::VirtualToPhysicalAddress(info.address_left); PAddr phys_address_right = Memory::VirtualToPhysicalAddress(info.address_right); if (info.active_fb == 0) { - WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left1)), - phys_address_left); - WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right1)), - phys_address_right); + WriteSingleHWReg( + base_address + + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left1)), + phys_address_left); + WriteSingleHWReg( + base_address + + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right1)), + phys_address_right); } else { - WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left2)), - phys_address_left); - WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right2)), - phys_address_right); + WriteSingleHWReg( + base_address + + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_left2)), + phys_address_left); + WriteSingleHWReg( + base_address + + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].address_right2)), + phys_address_right); } - WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].stride)), + WriteSingleHWReg(base_address + + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].stride)), info.stride); - WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].color_format)), - info.format); - WriteSingleHWReg(base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].active_fb)), - info.shown_fb); + WriteSingleHWReg( + base_address + + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].color_format)), + info.format); + WriteSingleHWReg( + base_address + 4 * static_cast<u32>(GPU_REG_INDEX(framebuffer_config[screen_id].active_fb)), + info.shown_fb); if (Pica::g_debug_context) Pica::g_debug_context->OnEvent(Pica::DebugContext::Event::BufferSwapped, nullptr); @@ -305,15 +322,15 @@ static void SetBufferSwap(Service::Interface* self) { static void FlushDataCache(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 address = cmd_buff[1]; - u32 size = cmd_buff[2]; + u32 size = cmd_buff[2]; u32 process = cmd_buff[4]; // TODO(purpasmart96): Verify return header on HW cmd_buff[1] = RESULT_SUCCESS.raw; // No error - LOG_DEBUG(Service_GSP, "(STUBBED) called address=0x%08X, size=0x%08X, process=0x%08X", - address, size, process); + LOG_DEBUG(Service_GSP, "(STUBBED) called address=0x%08X, size=0x%08X, process=0x%08X", address, + size, process); } /** @@ -356,11 +373,12 @@ static void RegisterInterruptRelayQueue(Service::Interface* self) { // This specific code is required for a successful initialization, rather than 0 first_initialization = false; cmd_buff[1] = ResultCode(ErrorDescription::GPU_FirstInitialization, ErrorModule::GX, - ErrorSummary::Success, ErrorLevel::Success).raw; + ErrorSummary::Success, ErrorLevel::Success) + .raw; } else { cmd_buff[1] = RESULT_SUCCESS.raw; } - cmd_buff[2] = g_thread_id++; // Thread ID + cmd_buff[2] = g_thread_id++; // Thread ID cmd_buff[4] = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom(); // GSP shared memory g_interrupt_event->Signal(); // TODO(bunnei): Is this correct? @@ -416,7 +434,8 @@ void SignalInterrupt(InterruptId interrupt_id) { // Update framebuffer information if requested // TODO(yuriks): Confirm where this code should be called. It is definitely updated without // executing any GSP commands, only waiting on the event. - int screen_id = (interrupt_id == InterruptId::PDC0) ? 0 : (interrupt_id == InterruptId::PDC1) ? 1 : -1; + int screen_id = + (interrupt_id == InterruptId::PDC0) ? 0 : (interrupt_id == InterruptId::PDC1) ? 1 : -1; if (screen_id != -1) { FrameBufferUpdate* info = GetFrameBufferInfo(thread_id, screen_id); if (info->is_dirty) { @@ -440,25 +459,27 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { switch (command.id) { // GX request DMA - typically used for copying memory from GSP heap to VRAM - case CommandId::REQUEST_DMA: - { + case CommandId::REQUEST_DMA: { MICROPROFILE_SCOPE(GPU_GSP_DMA); - // TODO: Consider attempting rasterizer-accelerated surface blit if that usage is ever possible/likely - Memory::RasterizerFlushRegion(Memory::VirtualToPhysicalAddress(command.dma_request.source_address), - command.dma_request.size); - Memory::RasterizerFlushAndInvalidateRegion(Memory::VirtualToPhysicalAddress(command.dma_request.dest_address), - command.dma_request.size); + // TODO: Consider attempting rasterizer-accelerated surface blit if that usage is ever + // possible/likely + Memory::RasterizerFlushRegion( + Memory::VirtualToPhysicalAddress(command.dma_request.source_address), + command.dma_request.size); + Memory::RasterizerFlushAndInvalidateRegion( + Memory::VirtualToPhysicalAddress(command.dma_request.dest_address), + command.dma_request.size); // TODO(Subv): These memory accesses should not go through the application's memory mapping. // They should go through the GSP module's memory mapping. - Memory::CopyBlock(command.dma_request.dest_address, command.dma_request.source_address, command.dma_request.size); + Memory::CopyBlock(command.dma_request.dest_address, command.dma_request.source_address, + command.dma_request.size); SignalInterrupt(InterruptId::DMA); break; } // TODO: This will need some rework in the future. (why?) - case CommandId::SUBMIT_GPU_CMDLIST: - { + case CommandId::SUBMIT_GPU_CMDLIST: { auto& params = command.submit_gpu_cmdlist; if (params.do_flush) { @@ -468,10 +489,12 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { } WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.address)), - Memory::VirtualToPhysicalAddress(params.address) >> 3); - WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.size)), params.size); + Memory::VirtualToPhysicalAddress(params.address) >> 3); + WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.size)), + params.size); - // TODO: Not sure if we are supposed to always write this .. seems to trigger processing though + // TODO: Not sure if we are supposed to always write this .. seems to trigger processing + // though WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(command_processor_config.trigger)), 1); // TODO(yuriks): Figure out the meaning of the `flags` field. @@ -481,67 +504,70 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { // It's assumed that the two "blocks" behave equivalently. // Presumably this is done simply to allow two memory fills to run in parallel. - case CommandId::SET_MEMORY_FILL: - { + case CommandId::SET_MEMORY_FILL: { auto& params = command.memory_fill; if (params.start1 != 0) { WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].address_start)), - Memory::VirtualToPhysicalAddress(params.start1) >> 3); + Memory::VirtualToPhysicalAddress(params.start1) >> 3); WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].address_end)), - Memory::VirtualToPhysicalAddress(params.end1) >> 3); - WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].value_32bit)), params.value1); - WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].control)), params.control1); + Memory::VirtualToPhysicalAddress(params.end1) >> 3); + WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].value_32bit)), + params.value1); + WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[0].control)), + params.control1); } if (params.start2 != 0) { WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].address_start)), - Memory::VirtualToPhysicalAddress(params.start2) >> 3); + Memory::VirtualToPhysicalAddress(params.start2) >> 3); WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].address_end)), - Memory::VirtualToPhysicalAddress(params.end2) >> 3); - WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].value_32bit)), params.value2); - WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].control)), params.control2); + Memory::VirtualToPhysicalAddress(params.end2) >> 3); + WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].value_32bit)), + params.value2); + WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(memory_fill_config[1].control)), + params.control2); } break; } - case CommandId::SET_DISPLAY_TRANSFER: - { + case CommandId::SET_DISPLAY_TRANSFER: { auto& params = command.display_transfer; WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.input_address)), - Memory::VirtualToPhysicalAddress(params.in_buffer_address) >> 3); + Memory::VirtualToPhysicalAddress(params.in_buffer_address) >> 3); WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.output_address)), - Memory::VirtualToPhysicalAddress(params.out_buffer_address) >> 3); - WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.input_size)), params.in_buffer_size); - WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.output_size)), params.out_buffer_size); - WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.flags)), params.flags); + Memory::VirtualToPhysicalAddress(params.out_buffer_address) >> 3); + WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.input_size)), + params.in_buffer_size); + WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.output_size)), + params.out_buffer_size); + WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.flags)), + params.flags); WriteGPURegister(static_cast<u32>(GPU_REG_INDEX(display_transfer_config.trigger)), 1); break; } - case CommandId::SET_TEXTURE_COPY: - { + case CommandId::SET_TEXTURE_COPY: { auto& params = command.texture_copy; WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.input_address), - Memory::VirtualToPhysicalAddress(params.in_buffer_address) >> 3); + Memory::VirtualToPhysicalAddress(params.in_buffer_address) >> 3); WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.output_address), - Memory::VirtualToPhysicalAddress(params.out_buffer_address) >> 3); + Memory::VirtualToPhysicalAddress(params.out_buffer_address) >> 3); WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.texture_copy.size), - params.size); + params.size); WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.texture_copy.input_size), - params.in_width_gap); + params.in_width_gap); WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.texture_copy.output_size), - params.out_width_gap); - WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.flags), - params.flags); + params.out_width_gap); + WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.flags), params.flags); - // NOTE: Actual GSP ORs 1 with current register instead of overwriting. Doesn't seem to matter. + // NOTE: Actual GSP ORs 1 with current register instead of overwriting. Doesn't seem to + // matter. WriteGPURegister((u32)GPU_REG_INDEX(display_transfer_config.trigger), 1); break; } - case CommandId::CACHE_FLUSH: - { + case CommandId::CACHE_FLUSH: { // NOTE: Rasterizer flushing handled elsewhere in CPU read/write and other GPU handlers // Use command.cache_flush.regions to implement this handler break; @@ -552,7 +578,8 @@ static void ExecuteCommand(const Command& command, u32 thread_id) { } if (Pica::g_debug_context) - Pica::g_debug_context->OnEvent(Pica::DebugContext::Event::GSPCommandProcessed, (void*)&command); + Pica::g_debug_context->OnEvent(Pica::DebugContext::Event::GSPCommandProcessed, + (void*)&command); } /** @@ -575,7 +602,7 @@ static void SetLcdForceBlack(Service::Interface* self) { // the color to black (all zero). data.is_enabled.Assign(enable_black); - LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_top), data.raw); // Top LCD + LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_top), data.raw); // Top LCD LCD::Write(HW::VADDR_LCD + 4 * LCD_REG_INDEX(color_fill_bottom), data.raw); // Bottom LCD cmd_buff[1] = RESULT_SUCCESS.raw; @@ -679,37 +706,37 @@ static void ReleaseRight(Service::Interface* self) { } const Interface::FunctionInfo FunctionTable[] = { - {0x00010082, WriteHWRegs, "WriteHWRegs"}, - {0x00020084, WriteHWRegsWithMask, "WriteHWRegsWithMask"}, - {0x00030082, nullptr, "WriteHWRegRepeat"}, - {0x00040080, ReadHWRegs, "ReadHWRegs"}, - {0x00050200, SetBufferSwap, "SetBufferSwap"}, - {0x00060082, nullptr, "SetCommandList"}, - {0x000700C2, nullptr, "RequestDma"}, - {0x00080082, FlushDataCache, "FlushDataCache"}, - {0x00090082, nullptr, "InvalidateDataCache"}, - {0x000A0044, nullptr, "RegisterInterruptEvents"}, - {0x000B0040, SetLcdForceBlack, "SetLcdForceBlack"}, - {0x000C0000, TriggerCmdReqQueue, "TriggerCmdReqQueue"}, - {0x000D0140, nullptr, "SetDisplayTransfer"}, - {0x000E0180, nullptr, "SetTextureCopy"}, - {0x000F0200, nullptr, "SetMemoryFill"}, - {0x00100040, SetAxiConfigQoSMode, "SetAxiConfigQoSMode"}, - {0x00110040, nullptr, "SetPerfLogMode"}, - {0x00120000, nullptr, "GetPerfLog"}, - {0x00130042, RegisterInterruptRelayQueue, "RegisterInterruptRelayQueue"}, + {0x00010082, WriteHWRegs, "WriteHWRegs"}, + {0x00020084, WriteHWRegsWithMask, "WriteHWRegsWithMask"}, + {0x00030082, nullptr, "WriteHWRegRepeat"}, + {0x00040080, ReadHWRegs, "ReadHWRegs"}, + {0x00050200, SetBufferSwap, "SetBufferSwap"}, + {0x00060082, nullptr, "SetCommandList"}, + {0x000700C2, nullptr, "RequestDma"}, + {0x00080082, FlushDataCache, "FlushDataCache"}, + {0x00090082, nullptr, "InvalidateDataCache"}, + {0x000A0044, nullptr, "RegisterInterruptEvents"}, + {0x000B0040, SetLcdForceBlack, "SetLcdForceBlack"}, + {0x000C0000, TriggerCmdReqQueue, "TriggerCmdReqQueue"}, + {0x000D0140, nullptr, "SetDisplayTransfer"}, + {0x000E0180, nullptr, "SetTextureCopy"}, + {0x000F0200, nullptr, "SetMemoryFill"}, + {0x00100040, SetAxiConfigQoSMode, "SetAxiConfigQoSMode"}, + {0x00110040, nullptr, "SetPerfLogMode"}, + {0x00120000, nullptr, "GetPerfLog"}, + {0x00130042, RegisterInterruptRelayQueue, "RegisterInterruptRelayQueue"}, {0x00140000, UnregisterInterruptRelayQueue, "UnregisterInterruptRelayQueue"}, - {0x00150002, nullptr, "TryAcquireRight"}, - {0x00160042, AcquireRight, "AcquireRight"}, - {0x00170000, ReleaseRight, "ReleaseRight"}, - {0x00180000, ImportDisplayCaptureInfo, "ImportDisplayCaptureInfo"}, - {0x00190000, nullptr, "SaveVramSysArea"}, - {0x001A0000, nullptr, "RestoreVramSysArea"}, - {0x001B0000, nullptr, "ResetGpuCore"}, - {0x001C0040, nullptr, "SetLedForceOff"}, - {0x001D0040, nullptr, "SetTestCommand"}, - {0x001E0080, nullptr, "SetInternalPriorities"}, - {0x001F0082, nullptr, "StoreDataCache"}, + {0x00150002, nullptr, "TryAcquireRight"}, + {0x00160042, AcquireRight, "AcquireRight"}, + {0x00170000, ReleaseRight, "ReleaseRight"}, + {0x00180000, ImportDisplayCaptureInfo, "ImportDisplayCaptureInfo"}, + {0x00190000, nullptr, "SaveVramSysArea"}, + {0x001A0000, nullptr, "RestoreVramSysArea"}, + {0x001B0000, nullptr, "ResetGpuCore"}, + {0x001C0040, nullptr, "SetLedForceOff"}, + {0x001D0040, nullptr, "SetTestCommand"}, + {0x001E0080, nullptr, "SetInternalPriorities"}, + {0x001F0082, nullptr, "StoreDataCache"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -721,9 +748,9 @@ Interface::Interface() { g_interrupt_event = nullptr; using Kernel::MemoryPermission; - g_shared_memory = Kernel::SharedMemory::Create(nullptr, 0x1000, - MemoryPermission::ReadWrite, MemoryPermission::ReadWrite, - 0, Kernel::MemoryRegion::BASE, "GSP:SharedMemory"); + g_shared_memory = Kernel::SharedMemory::Create(nullptr, 0x1000, MemoryPermission::ReadWrite, + MemoryPermission::ReadWrite, 0, + Kernel::MemoryRegion::BASE, "GSP:SharedMemory"); g_thread_id = 0; gpu_right_acquired = false; diff --git a/src/core/hle/service/gsp_gpu.h b/src/core/hle/service/gsp_gpu.h index 3b4b678a3..79a72f77d 100644 --- a/src/core/hle/service/gsp_gpu.h +++ b/src/core/hle/service/gsp_gpu.h @@ -6,10 +6,8 @@ #include <cstddef> #include <string> - #include "common/bit_field.h" #include "common/common_types.h" - #include "core/hle/result.h" #include "core/hle/service/service.h" @@ -20,30 +18,30 @@ namespace GSP_GPU { /// GSP interrupt ID enum class InterruptId : u8 { - PSC0 = 0x00, - PSC1 = 0x01, - PDC0 = 0x02, // Seems called every vertical screen line - PDC1 = 0x03, // Seems called every frame - PPF = 0x04, - P3D = 0x05, - DMA = 0x06, + PSC0 = 0x00, + PSC1 = 0x01, + PDC0 = 0x02, // Seems called every vertical screen line + PDC1 = 0x03, // Seems called every frame + PPF = 0x04, + P3D = 0x05, + DMA = 0x06, }; /// GSP command ID enum class CommandId : u32 { - REQUEST_DMA = 0x00, + REQUEST_DMA = 0x00, /// Submits a commandlist for execution by the GPU. SUBMIT_GPU_CMDLIST = 0x01, // Fills a given memory range with a particular value - SET_MEMORY_FILL = 0x02, + SET_MEMORY_FILL = 0x02, // Copies an image and optionally performs color-conversion or scaling. // This is highly similar to the GameCube's EFB copy feature - SET_DISPLAY_TRANSFER = 0x03, + SET_DISPLAY_TRANSFER = 0x03, // Conceptionally similar to SET_DISPLAY_TRANSFER and presumable uses the same hardware path - SET_TEXTURE_COPY = 0x04, + SET_TEXTURE_COPY = 0x04, /// Flushes up to 3 cache regions in a single command. CACHE_FLUSH = 0x05, }; @@ -61,19 +59,18 @@ struct InterruptRelayQueue { u32 missed_PDC0; u32 missed_PDC1; - InterruptId slot[0x34]; ///< Interrupt ID slots + InterruptId slot[0x34]; ///< Interrupt ID slots }; -static_assert(sizeof(InterruptRelayQueue) == 0x40, - "InterruptRelayQueue struct has incorrect size"); +static_assert(sizeof(InterruptRelayQueue) == 0x40, "InterruptRelayQueue struct has incorrect size"); struct FrameBufferInfo { BitField<0, 1, u32> active_fb; // 0 = first, 1 = second u32 address_left; u32 address_right; - u32 stride; // maps to 0x1EF00X90 ? - u32 format; // maps to 0x1EF00X70 ? - u32 shown_fb; // maps to 0x1EF00X78 ? + u32 stride; // maps to 0x1EF00X90 ? + u32 format; // maps to 0x1EF00X70 ? + u32 shown_fb; // maps to 0x1EF00X78 ? u32 unknown; }; static_assert(sizeof(FrameBufferInfo) == 0x1c, "Struct has incorrect size"); @@ -91,7 +88,8 @@ static_assert(sizeof(FrameBufferUpdate) == 0x40, "Struct has incorrect size"); // TODO: Not sure if this padding is correct. // Chances are the second block is stored at offset 0x24 rather than 0x20. #ifndef _MSC_VER -static_assert(offsetof(FrameBufferUpdate, framebuffer_info[1]) == 0x20, "FrameBufferInfo element has incorrect alignment"); +static_assert(offsetof(FrameBufferUpdate, framebuffer_info[1]) == 0x20, + "FrameBufferInfo element has incorrect alignment"); #endif /// GSP command @@ -163,13 +161,13 @@ struct CommandBuffer { // Current command index. This index is updated by GSP module after loading the command // data, right before the command is processed. When this index is updated by GSP module, // the total commands field is decreased by one as well. - BitField<0,8,u32> index; + BitField<0, 8, u32> index; // Total commands to process, must not be value 0 when GSP module handles commands. This // must be <=15 when writing a command to shared memory. This is incremented by the // application when writing a command to shared memory, after increasing this value // TriggerCmdReqQueue is only used if this field is value 1. - BitField<8,8,u32> number_commands; + BitField<8, 8, u32> number_commands; }; u32 unk[7]; diff --git a/src/core/hle/service/gsp_lcd.cpp b/src/core/hle/service/gsp_lcd.cpp index c700c21c5..b916dd759 100644 --- a/src/core/hle/service/gsp_lcd.cpp +++ b/src/core/hle/service/gsp_lcd.cpp @@ -10,11 +10,13 @@ namespace GSP_LCD { const Interface::FunctionInfo FunctionTable[] = { + // clang-format off {0x000F0000, nullptr, "PowerOnAllBacklights"}, {0x00100000, nullptr, "PowerOffAllBacklights"}, {0x00110040, nullptr, "PowerOnBacklight"}, {0x00120040, nullptr, "PowerOffBacklight"}, - {0x00130040, nullptr, "SetLedForceOff"} + {0x00130040, nullptr, "SetLedForceOff"}, + // clang-format on }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index cdec11388..99baded11 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -3,19 +3,15 @@ // Refer to the license.txt file included. #include <cmath> - -#include "common/logging/log.h" #include "common/emu_window.h" - -#include "core/hle/service/service.h" -#include "core/hle/service/hid/hid.h" -#include "core/hle/service/hid/hid_spvr.h" -#include "core/hle/service/hid/hid_user.h" - +#include "common/logging/log.h" #include "core/core_timing.h" #include "core/hle/kernel/event.h" #include "core/hle/kernel/shared_memory.h" - +#include "core/hle/service/hid/hid.h" +#include "core/hle/service/hid/hid_spvr.h" +#include "core/hle/service/hid/hid_user.h" +#include "core/hle/service/service.h" #include "video_core/video_core.h" namespace Service { @@ -37,11 +33,13 @@ static u32 next_accelerometer_index; static u32 next_gyroscope_index; static int enable_accelerometer_count = 0; // positive means enabled -static int enable_gyroscope_count = 0; // positive means enabled +static int enable_gyroscope_count = 0; // positive means enabled static PadState GetCirclePadDirectionState(s16 circle_pad_x, s16 circle_pad_y) { - constexpr float TAN30 = 0.577350269, TAN60 = 1 / TAN30; // 30 degree and 60 degree are angular thresholds for directions - constexpr int CIRCLE_PAD_THRESHOLD_SQUARE = 40 * 40; // a circle pad radius greater than 40 will trigger circle pad direction + // 30 degree and 60 degree are angular thresholds for directions + constexpr float TAN30 = 0.577350269, TAN60 = 1 / TAN30; + // a circle pad radius greater than 40 will trigger circle pad direction + constexpr int CIRCLE_PAD_THRESHOLD_SQUARE = 40 * 40; PadState state; state.hex = 0; @@ -90,7 +88,7 @@ void Update() { PadState old_state = mem->pad.entries[last_entry_index].current_state; // Compute bitmask with 1s for bits different from the old state - PadState changed = { { (state.hex ^ old_state.hex) } }; + PadState changed = {{(state.hex ^ old_state.hex)}}; // Get the current Pad entry PadDataEntry& pad_entry = mem->pad.entries[mem->pad.index]; @@ -135,11 +133,13 @@ void Update() { // Update accelerometer if (enable_accelerometer_count > 0) { mem->accelerometer.index = next_accelerometer_index; - next_accelerometer_index = (next_accelerometer_index + 1) % mem->accelerometer.entries.size(); + next_accelerometer_index = + (next_accelerometer_index + 1) % mem->accelerometer.entries.size(); - AccelerometerDataEntry& accelerometer_entry = mem->accelerometer.entries[mem->accelerometer.index]; - std::tie(accelerometer_entry.x, accelerometer_entry.y, accelerometer_entry.z) - = VideoCore::g_emu_window->GetAccelerometerState(); + AccelerometerDataEntry& accelerometer_entry = + mem->accelerometer.entries[mem->accelerometer.index]; + std::tie(accelerometer_entry.x, accelerometer_entry.y, accelerometer_entry.z) = + VideoCore::g_emu_window->GetAccelerometerState(); // Make up "raw" entry // TODO(wwylele): @@ -167,8 +167,8 @@ void Update() { next_gyroscope_index = (next_gyroscope_index + 1) % mem->gyroscope.entries.size(); GyroscopeDataEntry& gyroscope_entry = mem->gyroscope.entries[mem->gyroscope.index]; - std::tie(gyroscope_entry.x, gyroscope_entry.y, gyroscope_entry.z) - = VideoCore::g_emu_window->GetGyroscopeState(); + std::tie(gyroscope_entry.x, gyroscope_entry.y, gyroscope_entry.z) = + VideoCore::g_emu_window->GetGyroscopeState(); // Make up "raw" entry mem->gyroscope.raw_entry.x = gyroscope_entry.x; @@ -188,7 +188,7 @@ void Update() { void GetIPCHandles(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - cmd_buff[1] = 0; // No error + cmd_buff[1] = 0; // No error cmd_buff[2] = 0x14000000; // IPC Command Structure translate-header // TODO(yuriks): Return error from SendSyncRequest is this fails (part of IPC marshalling) cmd_buff[3] = Kernel::g_handle_table.Create(Service::HID::shared_mem).MoveFrom(); @@ -259,9 +259,7 @@ void GetGyroscopeLowCalibrateParam(Service::Interface* self) { const s16 param_unit = 6700; // an approximate value taken from hw GyroscopeCalibrateParam param = { - { 0, param_unit, -param_unit }, - { 0, param_unit, -param_unit }, - { 0, param_unit, -param_unit }, + {0, param_unit, -param_unit}, {0, param_unit, -param_unit}, {0, param_unit, -param_unit}, }; memcpy(&cmd_buff[2], ¶m, sizeof(param)); @@ -286,9 +284,9 @@ void Init() { AddService(new HID_SPVR_Interface); using Kernel::MemoryPermission; - shared_mem = SharedMemory::Create(nullptr, 0x1000, - MemoryPermission::ReadWrite, MemoryPermission::Read, - 0, Kernel::MemoryRegion::BASE, "HID:SharedMemory"); + shared_mem = + SharedMemory::Create(nullptr, 0x1000, MemoryPermission::ReadWrite, MemoryPermission::Read, + 0, Kernel::MemoryRegion::BASE, "HID:SharedMemory"); next_pad_index = 0; next_touch_index = 0; @@ -296,9 +294,9 @@ void Init() { // Create event handles event_pad_or_touch_1 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch1"); event_pad_or_touch_2 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch2"); - event_accelerometer = Event::Create(ResetType::OneShot, "HID:EventAccelerometer"); - event_gyroscope = Event::Create(ResetType::OneShot, "HID:EventGyroscope"); - event_debug_pad = Event::Create(ResetType::OneShot, "HID:EventDebugPad"); + event_accelerometer = Event::Create(ResetType::OneShot, "HID:EventAccelerometer"); + event_gyroscope = Event::Create(ResetType::OneShot, "HID:EventGyroscope"); + event_debug_pad = Event::Create(ResetType::OneShot, "HID:EventDebugPad"); } void Shutdown() { diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 669b1f723..7904e7355 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -5,14 +5,13 @@ #pragma once #include <array> - #ifndef _MSC_VER #include <cstddef> #endif -#include "core/settings.h" #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" +#include "core/settings.h" namespace Service { @@ -103,7 +102,7 @@ struct SharedMem { struct { s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0 s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks` - u32 index; ///< Index of the last updated pad state entry + u32 index; ///< Index of the last updated pad state entry INSERT_PADDING_WORDS(0x2); @@ -121,7 +120,7 @@ struct SharedMem { struct { s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0 s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks` - u32 index; ///< Index of the last updated touch entry + u32 index; ///< Index of the last updated touch entry INSERT_PADDING_WORDS(0x1); @@ -135,7 +134,7 @@ struct SharedMem { struct { s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0 s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks` - u32 index; ///< Index of the last updated accelerometer entry + u32 index; ///< Index of the last updated accelerometer entry INSERT_PADDING_WORDS(0x1); @@ -149,7 +148,7 @@ struct SharedMem { struct { s64 index_reset_ticks; ///< CPU tick count for when HID module updated entry index 0 s64 index_reset_ticks_previous; ///< Previous `index_reset_ticks` - u32 index; ///< Index of the last updated accelerometer entry + u32 index; ///< Index of the last updated accelerometer entry INSERT_PADDING_WORDS(0x1); @@ -176,9 +175,9 @@ struct GyroscopeCalibrateParam { // is technically allowed since C++11. This macro should be enabled once MSVC adds // support for that. #ifndef _MSC_VER -#define ASSERT_REG_POSITION(field_name, position) \ - static_assert(offsetof(SharedMem, field_name) == position * 4, \ - "Field "#field_name" has invalid position") +#define ASSERT_REG_POSITION(field_name, position) \ + static_assert(offsetof(SharedMem, field_name) == position * 4, \ + "Field " #field_name " has invalid position") ASSERT_REG_POSITION(pad.index_reset_ticks, 0x0); ASSERT_REG_POSITION(touch.index_reset_ticks, 0x2A); @@ -187,33 +186,33 @@ ASSERT_REG_POSITION(touch.index_reset_ticks, 0x2A); #endif // !defined(_MSC_VER) // Pre-defined PadStates for single button presses -const PadState PAD_NONE = {{0}}; -const PadState PAD_A = {{1u << 0}}; -const PadState PAD_B = {{1u << 1}}; -const PadState PAD_SELECT = {{1u << 2}}; -const PadState PAD_START = {{1u << 3}}; -const PadState PAD_RIGHT = {{1u << 4}}; -const PadState PAD_LEFT = {{1u << 5}}; -const PadState PAD_UP = {{1u << 6}}; -const PadState PAD_DOWN = {{1u << 7}}; -const PadState PAD_R = {{1u << 8}}; -const PadState PAD_L = {{1u << 9}}; -const PadState PAD_X = {{1u << 10}}; -const PadState PAD_Y = {{1u << 11}}; - -const PadState PAD_ZL = {{1u << 14}}; -const PadState PAD_ZR = {{1u << 15}}; - -const PadState PAD_TOUCH = {{1u << 20}}; - -const PadState PAD_C_RIGHT = {{1u << 24}}; -const PadState PAD_C_LEFT = {{1u << 25}}; -const PadState PAD_C_UP = {{1u << 26}}; -const PadState PAD_C_DOWN = {{1u << 27}}; +const PadState PAD_NONE = {{0}}; +const PadState PAD_A = {{1u << 0}}; +const PadState PAD_B = {{1u << 1}}; +const PadState PAD_SELECT = {{1u << 2}}; +const PadState PAD_START = {{1u << 3}}; +const PadState PAD_RIGHT = {{1u << 4}}; +const PadState PAD_LEFT = {{1u << 5}}; +const PadState PAD_UP = {{1u << 6}}; +const PadState PAD_DOWN = {{1u << 7}}; +const PadState PAD_R = {{1u << 8}}; +const PadState PAD_L = {{1u << 9}}; +const PadState PAD_X = {{1u << 10}}; +const PadState PAD_Y = {{1u << 11}}; + +const PadState PAD_ZL = {{1u << 14}}; +const PadState PAD_ZR = {{1u << 15}}; + +const PadState PAD_TOUCH = {{1u << 20}}; + +const PadState PAD_C_RIGHT = {{1u << 24}}; +const PadState PAD_C_LEFT = {{1u << 25}}; +const PadState PAD_C_UP = {{1u << 26}}; +const PadState PAD_C_DOWN = {{1u << 27}}; const PadState PAD_CIRCLE_RIGHT = {{1u << 28}}; -const PadState PAD_CIRCLE_LEFT = {{1u << 29}}; -const PadState PAD_CIRCLE_UP = {{1u << 30}}; -const PadState PAD_CIRCLE_DOWN = {{1u << 31}}; +const PadState PAD_CIRCLE_LEFT = {{1u << 29}}; +const PadState PAD_CIRCLE_UP = {{1u << 30}}; +const PadState PAD_CIRCLE_DOWN = {{1u << 31}}; /** * HID::GetIPCHandles service function @@ -305,6 +304,5 @@ void Init(); /// Shutdown HID service void Shutdown(); - } } diff --git a/src/core/hle/service/hid/hid_spvr.cpp b/src/core/hle/service/hid/hid_spvr.cpp index 046e65b11..09007e304 100644 --- a/src/core/hle/service/hid/hid_spvr.cpp +++ b/src/core/hle/service/hid/hid_spvr.cpp @@ -9,16 +9,16 @@ namespace Service { namespace HID { const Interface::FunctionInfo FunctionTable[] = { - {0x000A0000, GetIPCHandles, "GetIPCHandles"}, - {0x000B0000, nullptr, "StartAnalogStickCalibration"}, - {0x000E0000, nullptr, "GetAnalogStickCalibrateParam"}, - {0x00110000, EnableAccelerometer, "EnableAccelerometer"}, - {0x00120000, DisableAccelerometer, "DisableAccelerometer"}, - {0x00130000, EnableGyroscopeLow, "EnableGyroscopeLow"}, - {0x00140000, DisableGyroscopeLow, "DisableGyroscopeLow"}, + {0x000A0000, GetIPCHandles, "GetIPCHandles"}, + {0x000B0000, nullptr, "StartAnalogStickCalibration"}, + {0x000E0000, nullptr, "GetAnalogStickCalibrateParam"}, + {0x00110000, EnableAccelerometer, "EnableAccelerometer"}, + {0x00120000, DisableAccelerometer, "DisableAccelerometer"}, + {0x00130000, EnableGyroscopeLow, "EnableGyroscopeLow"}, + {0x00140000, DisableGyroscopeLow, "DisableGyroscopeLow"}, {0x00150000, GetGyroscopeLowRawToDpsCoefficient, "GetGyroscopeLowRawToDpsCoefficient"}, - {0x00160000, GetGyroscopeLowCalibrateParam, "GetGyroscopeLowCalibrateParam"}, - {0x00170000, GetSoundVolume, "GetSoundVolume"}, + {0x00160000, GetGyroscopeLowCalibrateParam, "GetGyroscopeLowCalibrateParam"}, + {0x00170000, GetSoundVolume, "GetSoundVolume"}, }; HID_SPVR_Interface::HID_SPVR_Interface() { diff --git a/src/core/hle/service/hid/hid_user.cpp b/src/core/hle/service/hid/hid_user.cpp index bb157b83d..42591543c 100644 --- a/src/core/hle/service/hid/hid_user.cpp +++ b/src/core/hle/service/hid/hid_user.cpp @@ -9,16 +9,16 @@ namespace Service { namespace HID { const Interface::FunctionInfo FunctionTable[] = { - {0x000A0000, GetIPCHandles, "GetIPCHandles"}, - {0x000B0000, nullptr, "StartAnalogStickCalibration"}, - {0x000E0000, nullptr, "GetAnalogStickCalibrateParam"}, - {0x00110000, EnableAccelerometer, "EnableAccelerometer"}, - {0x00120000, DisableAccelerometer, "DisableAccelerometer"}, - {0x00130000, EnableGyroscopeLow, "EnableGyroscopeLow"}, - {0x00140000, DisableGyroscopeLow, "DisableGyroscopeLow"}, + {0x000A0000, GetIPCHandles, "GetIPCHandles"}, + {0x000B0000, nullptr, "StartAnalogStickCalibration"}, + {0x000E0000, nullptr, "GetAnalogStickCalibrateParam"}, + {0x00110000, EnableAccelerometer, "EnableAccelerometer"}, + {0x00120000, DisableAccelerometer, "DisableAccelerometer"}, + {0x00130000, EnableGyroscopeLow, "EnableGyroscopeLow"}, + {0x00140000, DisableGyroscopeLow, "DisableGyroscopeLow"}, {0x00150000, GetGyroscopeLowRawToDpsCoefficient, "GetGyroscopeLowRawToDpsCoefficient"}, - {0x00160000, GetGyroscopeLowCalibrateParam, "GetGyroscopeLowCalibrateParam"}, - {0x00170000, GetSoundVolume, "GetSoundVolume"}, + {0x00160000, GetGyroscopeLowCalibrateParam, "GetGyroscopeLowCalibrateParam"}, + {0x00170000, GetSoundVolume, "GetSoundVolume"}, }; HID_U_Interface::HID_U_Interface() { diff --git a/src/core/hle/service/http_c.cpp b/src/core/hle/service/http_c.cpp index 0855ab227..3cf62a4b8 100644 --- a/src/core/hle/service/http_c.cpp +++ b/src/core/hle/service/http_c.cpp @@ -10,56 +10,56 @@ namespace HTTP_C { const Interface::FunctionInfo FunctionTable[] = { - {0x00010044, nullptr, "Initialize"}, - {0x00020082, nullptr, "CreateContext"}, - {0x00030040, nullptr, "CloseContext"}, - {0x00040040, nullptr, "CancelConnection"}, - {0x00050040, nullptr, "GetRequestState"}, - {0x00060040, nullptr, "GetDownloadSizeState"}, - {0x00070040, nullptr, "GetRequestError"}, - {0x00080042, nullptr, "InitializeConnectionSession"}, - {0x00090040, nullptr, "BeginRequest"}, - {0x000A0040, nullptr, "BeginRequestAsync"}, - {0x000B0082, nullptr, "ReceiveData"}, - {0x000C0102, nullptr, "ReceiveDataTimeout"}, - {0x000D0146, nullptr, "SetProxy"}, - {0x000E0040, nullptr, "SetProxyDefault"}, - {0x000F00C4, nullptr, "SetBasicAuthorization"}, - {0x00100080, nullptr, "SetSocketBufferSize"}, - {0x001100C4, nullptr, "AddRequestHeader"}, - {0x001200C4, nullptr, "AddPostDataAscii"}, - {0x001300C4, nullptr, "AddPostDataBinary"}, - {0x00140082, nullptr, "AddPostDataRaw"}, - {0x00150080, nullptr, "SetPostDataType"}, - {0x001600C4, nullptr, "SendPostDataAscii"}, - {0x00170144, nullptr, "SendPostDataAsciiTimeout"}, - {0x001800C4, nullptr, "SendPostDataBinary"}, - {0x00190144, nullptr, "SendPostDataBinaryTimeout"}, - {0x001A0082, nullptr, "SendPostDataRaw"}, - {0x001B0102, nullptr, "SendPOSTDataRawTimeout"}, - {0x001C0080, nullptr, "SetPostDataEncoding"}, - {0x001D0040, nullptr, "NotifyFinishSendPostData"}, - {0x001E00C4, nullptr, "GetResponseHeader"}, - {0x001F0144, nullptr, "GetResponseHeaderTimeout"}, - {0x00200082, nullptr, "GetResponseData"}, - {0x00210102, nullptr, "GetResponseDataTimeout"}, - {0x00220040, nullptr, "GetResponseStatusCode"}, - {0x002300C0, nullptr, "GetResponseStatusCodeTimeout"}, - {0x00240082, nullptr, "AddTrustedRootCA"}, - {0x00250080, nullptr, "AddDefaultCert"}, - {0x00260080, nullptr, "SelectRootCertChain"}, - {0x002700C4, nullptr, "SetClientCert"}, - {0x002B0080, nullptr, "SetSSLOpt"}, - {0x002C0080, nullptr, "SetSSLClearOpt"}, - {0x002D0000, nullptr, "CreateRootCertChain"}, - {0x002E0040, nullptr, "DestroyRootCertChain"}, - {0x002F0082, nullptr, "RootCertChainAddCert"}, - {0x00300080, nullptr, "RootCertChainAddDefaultCert"}, - {0x00350186, nullptr, "SetDefaultProxy"}, - {0x00360000, nullptr, "ClearDNSCache"}, - {0x00370080, nullptr, "SetKeepAlive"}, - {0x003800C0, nullptr, "SetPostDataTypeSize"}, - {0x00390000, nullptr, "Finalize"}, + {0x00010044, nullptr, "Initialize"}, + {0x00020082, nullptr, "CreateContext"}, + {0x00030040, nullptr, "CloseContext"}, + {0x00040040, nullptr, "CancelConnection"}, + {0x00050040, nullptr, "GetRequestState"}, + {0x00060040, nullptr, "GetDownloadSizeState"}, + {0x00070040, nullptr, "GetRequestError"}, + {0x00080042, nullptr, "InitializeConnectionSession"}, + {0x00090040, nullptr, "BeginRequest"}, + {0x000A0040, nullptr, "BeginRequestAsync"}, + {0x000B0082, nullptr, "ReceiveData"}, + {0x000C0102, nullptr, "ReceiveDataTimeout"}, + {0x000D0146, nullptr, "SetProxy"}, + {0x000E0040, nullptr, "SetProxyDefault"}, + {0x000F00C4, nullptr, "SetBasicAuthorization"}, + {0x00100080, nullptr, "SetSocketBufferSize"}, + {0x001100C4, nullptr, "AddRequestHeader"}, + {0x001200C4, nullptr, "AddPostDataAscii"}, + {0x001300C4, nullptr, "AddPostDataBinary"}, + {0x00140082, nullptr, "AddPostDataRaw"}, + {0x00150080, nullptr, "SetPostDataType"}, + {0x001600C4, nullptr, "SendPostDataAscii"}, + {0x00170144, nullptr, "SendPostDataAsciiTimeout"}, + {0x001800C4, nullptr, "SendPostDataBinary"}, + {0x00190144, nullptr, "SendPostDataBinaryTimeout"}, + {0x001A0082, nullptr, "SendPostDataRaw"}, + {0x001B0102, nullptr, "SendPOSTDataRawTimeout"}, + {0x001C0080, nullptr, "SetPostDataEncoding"}, + {0x001D0040, nullptr, "NotifyFinishSendPostData"}, + {0x001E00C4, nullptr, "GetResponseHeader"}, + {0x001F0144, nullptr, "GetResponseHeaderTimeout"}, + {0x00200082, nullptr, "GetResponseData"}, + {0x00210102, nullptr, "GetResponseDataTimeout"}, + {0x00220040, nullptr, "GetResponseStatusCode"}, + {0x002300C0, nullptr, "GetResponseStatusCodeTimeout"}, + {0x00240082, nullptr, "AddTrustedRootCA"}, + {0x00250080, nullptr, "AddDefaultCert"}, + {0x00260080, nullptr, "SelectRootCertChain"}, + {0x002700C4, nullptr, "SetClientCert"}, + {0x002B0080, nullptr, "SetSSLOpt"}, + {0x002C0080, nullptr, "SetSSLClearOpt"}, + {0x002D0000, nullptr, "CreateRootCertChain"}, + {0x002E0040, nullptr, "DestroyRootCertChain"}, + {0x002F0082, nullptr, "RootCertChainAddCert"}, + {0x00300080, nullptr, "RootCertChainAddDefaultCert"}, + {0x00350186, nullptr, "SetDefaultProxy"}, + {0x00360000, nullptr, "ClearDNSCache"}, + {0x00370080, nullptr, "SetKeepAlive"}, + {0x003800C0, nullptr, "SetPostDataTypeSize"}, + {0x00390000, nullptr, "Finalize"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/ir/ir.cpp b/src/core/hle/service/ir/ir.cpp index 079a87e48..4d6639ded 100644 --- a/src/core/hle/service/ir/ir.cpp +++ b/src/core/hle/service/ir/ir.cpp @@ -4,12 +4,11 @@ #include "core/hle/kernel/event.h" #include "core/hle/kernel/shared_memory.h" - -#include "core/hle/service/service.h" #include "core/hle/service/ir/ir.h" #include "core/hle/service/ir/ir_rst.h" #include "core/hle/service/ir/ir_u.h" #include "core/hle/service/ir/ir_user.h" +#include "core/hle/service/service.h" namespace Service { namespace IR { @@ -32,14 +31,14 @@ void InitializeIrNopShared(Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 transfer_buff_size = cmd_buff[1]; - u32 recv_buff_size = cmd_buff[2]; - u32 unk1 = cmd_buff[3]; - u32 send_buff_size = cmd_buff[4]; - u32 unk2 = cmd_buff[5]; - u8 baud_rate = cmd_buff[6] & 0xFF; - Handle handle = cmd_buff[8]; - - if(Kernel::g_handle_table.IsValid(handle)) { + u32 recv_buff_size = cmd_buff[2]; + u32 unk1 = cmd_buff[3]; + u32 send_buff_size = cmd_buff[4]; + u32 unk2 = cmd_buff[5]; + u8 baud_rate = cmd_buff[6] & 0xFF; + Handle handle = cmd_buff[8]; + + if (Kernel::g_handle_table.IsValid(handle)) { transfer_shared_memory = Kernel::g_handle_table.Get<Kernel::SharedMemory>(handle); transfer_shared_memory->name = "IR:TransferSharedMemory"; } @@ -47,7 +46,7 @@ void InitializeIrNopShared(Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; LOG_WARNING(Service_IR, "(STUBBED) called, transfer_buff_size=%d, recv_buff_size=%d, " - "unk1=%d, send_buff_size=%d, unk2=%d, baud_rate=%u, handle=0x%08X", + "unk1=%d, send_buff_size=%d, unk2=%d, baud_rate=%u, handle=0x%08X", transfer_buff_size, recv_buff_size, unk1, send_buff_size, unk2, baud_rate, handle); } @@ -94,13 +93,13 @@ void Init() { AddService(new IR_User_Interface); using Kernel::MemoryPermission; - shared_memory = SharedMemory::Create(nullptr, 0x1000, - Kernel::MemoryPermission::ReadWrite, Kernel::MemoryPermission::ReadWrite, - 0, Kernel::MemoryRegion::BASE, "IR:SharedMemory"); + shared_memory = SharedMemory::Create(nullptr, 0x1000, Kernel::MemoryPermission::ReadWrite, + Kernel::MemoryPermission::ReadWrite, 0, + Kernel::MemoryRegion::BASE, "IR:SharedMemory"); transfer_shared_memory = nullptr; // Create event handle(s) - handle_event = Event::Create(ResetType::OneShot, "IR:HandleEvent"); + handle_event = Event::Create(ResetType::OneShot, "IR:HandleEvent"); conn_status_event = Event::Create(ResetType::OneShot, "IR:ConnectionStatusEvent"); } diff --git a/src/core/hle/service/ir/ir_rst.cpp b/src/core/hle/service/ir/ir_rst.cpp index c0300f109..1f10ebd3d 100644 --- a/src/core/hle/service/ir/ir_rst.cpp +++ b/src/core/hle/service/ir/ir_rst.cpp @@ -9,10 +9,10 @@ namespace Service { namespace IR { const Interface::FunctionInfo FunctionTable[] = { - {0x00010000, GetHandles, "GetHandles"}, - {0x00020080, nullptr, "Initialize"}, - {0x00030000, nullptr, "Shutdown"}, - {0x00090000, nullptr, "WriteToTwoFields"}, + {0x00010000, GetHandles, "GetHandles"}, + {0x00020080, nullptr, "Initialize"}, + {0x00030000, nullptr, "Shutdown"}, + {0x00090000, nullptr, "WriteToTwoFields"}, }; IR_RST_Interface::IR_RST_Interface() { diff --git a/src/core/hle/service/ir/ir_u.cpp b/src/core/hle/service/ir/ir_u.cpp index 96f76cb83..429615f31 100644 --- a/src/core/hle/service/ir/ir_u.cpp +++ b/src/core/hle/service/ir/ir_u.cpp @@ -8,24 +8,26 @@ namespace Service { namespace IR { const Interface::FunctionInfo FunctionTable[] = { - {0x00010000, nullptr, "Initialize"}, - {0x00020000, nullptr, "Shutdown"}, - {0x00030042, nullptr, "StartSendTransfer"}, - {0x00040000, nullptr, "WaitSendTransfer"}, - {0x000500C2, nullptr, "StartRecvTransfer"}, - {0x00060000, nullptr, "WaitRecvTransfer"}, - {0x00070080, nullptr, "GetRecvTransferCount"}, - {0x00080000, nullptr, "GetSendState"}, - {0x00090040, nullptr, "SetBitRate"}, - {0x000A0000, nullptr, "GetBitRate"}, - {0x000B0040, nullptr, "SetIRLEDState"}, - {0x000C0000, nullptr, "GetIRLEDRecvState"}, - {0x000D0000, nullptr, "GetSendFinishedEvent"}, - {0x000E0000, nullptr, "GetRecvFinishedEvent"}, - {0x000F0000, nullptr, "GetTransferState"}, - {0x00100000, nullptr, "GetErrorStatus"}, - {0x00110040, nullptr, "SetSleepModeActive"}, - {0x00120040, nullptr, "SetSleepModeState"}, + // clang-format off + {0x00010000, nullptr, "Initialize"}, + {0x00020000, nullptr, "Shutdown"}, + {0x00030042, nullptr, "StartSendTransfer"}, + {0x00040000, nullptr, "WaitSendTransfer"}, + {0x000500C2, nullptr, "StartRecvTransfer"}, + {0x00060000, nullptr, "WaitRecvTransfer"}, + {0x00070080, nullptr, "GetRecvTransferCount"}, + {0x00080000, nullptr, "GetSendState"}, + {0x00090040, nullptr, "SetBitRate"}, + {0x000A0000, nullptr, "GetBitRate"}, + {0x000B0040, nullptr, "SetIRLEDState"}, + {0x000C0000, nullptr, "GetIRLEDRecvState"}, + {0x000D0000, nullptr, "GetSendFinishedEvent"}, + {0x000E0000, nullptr, "GetRecvFinishedEvent"}, + {0x000F0000, nullptr, "GetTransferState"}, + {0x00100000, nullptr, "GetErrorStatus"}, + {0x00110040, nullptr, "SetSleepModeActive"}, + {0x00120040, nullptr, "SetSleepModeState"}, + // clang-format off }; IR_U_Interface::IR_U_Interface() { diff --git a/src/core/hle/service/ir/ir_user.cpp b/src/core/hle/service/ir/ir_user.cpp index 06a601029..6cff1d544 100644 --- a/src/core/hle/service/ir/ir_user.cpp +++ b/src/core/hle/service/ir/ir_user.cpp @@ -9,32 +9,32 @@ namespace Service { namespace IR { const Interface::FunctionInfo FunctionTable[] = { - {0x00010182, nullptr, "InitializeIrNop"}, - {0x00020000, FinalizeIrNop, "FinalizeIrNop"}, - {0x00030000, nullptr, "ClearReceiveBuffer"}, - {0x00040000, nullptr, "ClearSendBuffer"}, - {0x000500C0, nullptr, "WaitConnection"}, - {0x00060040, RequireConnection, "RequireConnection"}, - {0x000702C0, nullptr, "AutoConnection"}, - {0x00080000, nullptr, "AnyConnection"}, - {0x00090000, Disconnect, "Disconnect"}, - {0x000A0000, nullptr, "GetReceiveEvent"}, - {0x000B0000, nullptr, "GetSendEvent"}, + {0x00010182, nullptr, "InitializeIrNop"}, + {0x00020000, FinalizeIrNop, "FinalizeIrNop"}, + {0x00030000, nullptr, "ClearReceiveBuffer"}, + {0x00040000, nullptr, "ClearSendBuffer"}, + {0x000500C0, nullptr, "WaitConnection"}, + {0x00060040, RequireConnection, "RequireConnection"}, + {0x000702C0, nullptr, "AutoConnection"}, + {0x00080000, nullptr, "AnyConnection"}, + {0x00090000, Disconnect, "Disconnect"}, + {0x000A0000, nullptr, "GetReceiveEvent"}, + {0x000B0000, nullptr, "GetSendEvent"}, {0x000C0000, GetConnectionStatusEvent, "GetConnectionStatusEvent"}, - {0x000D0042, nullptr, "SendIrNop"}, - {0x000E0042, nullptr, "SendIrNopLarge"}, - {0x000F0040, nullptr, "ReceiveIrnop"}, - {0x00100042, nullptr, "ReceiveIrnopLarge"}, - {0x00110040, nullptr, "GetLatestReceiveErrorResult"}, - {0x00120040, nullptr, "GetLatestSendErrorResult"}, - {0x00130000, nullptr, "GetConnectionStatus"}, - {0x00140000, nullptr, "GetTryingToConnectStatus"}, - {0x00150000, nullptr, "GetReceiveSizeFreeAndUsed"}, - {0x00160000, nullptr, "GetSendSizeFreeAndUsed"}, - {0x00170000, nullptr, "GetConnectionRole"}, - {0x00180182, InitializeIrNopShared, "InitializeIrNopShared"}, - {0x00190040, nullptr, "ReleaseReceivedData"}, - {0x001A0040, nullptr, "SetOwnMachineId"}, + {0x000D0042, nullptr, "SendIrNop"}, + {0x000E0042, nullptr, "SendIrNopLarge"}, + {0x000F0040, nullptr, "ReceiveIrnop"}, + {0x00100042, nullptr, "ReceiveIrnopLarge"}, + {0x00110040, nullptr, "GetLatestReceiveErrorResult"}, + {0x00120040, nullptr, "GetLatestSendErrorResult"}, + {0x00130000, nullptr, "GetConnectionStatus"}, + {0x00140000, nullptr, "GetTryingToConnectStatus"}, + {0x00150000, nullptr, "GetReceiveSizeFreeAndUsed"}, + {0x00160000, nullptr, "GetSendSizeFreeAndUsed"}, + {0x00170000, nullptr, "GetConnectionRole"}, + {0x00180182, InitializeIrNopShared, "InitializeIrNopShared"}, + {0x00190040, nullptr, "ReleaseReceivedData"}, + {0x001A0040, nullptr, "SetOwnMachineId"}, }; IR_User_Interface::IR_User_Interface() { diff --git a/src/core/hle/service/ldr_ro/cro_helper.cpp b/src/core/hle/service/ldr_ro/cro_helper.cpp index 3d2a613ee..b7d250312 100644 --- a/src/core/hle/service/ldr_ro/cro_helper.cpp +++ b/src/core/hle/service/ldr_ro/cro_helper.cpp @@ -5,7 +5,6 @@ #include "common/alignment.h" #include "common/logging/log.h" #include "common/scope_exit.h" - #include "core/hle/service/ldr_ro/cro_helper.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -14,37 +13,30 @@ namespace LDR_RO { static const ResultCode ERROR_BUFFER_TOO_SMALL = // 0xE0E12C1F - ResultCode(static_cast<ErrorDescription>(31), ErrorModule::RO, ErrorSummary::InvalidArgument, ErrorLevel::Usage); + ResultCode(static_cast<ErrorDescription>(31), ErrorModule::RO, ErrorSummary::InvalidArgument, + ErrorLevel::Usage); static ResultCode CROFormatError(u32 description) { - return ResultCode(static_cast<ErrorDescription>(description), ErrorModule::RO, ErrorSummary::WrongArgument, ErrorLevel::Permanent); + return ResultCode(static_cast<ErrorDescription>(description), ErrorModule::RO, + ErrorSummary::WrongArgument, ErrorLevel::Permanent); } -const std::array<int, 17> CROHelper::ENTRY_SIZE {{ +const std::array<int, 17> CROHelper::ENTRY_SIZE{{ 1, // code 1, // data 1, // module name - sizeof(SegmentEntry), - sizeof(ExportNamedSymbolEntry), - sizeof(ExportIndexedSymbolEntry), + sizeof(SegmentEntry), sizeof(ExportNamedSymbolEntry), sizeof(ExportIndexedSymbolEntry), 1, // export strings - sizeof(ExportTreeEntry), - sizeof(ImportModuleEntry), - sizeof(ExternalRelocationEntry), - sizeof(ImportNamedSymbolEntry), - sizeof(ImportIndexedSymbolEntry), + sizeof(ExportTreeEntry), sizeof(ImportModuleEntry), sizeof(ExternalRelocationEntry), + sizeof(ImportNamedSymbolEntry), sizeof(ImportIndexedSymbolEntry), sizeof(ImportAnonymousSymbolEntry), 1, // import strings - sizeof(StaticAnonymousSymbolEntry), - sizeof(InternalRelocationEntry), - sizeof(StaticRelocationEntry) + sizeof(StaticAnonymousSymbolEntry), sizeof(InternalRelocationEntry), + sizeof(StaticRelocationEntry), }}; -const std::array<CROHelper::HeaderField, 4> CROHelper::FIX_BARRIERS {{ - Fix0Barrier, - Fix1Barrier, - Fix2Barrier, - Fix3Barrier +const std::array<CROHelper::HeaderField, 4> CROHelper::FIX_BARRIERS{{ + Fix0Barrier, Fix1Barrier, Fix2Barrier, Fix3Barrier, }}; VAddr CROHelper::SegmentTagToAddress(SegmentTag segment_tag) const { @@ -63,7 +55,7 @@ VAddr CROHelper::SegmentTagToAddress(SegmentTag segment_tag) const { } ResultCode CROHelper::ApplyRelocation(VAddr target_address, RelocationType relocation_type, - u32 addend, u32 symbol_address, u32 target_future_address) { + u32 addend, u32 symbol_address, u32 target_future_address) { switch (relocation_type) { case RelocationType::Nothing: @@ -124,7 +116,8 @@ ResultCode CROHelper::ApplyRelocationBatch(VAddr batch, u32 symbol_address, bool return CROFormatError(0x12); } - ResultCode result = ApplyRelocation(relocation_target, relocation.type, relocation.addend, symbol_address, relocation_target); + ResultCode result = ApplyRelocation(relocation_target, relocation.type, relocation.addend, + symbol_address, relocation_target); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying relocation %08X", result.raw); return result; @@ -167,7 +160,7 @@ VAddr CROHelper::FindExportNamedSymbol(const std::string& name) const { if (test_byte >= len) { next.raw = entry.left.raw; - } else if((name[test_byte] >> test_bit_in_byte) & 1) { + } else if ((name[test_byte] >> test_bit_in_byte) & 1) { next.raw = entry.right.raw; } else { next.raw = entry.left.raw; @@ -213,24 +206,12 @@ ResultCode CROHelper::RebaseHeader(u32 cro_size) { // verifies that all offsets are in the correct order constexpr std::array<HeaderField, 18> OFFSET_ORDER = {{ - CodeOffset, - ModuleNameOffset, - SegmentTableOffset, - ExportNamedSymbolTableOffset, - ExportTreeTableOffset, - ExportIndexedSymbolTableOffset, - ExportStringsOffset, - ImportModuleTableOffset, - ExternalRelocationTableOffset, - ImportNamedSymbolTableOffset, - ImportIndexedSymbolTableOffset, - ImportAnonymousSymbolTableOffset, - ImportStringsOffset, - StaticAnonymousSymbolTableOffset, - InternalRelocationTableOffset, - StaticRelocationTableOffset, - DataOffset, - FileSize + CodeOffset, ModuleNameOffset, SegmentTableOffset, ExportNamedSymbolTableOffset, + ExportTreeTableOffset, ExportIndexedSymbolTableOffset, ExportStringsOffset, + ImportModuleTableOffset, ExternalRelocationTableOffset, ImportNamedSymbolTableOffset, + ImportIndexedSymbolTableOffset, ImportAnonymousSymbolTableOffset, ImportStringsOffset, + StaticAnonymousSymbolTableOffset, InternalRelocationTableOffset, + StaticRelocationTableOffset, DataOffset, FileSize, }}; u32 prev_offset = GetField(OFFSET_ORDER[0]); @@ -266,9 +247,9 @@ ResultCode CROHelper::RebaseHeader(u32 cro_size) { return RESULT_SUCCESS; } -ResultVal<VAddr> CROHelper::RebaseSegmentTable(u32 cro_size, - VAddr data_segment_address, u32 data_segment_size, - VAddr bss_segment_address, u32 bss_segment_size) { +ResultVal<VAddr> CROHelper::RebaseSegmentTable(u32 cro_size, VAddr data_segment_address, + u32 data_segment_size, VAddr bss_segment_address, + u32 bss_segment_size) { u32 prev_data_segment = 0; u32 segment_num = GetField(SegmentNum); @@ -309,8 +290,8 @@ ResultCode CROHelper::RebaseExportNamedSymbolTable() { if (entry.name_offset != 0) { entry.name_offset += module_address; - if (entry.name_offset < export_strings_offset - || entry.name_offset >= export_strings_end) { + if (entry.name_offset < export_strings_offset || + entry.name_offset >= export_strings_end) { return CROFormatError(0x11); } } @@ -337,9 +318,13 @@ ResultCode CROHelper::RebaseImportModuleTable() { VAddr import_strings_offset = GetField(ImportStringsOffset); VAddr import_strings_end = import_strings_offset + GetField(ImportStringsSize); VAddr import_indexed_symbol_table_offset = GetField(ImportIndexedSymbolTableOffset); - VAddr index_import_table_end = import_indexed_symbol_table_offset + GetField(ImportIndexedSymbolNum) * sizeof(ImportIndexedSymbolEntry); + VAddr index_import_table_end = + import_indexed_symbol_table_offset + + GetField(ImportIndexedSymbolNum) * sizeof(ImportIndexedSymbolEntry); VAddr import_anonymous_symbol_table_offset = GetField(ImportAnonymousSymbolTableOffset); - VAddr offset_import_table_end = import_anonymous_symbol_table_offset + GetField(ImportAnonymousSymbolNum) * sizeof(ImportAnonymousSymbolEntry); + VAddr offset_import_table_end = + import_anonymous_symbol_table_offset + + GetField(ImportAnonymousSymbolNum) * sizeof(ImportAnonymousSymbolEntry); u32 module_num = GetField(ImportModuleNum); for (u32 i = 0; i < module_num; ++i) { @@ -348,24 +333,24 @@ ResultCode CROHelper::RebaseImportModuleTable() { if (entry.name_offset != 0) { entry.name_offset += module_address; - if (entry.name_offset < import_strings_offset - || entry.name_offset >= import_strings_end) { + if (entry.name_offset < import_strings_offset || + entry.name_offset >= import_strings_end) { return CROFormatError(0x18); } } if (entry.import_indexed_symbol_table_offset != 0) { entry.import_indexed_symbol_table_offset += module_address; - if (entry.import_indexed_symbol_table_offset < import_indexed_symbol_table_offset - || entry.import_indexed_symbol_table_offset > index_import_table_end) { + if (entry.import_indexed_symbol_table_offset < import_indexed_symbol_table_offset || + entry.import_indexed_symbol_table_offset > index_import_table_end) { return CROFormatError(0x18); } } if (entry.import_anonymous_symbol_table_offset != 0) { entry.import_anonymous_symbol_table_offset += module_address; - if (entry.import_anonymous_symbol_table_offset < import_anonymous_symbol_table_offset - || entry.import_anonymous_symbol_table_offset > offset_import_table_end) { + if (entry.import_anonymous_symbol_table_offset < import_anonymous_symbol_table_offset || + entry.import_anonymous_symbol_table_offset > offset_import_table_end) { return CROFormatError(0x18); } } @@ -379,25 +364,27 @@ ResultCode CROHelper::RebaseImportNamedSymbolTable() { VAddr import_strings_offset = GetField(ImportStringsOffset); VAddr import_strings_end = import_strings_offset + GetField(ImportStringsSize); VAddr external_relocation_table_offset = GetField(ExternalRelocationTableOffset); - VAddr external_relocation_table_end = external_relocation_table_offset + GetField(ExternalRelocationNum) * sizeof(ExternalRelocationEntry); + VAddr external_relocation_table_end = + external_relocation_table_offset + + GetField(ExternalRelocationNum) * sizeof(ExternalRelocationEntry); u32 num = GetField(ImportNamedSymbolNum); - for (u32 i = 0; i < num ; ++i) { + for (u32 i = 0; i < num; ++i) { ImportNamedSymbolEntry entry; GetEntry(i, entry); if (entry.name_offset != 0) { entry.name_offset += module_address; - if (entry.name_offset < import_strings_offset - || entry.name_offset >= import_strings_end) { + if (entry.name_offset < import_strings_offset || + entry.name_offset >= import_strings_end) { return CROFormatError(0x1B); } } if (entry.relocation_batch_offset != 0) { entry.relocation_batch_offset += module_address; - if (entry.relocation_batch_offset < external_relocation_table_offset - || entry.relocation_batch_offset > external_relocation_table_end) { + if (entry.relocation_batch_offset < external_relocation_table_offset || + entry.relocation_batch_offset > external_relocation_table_end) { return CROFormatError(0x1B); } } @@ -409,17 +396,19 @@ ResultCode CROHelper::RebaseImportNamedSymbolTable() { ResultCode CROHelper::RebaseImportIndexedSymbolTable() { VAddr external_relocation_table_offset = GetField(ExternalRelocationTableOffset); - VAddr external_relocation_table_end = external_relocation_table_offset + GetField(ExternalRelocationNum) * sizeof(ExternalRelocationEntry); + VAddr external_relocation_table_end = + external_relocation_table_offset + + GetField(ExternalRelocationNum) * sizeof(ExternalRelocationEntry); u32 num = GetField(ImportIndexedSymbolNum); - for (u32 i = 0; i < num ; ++i) { + for (u32 i = 0; i < num; ++i) { ImportIndexedSymbolEntry entry; GetEntry(i, entry); if (entry.relocation_batch_offset != 0) { entry.relocation_batch_offset += module_address; - if (entry.relocation_batch_offset < external_relocation_table_offset - || entry.relocation_batch_offset > external_relocation_table_end) { + if (entry.relocation_batch_offset < external_relocation_table_offset || + entry.relocation_batch_offset > external_relocation_table_end) { return CROFormatError(0x14); } } @@ -431,17 +420,19 @@ ResultCode CROHelper::RebaseImportIndexedSymbolTable() { ResultCode CROHelper::RebaseImportAnonymousSymbolTable() { VAddr external_relocation_table_offset = GetField(ExternalRelocationTableOffset); - VAddr external_relocation_table_end = external_relocation_table_offset + GetField(ExternalRelocationNum) * sizeof(ExternalRelocationEntry); + VAddr external_relocation_table_end = + external_relocation_table_offset + + GetField(ExternalRelocationNum) * sizeof(ExternalRelocationEntry); u32 num = GetField(ImportAnonymousSymbolNum); - for (u32 i = 0; i < num ; ++i) { + for (u32 i = 0; i < num; ++i) { ImportAnonymousSymbolEntry entry; GetEntry(i, entry); if (entry.relocation_batch_offset != 0) { entry.relocation_batch_offset += module_address; - if (entry.relocation_batch_offset < external_relocation_table_offset - || entry.relocation_batch_offset > external_relocation_table_end) { + if (entry.relocation_batch_offset < external_relocation_table_offset || + entry.relocation_batch_offset > external_relocation_table_end) { return CROFormatError(0x17); } } @@ -475,7 +466,8 @@ ResultCode CROHelper::ResetExternalRelocations() { return CROFormatError(0x12); } - ResultCode result = ApplyRelocation(relocation_target, relocation.type, relocation.addend, unresolved_symbol, relocation_target); + ResultCode result = ApplyRelocation(relocation_target, relocation.type, relocation.addend, + unresolved_symbol, relocation_target); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying relocation %08X", result.raw); return result; @@ -528,23 +520,27 @@ ResultCode CROHelper::ClearExternalRelocations() { ResultCode CROHelper::ApplyStaticAnonymousSymbolToCRS(VAddr crs_address) { VAddr static_relocation_table_offset = GetField(StaticRelocationTableOffset); - VAddr static_relocation_table_end = static_relocation_table_offset + GetField(StaticRelocationNum) * sizeof(StaticRelocationEntry); + VAddr static_relocation_table_end = + static_relocation_table_offset + + GetField(StaticRelocationNum) * sizeof(StaticRelocationEntry); CROHelper crs(crs_address); u32 offset_export_num = GetField(StaticAnonymousSymbolNum); - LOG_INFO(Service_LDR, "CRO \"%s\" exports %d static anonymous symbols", ModuleName().data(), offset_export_num); + LOG_INFO(Service_LDR, "CRO \"%s\" exports %d static anonymous symbols", ModuleName().data(), + offset_export_num); for (u32 i = 0; i < offset_export_num; ++i) { StaticAnonymousSymbolEntry entry; GetEntry(i, entry); u32 batch_address = entry.relocation_batch_offset + module_address; - if (batch_address < static_relocation_table_offset - || batch_address > static_relocation_table_end) { + if (batch_address < static_relocation_table_offset || + batch_address > static_relocation_table_end) { return CROFormatError(0x16); } u32 symbol_address = SegmentTagToAddress(entry.symbol_position); - LOG_TRACE(Service_LDR, "CRO \"%s\" exports 0x%08X to the static module", ModuleName().data(), symbol_address); + LOG_TRACE(Service_LDR, "CRO \"%s\" exports 0x%08X to the static module", + ModuleName().data(), symbol_address); ResultCode result = crs.ApplyRelocationBatch(batch_address, symbol_address); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); @@ -571,7 +567,8 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) { if (target_segment.type == SegmentType::Data) { // If the relocation is to the .data segment, we need to relocate it in the old buffer - target_address = old_data_segment_address + relocation.target_position.offset_into_segment; + target_address = + old_data_segment_address + relocation.target_position.offset_into_segment; } else { target_address = target_addressB; } @@ -582,8 +579,10 @@ ResultCode CROHelper::ApplyInternalRelocations(u32 old_data_segment_address) { SegmentEntry symbol_segment; GetEntry(relocation.symbol_segment, symbol_segment); - LOG_TRACE(Service_LDR, "Internally relocates 0x%08X with 0x%08X", target_address, symbol_segment.offset); - ResultCode result = ApplyRelocation(target_address, relocation.type, relocation.addend, symbol_segment.offset, target_addressB); + LOG_TRACE(Service_LDR, "Internally relocates 0x%08X with 0x%08X", target_address, + symbol_segment.offset); + ResultCode result = ApplyRelocation(target_address, relocation.type, relocation.addend, + symbol_segment.offset, target_addressB); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying relocation %08X", result.raw); return result; @@ -734,25 +733,29 @@ ResultCode CROHelper::ApplyImportNamedSymbol(VAddr crs_address) { Memory::ReadBlock(relocation_addr, &relocation_entry, sizeof(ExternalRelocationEntry)); if (!relocation_entry.is_batch_resolved) { - ResultCode result = ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> { - std::string symbol_name = Memory::ReadCString(entry.name_offset, import_strings_size); - u32 symbol_address = source.FindExportNamedSymbol(symbol_name); - - if (symbol_address != 0) { - LOG_TRACE(Service_LDR, "CRO \"%s\" imports \"%s\" from \"%s\"", - ModuleName().data(), symbol_name.data(), source.ModuleName().data()); - - ResultCode result = ApplyRelocationBatch(relocation_addr, symbol_address); - if (result.IsError()) { - LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); - return result; + ResultCode result = + ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> { + std::string symbol_name = + Memory::ReadCString(entry.name_offset, import_strings_size); + u32 symbol_address = source.FindExportNamedSymbol(symbol_name); + + if (symbol_address != 0) { + LOG_TRACE(Service_LDR, "CRO \"%s\" imports \"%s\" from \"%s\"", + ModuleName().data(), symbol_name.data(), + source.ModuleName().data()); + + ResultCode result = ApplyRelocationBatch(relocation_addr, symbol_address); + if (result.IsError()) { + LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", + result.raw); + return result; + } + + return MakeResult<bool>(false); } - return MakeResult<bool>(false); - } - - return MakeResult<bool>(true); - }); + return MakeResult<bool>(true); + }); if (result.IsError()) { return result; } @@ -777,7 +780,6 @@ ResultCode CROHelper::ResetImportNamedSymbol() { LOG_ERROR(Service_LDR, "Error reseting relocation batch %08X", result.raw); return result; } - } return RESULT_SUCCESS; } @@ -831,40 +833,47 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) { GetEntry(i, entry); std::string want_cro_name = Memory::ReadCString(entry.name_offset, import_strings_size); - ResultCode result = ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> { - if (want_cro_name == source.ModuleName()) { - LOG_INFO(Service_LDR, "CRO \"%s\" imports %d indexed symbols from \"%s\"", - ModuleName().data(), entry.import_indexed_symbol_num, source.ModuleName().data()); - for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) { - ImportIndexedSymbolEntry im; - entry.GetImportIndexedSymbolEntry(j, im); - ExportIndexedSymbolEntry ex; - source.GetEntry(im.index, ex); - u32 symbol_address = source.SegmentTagToAddress(ex.symbol_position); - LOG_TRACE(Service_LDR, " Imports 0x%08X", symbol_address); - ResultCode result = ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); - if (result.IsError()) { - LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); - return result; + ResultCode result = + ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> { + if (want_cro_name == source.ModuleName()) { + LOG_INFO(Service_LDR, "CRO \"%s\" imports %d indexed symbols from \"%s\"", + ModuleName().data(), entry.import_indexed_symbol_num, + source.ModuleName().data()); + for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) { + ImportIndexedSymbolEntry im; + entry.GetImportIndexedSymbolEntry(j, im); + ExportIndexedSymbolEntry ex; + source.GetEntry(im.index, ex); + u32 symbol_address = source.SegmentTagToAddress(ex.symbol_position); + LOG_TRACE(Service_LDR, " Imports 0x%08X", symbol_address); + ResultCode result = + ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); + if (result.IsError()) { + LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", + result.raw); + return result; + } } - } - LOG_INFO(Service_LDR, "CRO \"%s\" imports %d anonymous symbols from \"%s\"", - ModuleName().data(), entry.import_anonymous_symbol_num, source.ModuleName().data()); - for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) { - ImportAnonymousSymbolEntry im; - entry.GetImportAnonymousSymbolEntry(j, im); - u32 symbol_address = source.SegmentTagToAddress(im.symbol_position); - LOG_TRACE(Service_LDR, " Imports 0x%08X", symbol_address); - ResultCode result = ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); - if (result.IsError()) { - LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); - return result; + LOG_INFO(Service_LDR, "CRO \"%s\" imports %d anonymous symbols from \"%s\"", + ModuleName().data(), entry.import_anonymous_symbol_num, + source.ModuleName().data()); + for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) { + ImportAnonymousSymbolEntry im; + entry.GetImportAnonymousSymbolEntry(j, im); + u32 symbol_address = source.SegmentTagToAddress(im.symbol_position); + LOG_TRACE(Service_LDR, " Imports 0x%08X", symbol_address); + ResultCode result = + ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); + if (result.IsError()) { + LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", + result.raw); + return result; + } } + return MakeResult<bool>(false); } - return MakeResult<bool>(false); - } - return MakeResult<bool>(true); - }); + return MakeResult<bool>(true); + }); if (result.IsError()) { return result; } @@ -873,8 +882,8 @@ ResultCode CROHelper::ApplyModuleImport(VAddr crs_address) { } ResultCode CROHelper::ApplyExportNamedSymbol(CROHelper target) { - LOG_DEBUG(Service_LDR, "CRO \"%s\" exports named symbols to \"%s\"", - ModuleName().data(), target.ModuleName().data()); + LOG_DEBUG(Service_LDR, "CRO \"%s\" exports named symbols to \"%s\"", ModuleName().data(), + target.ModuleName().data()); u32 target_import_strings_size = target.GetField(ImportStringsSize); u32 target_symbol_import_num = target.GetField(ImportNamedSymbolNum); for (u32 i = 0; i < target_symbol_import_num; ++i) { @@ -885,7 +894,8 @@ ResultCode CROHelper::ApplyExportNamedSymbol(CROHelper target) { Memory::ReadBlock(relocation_addr, &relocation_entry, sizeof(ExternalRelocationEntry)); if (!relocation_entry.is_batch_resolved) { - std::string symbol_name = Memory::ReadCString(entry.name_offset, target_import_strings_size); + std::string symbol_name = + Memory::ReadCString(entry.name_offset, target_import_strings_size); u32 symbol_address = FindExportNamedSymbol(symbol_name); if (symbol_address != 0) { LOG_TRACE(Service_LDR, " exports symbol \"%s\"", symbol_name.data()); @@ -901,8 +911,8 @@ ResultCode CROHelper::ApplyExportNamedSymbol(CROHelper target) { } ResultCode CROHelper::ResetExportNamedSymbol(CROHelper target) { - LOG_DEBUG(Service_LDR, "CRO \"%s\" unexports named symbols to \"%s\"", - ModuleName().data(), target.ModuleName().data()); + LOG_DEBUG(Service_LDR, "CRO \"%s\" unexports named symbols to \"%s\"", ModuleName().data(), + target.ModuleName().data()); u32 unresolved_symbol = target.GetOnUnresolvedAddress(); u32 target_import_strings_size = target.GetField(ImportStringsSize); u32 target_symbol_import_num = target.GetField(ImportNamedSymbolNum); @@ -914,11 +924,13 @@ ResultCode CROHelper::ResetExportNamedSymbol(CROHelper target) { Memory::ReadBlock(relocation_addr, &relocation_entry, sizeof(ExternalRelocationEntry)); if (relocation_entry.is_batch_resolved) { - std::string symbol_name = Memory::ReadCString(entry.name_offset, target_import_strings_size); + std::string symbol_name = + Memory::ReadCString(entry.name_offset, target_import_strings_size); u32 symbol_address = FindExportNamedSymbol(symbol_name); if (symbol_address != 0) { LOG_TRACE(Service_LDR, " unexports symbol \"%s\"", symbol_name.data()); - ResultCode result = target.ApplyRelocationBatch(relocation_addr, unresolved_symbol, true); + ResultCode result = + target.ApplyRelocationBatch(relocation_addr, unresolved_symbol, true); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); return result; @@ -940,8 +952,8 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) { if (Memory::ReadCString(entry.name_offset, target_import_string_size) != module_name) continue; - LOG_INFO(Service_LDR, "CRO \"%s\" exports %d indexed symbols to \"%s\"", - module_name.data(), entry.import_indexed_symbol_num, target.ModuleName().data()); + LOG_INFO(Service_LDR, "CRO \"%s\" exports %d indexed symbols to \"%s\"", module_name.data(), + entry.import_indexed_symbol_num, target.ModuleName().data()); for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) { ImportIndexedSymbolEntry im; entry.GetImportIndexedSymbolEntry(j, im); @@ -949,7 +961,8 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) { GetEntry(im.index, ex); u32 symbol_address = SegmentTagToAddress(ex.symbol_position); LOG_TRACE(Service_LDR, " exports symbol 0x%08X", symbol_address); - ResultCode result = target.ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); + ResultCode result = + target.ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); return result; @@ -957,13 +970,14 @@ ResultCode CROHelper::ApplyModuleExport(CROHelper target) { } LOG_INFO(Service_LDR, "CRO \"%s\" exports %d anonymous symbols to \"%s\"", - module_name.data(), entry.import_anonymous_symbol_num, target.ModuleName().data()); + module_name.data(), entry.import_anonymous_symbol_num, target.ModuleName().data()); for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) { ImportAnonymousSymbolEntry im; entry.GetImportAnonymousSymbolEntry(j, im); u32 symbol_address = SegmentTagToAddress(im.symbol_position); LOG_TRACE(Service_LDR, " exports symbol 0x%08X", symbol_address); - ResultCode result = target.ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); + ResultCode result = + target.ApplyRelocationBatch(im.relocation_batch_offset, symbol_address); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); return result; @@ -987,12 +1001,13 @@ ResultCode CROHelper::ResetModuleExport(CROHelper target) { if (Memory::ReadCString(entry.name_offset, target_import_string_size) != module_name) continue; - LOG_DEBUG(Service_LDR, "CRO \"%s\" unexports indexed symbols to \"%s\"", - module_name.data(), target.ModuleName().data()); + LOG_DEBUG(Service_LDR, "CRO \"%s\" unexports indexed symbols to \"%s\"", module_name.data(), + target.ModuleName().data()); for (u32 j = 0; j < entry.import_indexed_symbol_num; ++j) { ImportIndexedSymbolEntry im; entry.GetImportIndexedSymbolEntry(j, im); - ResultCode result = target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true); + ResultCode result = + target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); return result; @@ -1000,11 +1015,12 @@ ResultCode CROHelper::ResetModuleExport(CROHelper target) { } LOG_DEBUG(Service_LDR, "CRO \"%s\" unexports anonymous symbols to \"%s\"", - module_name.data(), target.ModuleName().data()); + module_name.data(), target.ModuleName().data()); for (u32 j = 0; j < entry.import_anonymous_symbol_num; ++j) { ImportAnonymousSymbolEntry im; entry.GetImportAnonymousSymbolEntry(j, im); - ResultCode result = target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true); + ResultCode result = + target.ApplyRelocationBatch(im.relocation_batch_offset, unresolved_symbol, true); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); return result; @@ -1025,25 +1041,27 @@ ResultCode CROHelper::ApplyExitRelocations(VAddr crs_address) { ExternalRelocationEntry relocation_entry; Memory::ReadBlock(relocation_addr, &relocation_entry, sizeof(ExternalRelocationEntry)); - if (Memory::ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit"){ - ResultCode result = ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> { - u32 symbol_address = source.FindExportNamedSymbol("nnroAeabiAtexit_"); + if (Memory::ReadCString(entry.name_offset, import_strings_size) == "__aeabi_atexit") { + ResultCode result = + ForEachAutoLinkCRO(crs_address, [&](CROHelper source) -> ResultVal<bool> { + u32 symbol_address = source.FindExportNamedSymbol("nnroAeabiAtexit_"); - if (symbol_address != 0) { - LOG_DEBUG(Service_LDR, "CRO \"%s\" import exit function from \"%s\"", - ModuleName().data(), source.ModuleName().data()); + if (symbol_address != 0) { + LOG_DEBUG(Service_LDR, "CRO \"%s\" import exit function from \"%s\"", + ModuleName().data(), source.ModuleName().data()); - ResultCode result = ApplyRelocationBatch(relocation_addr, symbol_address); - if (result.IsError()) { - LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", result.raw); - return result; - } + ResultCode result = ApplyRelocationBatch(relocation_addr, symbol_address); + if (result.IsError()) { + LOG_ERROR(Service_LDR, "Error applying relocation batch %08X", + result.raw); + return result; + } - return MakeResult<bool>(false); - } + return MakeResult<bool>(false); + } - return MakeResult<bool>(true); - }); + return MakeResult<bool>(true); + }); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error applying exit relocation %08X", result.raw); return result; @@ -1070,9 +1088,9 @@ static ResultCode VerifyStringTableLength(VAddr address, u32 size) { return RESULT_SUCCESS; } -ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, - VAddr data_segment_addresss, u32 data_segment_size, - VAddr bss_segment_address, u32 bss_segment_size, bool is_crs) { +ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment_addresss, + u32 data_segment_size, VAddr bss_segment_address, u32 bss_segment_size, + bool is_crs) { ResultCode result = RebaseHeader(cro_size); if (result.IsError()) { @@ -1088,9 +1106,8 @@ ResultCode CROHelper::Rebase(VAddr crs_address, u32 cro_size, u32 prev_data_segment_address = 0; if (!is_crs) { - auto result_val = RebaseSegmentTable(cro_size, - data_segment_addresss, data_segment_size, - bss_segment_address, bss_segment_size); + auto result_val = RebaseSegmentTable(cro_size, data_segment_addresss, data_segment_size, + bss_segment_address, bss_segment_size); if (result_val.Failed()) { LOG_ERROR(Service_LDR, "Error rebasing segment table %08X", result_val.Code().raw); return result_val.Code(); @@ -1374,7 +1391,8 @@ void CROHelper::Unregister(VAddr crs_address) { CROHelper next_head(crs.NextModule()), previous_head(crs.PreviousModule()); CROHelper next(NextModule()), previous(PreviousModule()); - if (module_address == next_head.module_address || module_address == previous_head.module_address) { + if (module_address == next_head.module_address || + module_address == previous_head.module_address) { // removing head if (next.module_address) { // the next is new head @@ -1400,7 +1418,8 @@ void CROHelper::Unregister(VAddr crs_address) { // let head's previous point to the new tail if (next_head.module_address && next_head.PreviousModule() == module_address) { next_head.SetPreviousModule(previous.module_address); - } else if (previous_head.module_address && previous_head.PreviousModule() == module_address) { + } else if (previous_head.module_address && + previous_head.PreviousModule() == module_address) { previous_head.SetPreviousModule(previous.module_address); } else { UNREACHABLE(); @@ -1419,9 +1438,9 @@ u32 CROHelper::GetFixEnd(u32 fix_level) const { u32 entry_size_i = 2; int field = ModuleNameOffset; while (true) { - end = std::max<u32>(end, - GetField(static_cast<HeaderField>(field)) + - GetField(static_cast<HeaderField>(field + 1)) * ENTRY_SIZE[entry_size_i]); + end = std::max<u32>(end, GetField(static_cast<HeaderField>(field)) + + GetField(static_cast<HeaderField>(field + 1)) * + ENTRY_SIZE[entry_size_i]); ++entry_size_i; field += 2; diff --git a/src/core/hle/service/ldr_ro/cro_helper.h b/src/core/hle/service/ldr_ro/cro_helper.h index 34e357afd..6a0d0d3bf 100644 --- a/src/core/hle/service/ldr_ro/cro_helper.h +++ b/src/core/hle/service/ldr_ro/cro_helper.h @@ -6,12 +6,10 @@ #include <array> #include <tuple> - #include "common/common_types.h" #include "common/swap.h" - -#include "core/memory.h" #include "core/hle/result.h" +#include "core/memory.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // Namespace LDR_RO @@ -21,14 +19,17 @@ namespace LDR_RO { // GCC versions < 5.0 do not implement std::is_trivially_copyable. // Excluding MSVC because it has weird behaviour for std::is_trivially_copyable. #if (__GNUC__ >= 5) || defined(__clang__) - #define ASSERT_CRO_STRUCT(name, size) \ - static_assert(std::is_standard_layout<name>::value, "CRO structure " #name " doesn't use standard layout"); \ - static_assert(std::is_trivially_copyable<name>::value, "CRO structure " #name " isn't trivially copyable"); \ - static_assert(sizeof(name) == (size), "Unexpected struct size for CRO structure " #name) +#define ASSERT_CRO_STRUCT(name, size) \ + static_assert(std::is_standard_layout<name>::value, \ + "CRO structure " #name " doesn't use standard layout"); \ + static_assert(std::is_trivially_copyable<name>::value, \ + "CRO structure " #name " isn't trivially copyable"); \ + static_assert(sizeof(name) == (size), "Unexpected struct size for CRO structure " #name) #else - #define ASSERT_CRO_STRUCT(name, size) \ - static_assert(std::is_standard_layout<name>::value, "CRO structure " #name " doesn't use standard layout"); \ - static_assert(sizeof(name) == (size), "Unexpected struct size for CRO structure " #name) +#define ASSERT_CRO_STRUCT(name, size) \ + static_assert(std::is_standard_layout<name>::value, \ + "CRO structure " #name " doesn't use standard layout"); \ + static_assert(sizeof(name) == (size), "Unexpected struct size for CRO structure " #name) #endif static constexpr u32 CRO_HEADER_SIZE = 0x138; @@ -37,8 +38,7 @@ static constexpr u32 CRO_HASH_SIZE = 0x80; /// Represents a loaded module (CRO) with interfaces manipulating it. class CROHelper final { public: - explicit CROHelper(VAddr cro_address) : module_address(cro_address) { - } + explicit CROHelper(VAddr cro_address) : module_address(cro_address) {} std::string ModuleName() const { return Memory::ReadCString(GetField(ModuleNameOffset), GetField(ModuleNameSize)); @@ -59,9 +59,9 @@ public: * @param is_crs true if the module itself is the static module * @returns ResultCode RESULT_SUCCESS on success, otherwise error code. */ - ResultCode Rebase(VAddr crs_address, u32 cro_size, - VAddr data_segment_addresss, u32 data_segment_size, - VAddr bss_segment_address, u32 bss_segment_size, bool is_crs); + ResultCode Rebase(VAddr crs_address, u32 cro_size, VAddr data_segment_addresss, + u32 data_segment_size, VAddr bss_segment_address, u32 bss_segment_size, + bool is_crs); /** * Unrebases the module. @@ -148,8 +148,9 @@ private: const VAddr module_address; ///< the virtual address of this module /** - * Each item in this enum represents a u32 field in the header begin from address+0x80, successively. - * We don't directly use a struct here, to avoid GetPointer, reinterpret_cast, or Read/WriteBlock repeatedly. + * Each item in this enum represents a u32 field in the header begin from address+0x80, + * successively. We don't directly use a struct here, to avoid GetPointer, reinterpret_cast, or + * Read/WriteBlock repeatedly. */ enum HeaderField { Magic = 0, @@ -208,18 +209,20 @@ private: Fix2Barrier = ImportModuleTableOffset, Fix1Barrier = StaticAnonymousSymbolTableOffset, }; - static_assert(Fix0Barrier == (CRO_HEADER_SIZE - CRO_HASH_SIZE) / 4, "CRO Header fields are wrong!"); + static_assert(Fix0Barrier == (CRO_HEADER_SIZE - CRO_HASH_SIZE) / 4, + "CRO Header fields are wrong!"); enum class SegmentType : u32 { - Code = 0, + Code = 0, ROData = 1, - Data = 2, - BSS = 3, + Data = 2, + BSS = 3, }; /** * Identifies a program location inside of a segment. - * Required to refer to program locations because individual segments may be relocated independently of each other. + * Required to refer to program locations because individual segments may be relocated + * independently of each other. */ union SegmentTag { u32_le raw; @@ -282,7 +285,7 @@ private: /// Identifies an indexed symbol imported from another module. struct ImportIndexedSymbolEntry { - u32_le index; // index of an ExportIndexedSymbolEntry in the exporting module + u32_le index; // index of an ExportIndexedSymbolEntry in the exporting module u32_le relocation_batch_offset; // pointing to a relocation batch in ExternalRelocationTable static constexpr HeaderField TABLE_OFFSET_FIELD = ImportIndexedSymbolTableOffset; @@ -291,8 +294,8 @@ private: /// Identifies an anonymous symbol imported from another module. struct ImportAnonymousSymbolEntry { - SegmentTag symbol_position; // in the exporting segment - u32_le relocation_batch_offset; // pointing to a relocation batch in ExternalRelocationTable + SegmentTag symbol_position; // in the exporting segment + u32_le relocation_batch_offset; // pointing to a relocation batch in ExternalRelocationTable static constexpr HeaderField TABLE_OFFSET_FIELD = ImportAnonymousSymbolTableOffset; }; @@ -300,42 +303,47 @@ private: /// Information of a imported module and symbols imported from it. struct ImportModuleEntry { - u32_le name_offset; // pointing to a substring in ImportStrings - u32_le import_indexed_symbol_table_offset; // pointing to a subtable in ImportIndexedSymbolTable + u32_le name_offset; // pointing to a substring in ImportStrings + u32_le import_indexed_symbol_table_offset; // pointing to a subtable in + // ImportIndexedSymbolTable u32_le import_indexed_symbol_num; - u32_le import_anonymous_symbol_table_offset; // pointing to a subtable in ImportAnonymousSymbolTable + u32_le import_anonymous_symbol_table_offset; // pointing to a subtable in + // ImportAnonymousSymbolTable u32_le import_anonymous_symbol_num; static constexpr HeaderField TABLE_OFFSET_FIELD = ImportModuleTableOffset; void GetImportIndexedSymbolEntry(u32 index, ImportIndexedSymbolEntry& entry) { - Memory::ReadBlock(import_indexed_symbol_table_offset + index * sizeof(ImportIndexedSymbolEntry), - &entry, sizeof(ImportIndexedSymbolEntry)); + Memory::ReadBlock(import_indexed_symbol_table_offset + + index * sizeof(ImportIndexedSymbolEntry), + &entry, sizeof(ImportIndexedSymbolEntry)); } void GetImportAnonymousSymbolEntry(u32 index, ImportAnonymousSymbolEntry& entry) { - Memory::ReadBlock(import_anonymous_symbol_table_offset + index * sizeof(ImportAnonymousSymbolEntry), - &entry, sizeof(ImportAnonymousSymbolEntry)); + Memory::ReadBlock(import_anonymous_symbol_table_offset + + index * sizeof(ImportAnonymousSymbolEntry), + &entry, sizeof(ImportAnonymousSymbolEntry)); } }; ASSERT_CRO_STRUCT(ImportModuleEntry, 20); enum class RelocationType : u8 { - Nothing = 0, - AbsoluteAddress = 2, - RelativeAddress = 3, - ThumbBranch = 10, - ArmBranch = 28, - ModifyArmBranch = 29, - AbsoluteAddress2 = 38, + Nothing = 0, + AbsoluteAddress = 2, + RelativeAddress = 3, + ThumbBranch = 10, + ArmBranch = 28, + ModifyArmBranch = 29, + AbsoluteAddress2 = 38, AlignedRelativeAddress = 42, }; struct RelocationEntry { - SegmentTag target_position; // to self's segment as an ExternalRelocationEntry; to static module segment as a StaticRelocationEntry + SegmentTag target_position; // to self's segment as an ExternalRelocationEntry; to static + // module segment as a StaticRelocationEntry RelocationType type; u8 is_batch_end; - u8 is_batch_resolved; // set at a batch beginning if the batch is resolved + u8 is_batch_resolved; // set at a batch beginning if the batch is resolved INSERT_PADDING_BYTES(1); u32_le addend; }; @@ -366,8 +374,8 @@ private: /// Identifies a special static anonymous symbol (no game is known using this). struct StaticAnonymousSymbolEntry { - SegmentTag symbol_position; // to self's segment - u32_le relocation_batch_offset; // pointing to a relocation batch in StaticRelocationTable + SegmentTag symbol_position; // to self's segment + u32_le relocation_batch_offset; // pointing to a relocation batch in StaticRelocationTable static constexpr HeaderField TABLE_OFFSET_FIELD = StaticAnonymousSymbolTableOffset; }; @@ -446,12 +454,15 @@ private: } /** - * A helper function iterating over all registered auto-link modules, including the static module. + * A helper function iterating over all registered auto-link modules, including the static + * module. * @param crs_address the virtual address of the static module * @param func a function object to operate on a module. It accepts one parameter - * CROHelper and returns ResultVal<bool>. It should return true to continue the iteration, + * CROHelper and returns ResultVal<bool>. It should return true to continue the + * iteration, * false to stop the iteration, or an error code (which will also stop the iteration). - * @returns ResultCode indicating the result of the operation, RESULT_SUCCESS if all iteration success, + * @returns ResultCode indicating the result of the operation, RESULT_SUCCESS if all iteration + * success, * otherwise error code of the last iteration. */ template <typename FunctionObject> @@ -477,8 +488,8 @@ private: * Usually equals to target_address, but will be different for a target in .data segment * @returns ResultCode RESULT_SUCCESS on success, otherwise error code. */ - ResultCode ApplyRelocation(VAddr target_address, RelocationType relocation_type, - u32 addend, u32 symbol_address, u32 target_future_address); + ResultCode ApplyRelocation(VAddr target_address, RelocationType relocation_type, u32 addend, + u32 symbol_address, u32 target_future_address); /** * Clears a relocation to zero @@ -492,7 +503,8 @@ private: * Applies or resets a batch of relocations * @param batch the virtual address of the first relocation in the batch * @param symbol_address the symbol address to be relocated with - * @param reset false to set the batch to resolved state, true to reset the batch to unresolved state + * @param reset false to set the batch to resolved state, true to reset the batch to unresolved + * state * @returns ResultCode RESULT_SUCCESS on success, otherwise error code. */ ResultCode ApplyRelocationBatch(VAddr batch, u32 symbol_address, bool reset = false); @@ -507,7 +519,8 @@ private: /** * Rebases offsets in module header according to module address. * @param cro_size the size of the CRO file - * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error code. + * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error + * code. */ ResultCode RebaseHeader(u32 cro_size); @@ -520,43 +533,49 @@ private: * @param bss_segment_size the buffer size for .bss segment * @returns ResultVal<VAddr> with the virtual address of .data segment in CRO. */ - ResultVal<VAddr> RebaseSegmentTable(u32 cro_size, - VAddr data_segment_address, u32 data_segment_size, - VAddr bss_segment_address, u32 bss_segment_size); + ResultVal<VAddr> RebaseSegmentTable(u32 cro_size, VAddr data_segment_address, + u32 data_segment_size, VAddr bss_segment_address, + u32 bss_segment_size); /** * Rebases offsets in exported named symbol table according to module address. - * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error code. + * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error + * code. */ ResultCode RebaseExportNamedSymbolTable(); /** * Verifies indices in export tree table. - * @returns ResultCode RESULT_SUCCESS if all indices are verified as valid, otherwise error code. + * @returns ResultCode RESULT_SUCCESS if all indices are verified as valid, otherwise error + * code. */ ResultCode VerifyExportTreeTable() const; /** * Rebases offsets in exported module table according to module address. - * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error code. + * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error + * code. */ ResultCode RebaseImportModuleTable(); /** * Rebases offsets in imported named symbol table according to module address. - * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error code. + * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error + * code. */ ResultCode RebaseImportNamedSymbolTable(); /** * Rebases offsets in imported indexed symbol table according to module address. - * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error code. + * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error + * code. */ ResultCode RebaseImportIndexedSymbolTable(); /** * Rebases offsets in imported anonymous symbol table according to module address. - * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error code. + * @returns ResultCode RESULT_SUCCESS if all offsets are verified as valid, otherwise error + * code. */ ResultCode RebaseImportAnonymousSymbolTable(); @@ -621,7 +640,8 @@ private: void UnrebaseHeader(); /** - * Looks up all imported named symbols of this module in all registered auto-link modules, and resolves them if found. + * Looks up all imported named symbols of this module in all registered auto-link modules, and + * resolves them if found. * @param crs_address the virtual address of the static module * @returns ResultCode RESULT_SUCCESS on success, otherwise error code. */ @@ -646,7 +666,8 @@ private: ResultCode ResetImportAnonymousSymbol(); /** - * Finds registered auto-link modules that this module imports, and resolves indexed and anonymous symbols exported by them. + * Finds registered auto-link modules that this module imports, and resolves indexed and + * anonymous symbols exported by them. * @param crs_address the virtual address of the static module * @returns ResultCode RESULT_SUCCESS on success, otherwise error code. */ @@ -667,7 +688,8 @@ private: ResultCode ResetExportNamedSymbol(CROHelper target); /** - * Resolves imported indexed and anonymous symbols in the target module which imports this module. + * Resolves imported indexed and anonymous symbols in the target module which imports this + * module. * @param target the module to resolve. * @returns ResultCode RESULT_SUCCESS on success, otherwise error code. */ diff --git a/src/core/hle/service/ldr_ro/ldr_ro.cpp b/src/core/hle/service/ldr_ro/ldr_ro.cpp index 8ba73ea8d..ec183d1f5 100644 --- a/src/core/hle/service/ldr_ro/ldr_ro.cpp +++ b/src/core/hle/service/ldr_ro/ldr_ro.cpp @@ -5,7 +5,6 @@ #include "common/alignment.h" #include "common/common_types.h" #include "common/logging/log.h" - #include "core/arm/arm_interface.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/vm_manager.h" @@ -18,24 +17,33 @@ namespace LDR_RO { -static const ResultCode ERROR_ALREADY_INITIALIZED = // 0xD9612FF9 - ResultCode(ErrorDescription::AlreadyInitialized, ErrorModule::RO, ErrorSummary::Internal, ErrorLevel::Permanent); -static const ResultCode ERROR_NOT_INITIALIZED = // 0xD9612FF8 - ResultCode(ErrorDescription::NotInitialized, ErrorModule::RO, ErrorSummary::Internal, ErrorLevel::Permanent); -static const ResultCode ERROR_BUFFER_TOO_SMALL = // 0xE0E12C1F - ResultCode(static_cast<ErrorDescription>(31), ErrorModule::RO, ErrorSummary::InvalidArgument, ErrorLevel::Usage); -static const ResultCode ERROR_MISALIGNED_ADDRESS = // 0xD9012FF1 - ResultCode(ErrorDescription::MisalignedAddress, ErrorModule::RO, ErrorSummary::WrongArgument, ErrorLevel::Permanent); -static const ResultCode ERROR_MISALIGNED_SIZE = // 0xD9012FF2 - ResultCode(ErrorDescription::MisalignedSize, ErrorModule::RO, ErrorSummary::WrongArgument, ErrorLevel::Permanent); -static const ResultCode ERROR_ILLEGAL_ADDRESS = // 0xE1612C0F - ResultCode(static_cast<ErrorDescription>(15), ErrorModule::RO, ErrorSummary::Internal, ErrorLevel::Usage); -static const ResultCode ERROR_INVALID_MEMORY_STATE = // 0xD8A12C08 - ResultCode(static_cast<ErrorDescription>(8), ErrorModule::RO, ErrorSummary::InvalidState, ErrorLevel::Permanent); -static const ResultCode ERROR_NOT_LOADED = // 0xD8A12C0D - ResultCode(static_cast<ErrorDescription>(13), ErrorModule::RO, ErrorSummary::InvalidState, ErrorLevel::Permanent); -static const ResultCode ERROR_INVALID_DESCRIPTOR = // 0xD9001830 - ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS, ErrorSummary::WrongArgument, ErrorLevel::Permanent); +static const ResultCode ERROR_ALREADY_INITIALIZED = // 0xD9612FF9 + ResultCode(ErrorDescription::AlreadyInitialized, ErrorModule::RO, ErrorSummary::Internal, + ErrorLevel::Permanent); +static const ResultCode ERROR_NOT_INITIALIZED = // 0xD9612FF8 + ResultCode(ErrorDescription::NotInitialized, ErrorModule::RO, ErrorSummary::Internal, + ErrorLevel::Permanent); +static const ResultCode ERROR_BUFFER_TOO_SMALL = // 0xE0E12C1F + ResultCode(static_cast<ErrorDescription>(31), ErrorModule::RO, ErrorSummary::InvalidArgument, + ErrorLevel::Usage); +static const ResultCode ERROR_MISALIGNED_ADDRESS = // 0xD9012FF1 + ResultCode(ErrorDescription::MisalignedAddress, ErrorModule::RO, ErrorSummary::WrongArgument, + ErrorLevel::Permanent); +static const ResultCode ERROR_MISALIGNED_SIZE = // 0xD9012FF2 + ResultCode(ErrorDescription::MisalignedSize, ErrorModule::RO, ErrorSummary::WrongArgument, + ErrorLevel::Permanent); +static const ResultCode ERROR_ILLEGAL_ADDRESS = // 0xE1612C0F + ResultCode(static_cast<ErrorDescription>(15), ErrorModule::RO, ErrorSummary::Internal, + ErrorLevel::Usage); +static const ResultCode ERROR_INVALID_MEMORY_STATE = // 0xD8A12C08 + ResultCode(static_cast<ErrorDescription>(8), ErrorModule::RO, ErrorSummary::InvalidState, + ErrorLevel::Permanent); +static const ResultCode ERROR_NOT_LOADED = // 0xD8A12C0D + ResultCode(static_cast<ErrorDescription>(13), ErrorModule::RO, ErrorSummary::InvalidState, + ErrorLevel::Permanent); +static const ResultCode ERROR_INVALID_DESCRIPTOR = // 0xD9001830 + ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS, + ErrorSummary::WrongArgument, ErrorLevel::Permanent); static MemorySynchronizer memory_synchronizer; @@ -44,10 +52,10 @@ static VAddr loaded_crs; ///< the virtual address of the static module static bool VerifyBufferState(VAddr buffer_ptr, u32 size) { auto vma = Kernel::g_current_process->vm_manager.FindVMA(buffer_ptr); - return vma != Kernel::g_current_process->vm_manager.vma_map.end() - && vma->second.base + vma->second.size >= buffer_ptr + size - && vma->second.permissions == Kernel::VMAPermission::ReadWrite - && vma->second.meminfo_state == Kernel::MemoryState::Private; + return vma != Kernel::g_current_process->vm_manager.vma_map.end() && + vma->second.base + vma->second.size >= buffer_ptr + size && + vma->second.permissions == Kernel::VMAPermission::ReadWrite && + vma->second.meminfo_state == Kernel::MemoryState::Private; } /** @@ -66,13 +74,14 @@ static bool VerifyBufferState(VAddr buffer_ptr, u32 size) { static void Initialize(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); VAddr crs_buffer_ptr = cmd_buff[1]; - u32 crs_size = cmd_buff[2]; - VAddr crs_address = cmd_buff[3]; - u32 descriptor = cmd_buff[4]; - u32 process = cmd_buff[5]; + u32 crs_size = cmd_buff[2]; + VAddr crs_address = cmd_buff[3]; + u32 descriptor = cmd_buff[4]; + u32 process = cmd_buff[5]; - LOG_DEBUG(Service_LDR, "called, crs_buffer_ptr=0x%08X, crs_address=0x%08X, crs_size=0x%X, descriptor=0x%08X, process=0x%08X", - crs_buffer_ptr, crs_address, crs_size, descriptor, process); + LOG_DEBUG(Service_LDR, "called, crs_buffer_ptr=0x%08X, crs_address=0x%08X, crs_size=0x%X, " + "descriptor=0x%08X, process=0x%08X", + crs_buffer_ptr, crs_address, crs_size, descriptor, process); if (descriptor != 0) { LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); @@ -119,7 +128,8 @@ static void Initialize(Service::Interface* self) { return; } - if (crs_address < Memory::PROCESS_IMAGE_VADDR || crs_address + crs_size > Memory::PROCESS_IMAGE_VADDR_END) { + if (crs_address < Memory::PROCESS_IMAGE_VADDR || + crs_address + crs_size > Memory::PROCESS_IMAGE_VADDR_END) { LOG_ERROR(Service_LDR, "CRS mapping address is not in the process image region"); cmd_buff[1] = ERROR_ILLEGAL_ADDRESS.raw; return; @@ -131,14 +141,17 @@ static void Initialize(Service::Interface* self) { // TODO(wwylele): should be memory aliasing std::shared_ptr<std::vector<u8>> crs_mem = std::make_shared<std::vector<u8>>(crs_size); Memory::ReadBlock(crs_buffer_ptr, crs_mem->data(), crs_size); - result = Kernel::g_current_process->vm_manager.MapMemoryBlock(crs_address, crs_mem, 0, crs_size, Kernel::MemoryState::Code).Code(); + result = Kernel::g_current_process->vm_manager + .MapMemoryBlock(crs_address, crs_mem, 0, crs_size, Kernel::MemoryState::Code) + .Code(); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error mapping memory block %08X", result.raw); cmd_buff[1] = result.raw; return; } - result = Kernel::g_current_process->vm_manager.ReprotectRange(crs_address, crs_size, Kernel::VMAPermission::Read); + result = Kernel::g_current_process->vm_manager.ReprotectRange(crs_address, crs_size, + Kernel::VMAPermission::Read); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error reprotecting memory block %08X", result.raw); cmd_buff[1] = result.raw; @@ -186,9 +199,9 @@ static void Initialize(Service::Interface* self) { static void LoadCRR(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 crr_buffer_ptr = cmd_buff[1]; - u32 crr_size = cmd_buff[2]; - u32 descriptor = cmd_buff[3]; - u32 process = cmd_buff[4]; + u32 crr_size = cmd_buff[2]; + u32 descriptor = cmd_buff[3]; + u32 process = cmd_buff[4]; if (descriptor != 0) { LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); @@ -200,7 +213,8 @@ static void LoadCRR(Service::Interface* self) { cmd_buff[0] = IPC::MakeHeader(2, 1, 0); cmd_buff[1] = RESULT_SUCCESS.raw; // No error - LOG_WARNING(Service_LDR, "(STUBBED) called, crr_buffer_ptr=0x%08X, crr_size=0x%08X, descriptor=0x%08X, process=0x%08X", + LOG_WARNING(Service_LDR, "(STUBBED) called, crr_buffer_ptr=0x%08X, crr_size=0x%08X, " + "descriptor=0x%08X, process=0x%08X", crr_buffer_ptr, crr_size, descriptor, process); } @@ -218,8 +232,8 @@ static void LoadCRR(Service::Interface* self) { static void UnloadCRR(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 crr_buffer_ptr = cmd_buff[1]; - u32 descriptor = cmd_buff[2]; - u32 process = cmd_buff[3]; + u32 descriptor = cmd_buff[2]; + u32 process = cmd_buff[3]; if (descriptor != 0) { LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); @@ -231,7 +245,8 @@ static void UnloadCRR(Service::Interface* self) { cmd_buff[0] = IPC::MakeHeader(3, 1, 0); cmd_buff[1] = RESULT_SUCCESS.raw; // No error - LOG_WARNING(Service_LDR, "(STUBBED) called, crr_buffer_ptr=0x%08X, descriptor=0x%08X, process=0x%08X", + LOG_WARNING(Service_LDR, + "(STUBBED) called, crr_buffer_ptr=0x%08X, descriptor=0x%08X, process=0x%08X", crr_buffer_ptr, descriptor, process); } @@ -263,27 +278,28 @@ static void UnloadCRR(Service::Interface* self) { */ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { u32* cmd_buff = Kernel::GetCommandBuffer(); - VAddr cro_buffer_ptr = cmd_buff[1]; - VAddr cro_address = cmd_buff[2]; - u32 cro_size = cmd_buff[3]; + VAddr cro_buffer_ptr = cmd_buff[1]; + VAddr cro_address = cmd_buff[2]; + u32 cro_size = cmd_buff[3]; VAddr data_segment_address = cmd_buff[4]; - u32 zero = cmd_buff[5]; - u32 data_segment_size = cmd_buff[6]; - u32 bss_segment_address = cmd_buff[7]; - u32 bss_segment_size = cmd_buff[8]; - bool auto_link = (cmd_buff[9] & 0xFF) != 0; - u32 fix_level = cmd_buff[10]; - VAddr crr_address = cmd_buff[11]; - u32 descriptor = cmd_buff[12]; - u32 process = cmd_buff[13]; - - LOG_DEBUG(Service_LDR, "called (%s), cro_buffer_ptr=0x%08X, cro_address=0x%08X, cro_size=0x%X, " - "data_segment_address=0x%08X, zero=%d, data_segment_size=0x%X, bss_segment_address=0x%08X, bss_segment_size=0x%X, " - "auto_link=%s, fix_level=%d, crr_address=0x%08X, descriptor=0x%08X, process=0x%08X", - link_on_load_bug_fix ? "new" : "old", cro_buffer_ptr, cro_address, cro_size, - data_segment_address, zero, data_segment_size, bss_segment_address, bss_segment_size, - auto_link ? "true" : "false", fix_level, crr_address, descriptor, process - ); + u32 zero = cmd_buff[5]; + u32 data_segment_size = cmd_buff[6]; + u32 bss_segment_address = cmd_buff[7]; + u32 bss_segment_size = cmd_buff[8]; + bool auto_link = (cmd_buff[9] & 0xFF) != 0; + u32 fix_level = cmd_buff[10]; + VAddr crr_address = cmd_buff[11]; + u32 descriptor = cmd_buff[12]; + u32 process = cmd_buff[13]; + + LOG_DEBUG(Service_LDR, + "called (%s), cro_buffer_ptr=0x%08X, cro_address=0x%08X, cro_size=0x%X, " + "data_segment_address=0x%08X, zero=%d, data_segment_size=0x%X, " + "bss_segment_address=0x%08X, bss_segment_size=0x%X, " + "auto_link=%s, fix_level=%d, crr_address=0x%08X, descriptor=0x%08X, process=0x%08X", + link_on_load_bug_fix ? "new" : "old", cro_buffer_ptr, cro_address, cro_size, + data_segment_address, zero, data_segment_size, bss_segment_address, bss_segment_size, + auto_link ? "true" : "false", fix_level, crr_address, descriptor, process); if (descriptor != 0) { LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); @@ -330,8 +346,8 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { return; } - if (cro_address < Memory::PROCESS_IMAGE_VADDR - || cro_address + cro_size > Memory::PROCESS_IMAGE_VADDR_END) { + if (cro_address < Memory::PROCESS_IMAGE_VADDR || + cro_address + cro_size > Memory::PROCESS_IMAGE_VADDR_END) { LOG_ERROR(Service_LDR, "CRO mapping address is not in the process image region"); cmd_buff[1] = ERROR_ILLEGAL_ADDRESS.raw; return; @@ -339,7 +355,9 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { if (zero) { LOG_ERROR(Service_LDR, "Zero is not zero %d", zero); - cmd_buff[1] = ResultCode(static_cast<ErrorDescription>(29), ErrorModule::RO, ErrorSummary::Internal, ErrorLevel::Usage).raw; + cmd_buff[1] = ResultCode(static_cast<ErrorDescription>(29), ErrorModule::RO, + ErrorSummary::Internal, ErrorLevel::Usage) + .raw; return; } @@ -349,14 +367,17 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { // TODO(wwylele): should be memory aliasing std::shared_ptr<std::vector<u8>> cro_mem = std::make_shared<std::vector<u8>>(cro_size); Memory::ReadBlock(cro_buffer_ptr, cro_mem->data(), cro_size); - result = Kernel::g_current_process->vm_manager.MapMemoryBlock(cro_address, cro_mem, 0, cro_size, Kernel::MemoryState::Code).Code(); + result = Kernel::g_current_process->vm_manager + .MapMemoryBlock(cro_address, cro_mem, 0, cro_size, Kernel::MemoryState::Code) + .Code(); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error mapping memory block %08X", result.raw); cmd_buff[1] = result.raw; return; } - result = Kernel::g_current_process->vm_manager.ReprotectRange(cro_address, cro_size, Kernel::VMAPermission::Read); + result = Kernel::g_current_process->vm_manager.ReprotectRange(cro_address, cro_size, + Kernel::VMAPermission::Read); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error reprotecting memory block %08X", result.raw); Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size); @@ -384,7 +405,8 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { return; } - result = cro.Rebase(loaded_crs, cro_size, data_segment_address, data_segment_size, bss_segment_address, bss_segment_size, false); + result = cro.Rebase(loaded_crs, cro_size, data_segment_address, data_segment_size, + bss_segment_address, bss_segment_size, false); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error rebasing CRO %08X", result.raw); Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size); @@ -409,7 +431,8 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { // TODO(wwylele): verify the behaviour when buffer_ptr == address if (cro_buffer_ptr != cro_address) { if (fix_size != cro_size) { - result = Kernel::g_current_process->vm_manager.UnmapRange(cro_address + fix_size, cro_size - fix_size); + result = Kernel::g_current_process->vm_manager.UnmapRange(cro_address + fix_size, + cro_size - fix_size); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error unmapping memory block %08X", result.raw); Kernel::g_current_process->vm_manager.UnmapRange(cro_address, cro_size); @@ -426,7 +449,8 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { u32 exe_size; std::tie(exe_begin, exe_size) = cro.GetExecutablePages(); if (exe_begin) { - result = Kernel::g_current_process->vm_manager.ReprotectRange(exe_begin, exe_size, Kernel::VMAPermission::ReadExecute); + result = Kernel::g_current_process->vm_manager.ReprotectRange( + exe_begin, exe_size, Kernel::VMAPermission::ReadExecute); if (result.IsError()) { LOG_ERROR(Service_LDR, "Error reprotecting memory block %08X", result.raw); Kernel::g_current_process->vm_manager.UnmapRange(cro_address, fix_size); @@ -437,8 +461,8 @@ static void LoadCRO(Service::Interface* self, bool link_on_load_bug_fix) { Core::g_app_core->ClearInstructionCache(); - LOG_INFO(Service_LDR, "CRO \"%s\" loaded at 0x%08X, fixed_end=0x%08X", - cro.ModuleName().data(), cro_address, cro_address+fix_size); + LOG_INFO(Service_LDR, "CRO \"%s\" loaded at 0x%08X, fixed_end=0x%08X", cro.ModuleName().data(), + cro_address, cro_address + fix_size); cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[2] = fix_size; @@ -464,14 +488,15 @@ static void LoadCRO(Service::Interface* self) { */ static void UnloadCRO(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - VAddr cro_address = cmd_buff[1]; - u32 zero = cmd_buff[2]; - VAddr cro_buffer_ptr = cmd_buff[3]; - u32 descriptor = cmd_buff[4]; - u32 process = cmd_buff[5]; + VAddr cro_address = cmd_buff[1]; + u32 zero = cmd_buff[2]; + VAddr cro_buffer_ptr = cmd_buff[3]; + u32 descriptor = cmd_buff[4]; + u32 process = cmd_buff[5]; - LOG_DEBUG(Service_LDR, "called, cro_address=0x%08X, zero=%d, cro_buffer_ptr=0x%08X, descriptor=0x%08X, process=0x%08X", - cro_address, zero, cro_buffer_ptr, descriptor, process); + LOG_DEBUG(Service_LDR, "called, cro_address=0x%08X, zero=%d, cro_buffer_ptr=0x%08X, " + "descriptor=0x%08X, process=0x%08X", + cro_address, zero, cro_buffer_ptr, descriptor, process); if (descriptor != 0) { LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); @@ -558,11 +583,11 @@ static void UnloadCRO(Service::Interface* self) { static void LinkCRO(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); VAddr cro_address = cmd_buff[1]; - u32 descriptor = cmd_buff[2]; - u32 process = cmd_buff[3]; + u32 descriptor = cmd_buff[2]; + u32 process = cmd_buff[3]; LOG_DEBUG(Service_LDR, "called, cro_address=0x%08X, descriptor=0x%08X, process=0x%08X", - cro_address, descriptor, process); + cro_address, descriptor, process); if (descriptor != 0) { LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); @@ -620,11 +645,11 @@ static void LinkCRO(Service::Interface* self) { static void UnlinkCRO(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); VAddr cro_address = cmd_buff[1]; - u32 descriptor = cmd_buff[2]; - u32 process = cmd_buff[3]; + u32 descriptor = cmd_buff[2]; + u32 process = cmd_buff[3]; LOG_DEBUG(Service_LDR, "called, cro_address=0x%08X, descriptor=0x%08X, process=0x%08X", - cro_address, descriptor, process); + cro_address, descriptor, process); if (descriptor != 0) { LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); @@ -682,11 +707,11 @@ static void UnlinkCRO(Service::Interface* self) { static void Shutdown(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); VAddr crs_buffer_ptr = cmd_buff[1]; - u32 descriptor = cmd_buff[2]; - u32 process = cmd_buff[3]; + u32 descriptor = cmd_buff[2]; + u32 process = cmd_buff[3]; LOG_DEBUG(Service_LDR, "called, crs_buffer_ptr=0x%08X, descriptor=0x%08X, process=0x%08X", - crs_buffer_ptr, descriptor, process); + crs_buffer_ptr, descriptor, process); if (descriptor != 0) { LOG_ERROR(Service_LDR, "IPC handle descriptor failed validation (0x%X)", descriptor); @@ -724,15 +749,17 @@ static void Shutdown(Service::Interface* self) { } const Interface::FunctionInfo FunctionTable[] = { - {0x000100C2, Initialize, "Initialize"}, - {0x00020082, LoadCRR, "LoadCRR"}, - {0x00030042, UnloadCRR, "UnloadCRR"}, - {0x000402C2, LoadCRO<false>, "LoadCRO"}, - {0x000500C2, UnloadCRO, "UnloadCRO"}, - {0x00060042, LinkCRO, "LinkCRO"}, - {0x00070042, UnlinkCRO, "UnlinkCRO"}, - {0x00080042, Shutdown, "Shutdown"}, - {0x000902C2, LoadCRO<true>, "LoadCRO_New"}, + // clang-format off + {0x000100C2, Initialize, "Initialize"}, + {0x00020082, LoadCRR, "LoadCRR"}, + {0x00030042, UnloadCRR, "UnloadCRR"}, + {0x000402C2, LoadCRO<false>, "LoadCRO"}, + {0x000500C2, UnloadCRO, "UnloadCRO"}, + {0x00060042, LinkCRO, "LinkCRO"}, + {0x00070042, UnlinkCRO, "UnlinkCRO"}, + {0x00080042, Shutdown, "Shutdown"}, + {0x000902C2, LoadCRO<true>, "LoadCRO_New"}, + // clang-format on }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/ldr_ro/memory_synchronizer.cpp b/src/core/hle/service/ldr_ro/memory_synchronizer.cpp index 4402876e6..989887264 100644 --- a/src/core/hle/service/ldr_ro/memory_synchronizer.cpp +++ b/src/core/hle/service/ldr_ro/memory_synchronizer.cpp @@ -3,9 +3,7 @@ // Refer to the license.txt file included. #include <algorithm> - #include "common/assert.h" - #include "core/hle/service/ldr_ro/memory_synchronizer.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -14,9 +12,8 @@ namespace LDR_RO { auto MemorySynchronizer::FindMemoryBlock(VAddr mapping, VAddr original) { - auto block = std::find_if(memory_blocks.begin(), memory_blocks.end(), [=](MemoryBlock& b){ - return b.original == original; - }); + auto block = std::find_if(memory_blocks.begin(), memory_blocks.end(), + [=](MemoryBlock& b) { return b.original == original; }); ASSERT(block->mapping == mapping); return block; } diff --git a/src/core/hle/service/ldr_ro/memory_synchronizer.h b/src/core/hle/service/ldr_ro/memory_synchronizer.h index 92f267912..883ee4acf 100644 --- a/src/core/hle/service/ldr_ro/memory_synchronizer.h +++ b/src/core/hle/service/ldr_ro/memory_synchronizer.h @@ -5,7 +5,6 @@ #pragma once #include <vector> - #include "core/memory.h" //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index f792bc9cd..edd1ea97b 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp @@ -10,22 +10,22 @@ namespace MIC_U { const Interface::FunctionInfo FunctionTable[] = { - {0x00010042, nullptr, "MapSharedMem"}, - {0x00020000, nullptr, "UnmapSharedMem"}, - {0x00030140, nullptr, "Initialize"}, - {0x00040040, nullptr, "AdjustSampling"}, - {0x00050000, nullptr, "StopSampling"}, - {0x00060000, nullptr, "IsSampling"}, - {0x00070000, nullptr, "GetEventHandle"}, - {0x00080040, nullptr, "SetGain"}, - {0x00090000, nullptr, "GetGain"}, - {0x000A0040, nullptr, "SetPower"}, - {0x000B0000, nullptr, "GetPower"}, - {0x000C0042, nullptr, "size"}, - {0x000D0040, nullptr, "SetClamp"}, - {0x000E0000, nullptr, "GetClamp"}, - {0x000F0040, nullptr, "SetAllowShellClosed"}, - {0x00100040, nullptr, "unknown_input2"}, + {0x00010042, nullptr, "MapSharedMem"}, + {0x00020000, nullptr, "UnmapSharedMem"}, + {0x00030140, nullptr, "Initialize"}, + {0x00040040, nullptr, "AdjustSampling"}, + {0x00050000, nullptr, "StopSampling"}, + {0x00060000, nullptr, "IsSampling"}, + {0x00070000, nullptr, "GetEventHandle"}, + {0x00080040, nullptr, "SetGain"}, + {0x00090000, nullptr, "GetGain"}, + {0x000A0040, nullptr, "SetPower"}, + {0x000B0000, nullptr, "GetPower"}, + {0x000C0042, nullptr, "size"}, + {0x000D0040, nullptr, "SetClamp"}, + {0x000E0000, nullptr, "GetClamp"}, + {0x000F0040, nullptr, "SetAllowShellClosed"}, + {0x00100040, nullptr, "unknown_input2"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/ndm/ndm.cpp b/src/core/hle/service/ndm/ndm.cpp index bc9c3413d..5eb97f0d3 100644 --- a/src/core/hle/service/ndm/ndm.cpp +++ b/src/core/hle/service/ndm/ndm.cpp @@ -4,21 +4,23 @@ #include "common/common_types.h" #include "common/logging/log.h" -#include "core/hle/service/service.h" #include "core/hle/service/ndm/ndm.h" #include "core/hle/service/ndm/ndm_u.h" +#include "core/hle/service/service.h" namespace Service { namespace NDM { enum : u32 { DEFAULT_RETRY_INTERVAL = 10, - DEFAULT_SCAN_INTERVAL = 30 + DEFAULT_SCAN_INTERVAL = 30, }; static DaemonMask daemon_bit_mask = DaemonMask::Default; static DaemonMask default_daemon_bit_mask = DaemonMask::Default; -static std::array<DaemonStatus, 4> daemon_status = { DaemonStatus::Idle, DaemonStatus::Idle, DaemonStatus::Idle, DaemonStatus::Idle }; +static std::array<DaemonStatus, 4> daemon_status = { + DaemonStatus::Idle, DaemonStatus::Idle, DaemonStatus::Idle, DaemonStatus::Idle, +}; static ExclusiveState exclusive_state = ExclusiveState::None; static u32 scan_interval = DEFAULT_SCAN_INTERVAL; static u32 retry_interval = DEFAULT_RETRY_INTERVAL; @@ -72,7 +74,8 @@ void UnlockState(Service::Interface* self) { void SuspendDaemons(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 bit_mask = cmd_buff[1] & 0xF; - daemon_bit_mask = static_cast<DaemonMask>(static_cast<u32>(default_daemon_bit_mask) & ~bit_mask); + daemon_bit_mask = + static_cast<DaemonMask>(static_cast<u32>(default_daemon_bit_mask) & ~bit_mask); for (size_t index = 0; index < daemon_status.size(); ++index) { if (bit_mask & (1 << index)) { daemon_status[index] = DaemonStatus::Suspended; @@ -228,9 +231,7 @@ void Init() { AddService(new NDM_U_Interface); } -void Shutdown() { - -} +void Shutdown() {} -}// namespace NDM -}// namespace Service +} // namespace NDM +} // namespace Service diff --git a/src/core/hle/service/ndm/ndm.h b/src/core/hle/service/ndm/ndm.h index 5c2b968dc..979e7fcf1 100644 --- a/src/core/hle/service/ndm/ndm.h +++ b/src/core/hle/service/ndm/ndm.h @@ -13,35 +13,30 @@ class Interface; namespace NDM { enum class Daemon : u32 { - Cec = 0, - Boss = 1, - Nim = 2, - Friend = 3 + Cec = 0, + Boss = 1, + Nim = 2, + Friend = 3, }; enum class DaemonMask : u32 { - None = 0, - Cec = (1 << static_cast<u32>(Daemon::Cec)), - Boss = (1 << static_cast<u32>(Daemon::Boss)), - Nim = (1 << static_cast<u32>(Daemon::Nim)), - Friend = (1 << static_cast<u32>(Daemon::Friend)), + None = 0, + Cec = (1 << static_cast<u32>(Daemon::Cec)), + Boss = (1 << static_cast<u32>(Daemon::Boss)), + Nim = (1 << static_cast<u32>(Daemon::Nim)), + Friend = (1 << static_cast<u32>(Daemon::Friend)), Default = Cec | Friend, - All = Cec | Boss | Nim | Friend + All = Cec | Boss | Nim | Friend, }; -enum class DaemonStatus : u32 { - Busy = 0, - Idle = 1, - Suspending = 2, - Suspended = 3 -}; +enum class DaemonStatus : u32 { Busy = 0, Idle = 1, Suspending = 2, Suspended = 3 }; enum class ExclusiveState : u32 { - None = 0, - Infrastructure = 1, + None = 0, + Infrastructure = 1, LocalCommunications = 2, - Streetpass = 3, - StreetpassData = 4, + Streetpass = 3, + StreetpassData = 4, }; /** @@ -205,7 +200,6 @@ void SetRetryInterval(Service::Interface* self); */ void GetRetryInterval(Service::Interface* self); - /** * NDM::OverrideDefaultDaemons service function * Inputs: @@ -233,7 +227,8 @@ void ResetDefaultDaemons(Service::Interface* self); * 1 : Result, 0 on success, otherwise error code * 2 : Daemon bit mask * Note: - * Gets the current default daemon bit mask. The default value is (DAEMONMASK_CEC | DAEMONMASK_FRIENDS) + * Gets the current default daemon bit mask. The default value is (DAEMONMASK_CEC | + * DAEMONMASK_FRIENDS) */ void GetDefaultDaemons(Service::Interface* self); @@ -252,5 +247,5 @@ void Init(); /// Shutdown NDM service void Shutdown(); -}// namespace NDM -}// namespace Service +} // namespace NDM +} // namespace Service diff --git a/src/core/hle/service/ndm/ndm_u.cpp b/src/core/hle/service/ndm/ndm_u.cpp index 3ff0744ee..f5c7a341a 100644 --- a/src/core/hle/service/ndm/ndm_u.cpp +++ b/src/core/hle/service/ndm/ndm_u.cpp @@ -9,28 +9,28 @@ namespace Service { namespace NDM { const Interface::FunctionInfo FunctionTable[] = { - {0x00010042, EnterExclusiveState, "EnterExclusiveState"}, - {0x00020002, LeaveExclusiveState, "LeaveExclusiveState"}, - {0x00030000, QueryExclusiveMode, "QueryExclusiveMode"}, - {0x00040002, LockState, "LockState"}, - {0x00050002, UnlockState, "UnlockState"}, - {0x00060040, SuspendDaemons, "SuspendDaemons"}, - {0x00070040, ResumeDaemons, "ResumeDaemons"}, - {0x00080040, SuspendScheduler, "SuspendScheduler"}, - {0x00090000, ResumeScheduler, "ResumeScheduler"}, - {0x000A0000, nullptr, "GetCurrentState"}, - {0x000B0000, nullptr, "GetTargetState"}, - {0x000C0000, nullptr, "<Stubbed>"}, - {0x000D0040, QueryStatus, "QueryStatus"}, - {0x000E0040, GetDaemonDisableCount, "GetDaemonDisableCount"}, - {0x000F0000, GetSchedulerDisableCount,"GetSchedulerDisableCount"}, - {0x00100040, SetScanInterval, "SetScanInterval"}, - {0x00110000, GetScanInterval, "GetScanInterval"}, - {0x00120040, SetRetryInterval, "SetRetryInterval"}, - {0x00130000, GetRetryInterval, "GetRetryInterval"}, - {0x00140040, OverrideDefaultDaemons, "OverrideDefaultDaemons"}, - {0x00150000, ResetDefaultDaemons, "ResetDefaultDaemons"}, - {0x00160000, GetDefaultDaemons, "GetDefaultDaemons"}, + {0x00010042, EnterExclusiveState, "EnterExclusiveState"}, + {0x00020002, LeaveExclusiveState, "LeaveExclusiveState"}, + {0x00030000, QueryExclusiveMode, "QueryExclusiveMode"}, + {0x00040002, LockState, "LockState"}, + {0x00050002, UnlockState, "UnlockState"}, + {0x00060040, SuspendDaemons, "SuspendDaemons"}, + {0x00070040, ResumeDaemons, "ResumeDaemons"}, + {0x00080040, SuspendScheduler, "SuspendScheduler"}, + {0x00090000, ResumeScheduler, "ResumeScheduler"}, + {0x000A0000, nullptr, "GetCurrentState"}, + {0x000B0000, nullptr, "GetTargetState"}, + {0x000C0000, nullptr, "<Stubbed>"}, + {0x000D0040, QueryStatus, "QueryStatus"}, + {0x000E0040, GetDaemonDisableCount, "GetDaemonDisableCount"}, + {0x000F0000, GetSchedulerDisableCount, "GetSchedulerDisableCount"}, + {0x00100040, SetScanInterval, "SetScanInterval"}, + {0x00110000, GetScanInterval, "GetScanInterval"}, + {0x00120040, SetRetryInterval, "SetRetryInterval"}, + {0x00130000, GetRetryInterval, "GetRetryInterval"}, + {0x00140040, OverrideDefaultDaemons, "OverrideDefaultDaemons"}, + {0x00150000, ResetDefaultDaemons, "ResetDefaultDaemons"}, + {0x00160000, GetDefaultDaemons, "GetDefaultDaemons"}, {0x00170000, ClearHalfAwakeMacFilter, "ClearHalfAwakeMacFilter"}, }; diff --git a/src/core/hle/service/news/news.cpp b/src/core/hle/service/news/news.cpp index b3f500694..8b70ec45b 100644 --- a/src/core/hle/service/news/news.cpp +++ b/src/core/hle/service/news/news.cpp @@ -3,11 +3,10 @@ // Refer to the license.txt file included. #include "common/logging/log.h" - -#include "core/hle/service/service.h" #include "core/hle/service/news/news.h" #include "core/hle/service/news/news_s.h" #include "core/hle/service/news/news_u.h" +#include "core/hle/service/service.h" namespace Service { namespace NEWS { @@ -19,8 +18,7 @@ void Init() { AddService(new NEWS_U_Interface); } -void Shutdown() { -} +void Shutdown() {} } // namespace NEWS diff --git a/src/core/hle/service/news/news_s.cpp b/src/core/hle/service/news/news_s.cpp index 39b5a50f8..dda3d0f6a 100644 --- a/src/core/hle/service/news/news_s.cpp +++ b/src/core/hle/service/news/news_s.cpp @@ -9,19 +9,19 @@ namespace Service { namespace NEWS { const Interface::FunctionInfo FunctionTable[] = { - {0x000100C6, nullptr, "AddNotification"}, - {0x00050000, nullptr, "GetTotalNotifications"}, - {0x00060042, nullptr, "SetNewsDBHeader"}, - {0x00070082, nullptr, "SetNotificationHeader"}, - {0x00080082, nullptr, "SetNotificationMessage"}, - {0x00090082, nullptr, "SetNotificationImage"}, - {0x000A0042, nullptr, "GetNewsDBHeader"}, - {0x000B0082, nullptr, "GetNotificationHeader"}, - {0x000C0082, nullptr, "GetNotificationMessage"}, - {0x000D0082, nullptr, "GetNotificationImage"}, - {0x000E0040, nullptr, "SetInfoLEDPattern"}, - {0x00120082, nullptr, "GetNotificationHeaderOther"}, - {0x00130000, nullptr, "WriteNewsDBSavedata"}, + {0x000100C6, nullptr, "AddNotification"}, + {0x00050000, nullptr, "GetTotalNotifications"}, + {0x00060042, nullptr, "SetNewsDBHeader"}, + {0x00070082, nullptr, "SetNotificationHeader"}, + {0x00080082, nullptr, "SetNotificationMessage"}, + {0x00090082, nullptr, "SetNotificationImage"}, + {0x000A0042, nullptr, "GetNewsDBHeader"}, + {0x000B0082, nullptr, "GetNotificationHeader"}, + {0x000C0082, nullptr, "GetNotificationMessage"}, + {0x000D0082, nullptr, "GetNotificationImage"}, + {0x000E0040, nullptr, "SetInfoLEDPattern"}, + {0x00120082, nullptr, "GetNotificationHeaderOther"}, + {0x00130000, nullptr, "WriteNewsDBSavedata"}, }; NEWS_S_Interface::NEWS_S_Interface() { diff --git a/src/core/hle/service/news/news_u.cpp b/src/core/hle/service/news/news_u.cpp index 6b75cc24e..a07e466de 100644 --- a/src/core/hle/service/news/news_u.cpp +++ b/src/core/hle/service/news/news_u.cpp @@ -8,7 +8,7 @@ namespace Service { namespace NEWS { const Interface::FunctionInfo FunctionTable[] = { - {0x000100C6, nullptr, "AddNotification"}, + {0x000100C6, nullptr, "AddNotification"}, }; NEWS_U_Interface::NEWS_U_Interface() { diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp index ed42464ce..0be94322c 100644 --- a/src/core/hle/service/nim/nim.cpp +++ b/src/core/hle/service/nim/nim.cpp @@ -4,12 +4,11 @@ #include "common/common_types.h" #include "common/logging/log.h" - -#include "core/hle/service/service.h" #include "core/hle/service/nim/nim.h" #include "core/hle/service/nim/nim_aoc.h" #include "core/hle/service/nim/nim_s.h" #include "core/hle/service/nim/nim_u.h" +#include "core/hle/service/service.h" namespace Service { namespace NIM { @@ -31,8 +30,7 @@ void Init() { AddService(new NIM_U_Interface); } -void Shutdown() { -} +void Shutdown() {} } // namespace NIM diff --git a/src/core/hle/service/nim/nim_aoc.cpp b/src/core/hle/service/nim/nim_aoc.cpp index 4a4818d57..2d0fb6fc4 100644 --- a/src/core/hle/service/nim/nim_aoc.cpp +++ b/src/core/hle/service/nim/nim_aoc.cpp @@ -8,14 +8,14 @@ namespace Service { namespace NIM { const Interface::FunctionInfo FunctionTable[] = { - {0x00030042, nullptr, "SetApplicationId"}, - {0x00040042, nullptr, "SetTin"}, - {0x000902D0, nullptr, "ListContentSetsEx"}, - {0x00180000, nullptr, "GetBalance"}, - {0x001D0000, nullptr, "GetCustomerSupportCode"}, - {0x00210000, nullptr, "Initialize"}, - {0x00240282, nullptr, "CalculateContentsRequiredSize"}, - {0x00250000, nullptr, "RefreshServerTime"}, + {0x00030042, nullptr, "SetApplicationId"}, + {0x00040042, nullptr, "SetTin"}, + {0x000902D0, nullptr, "ListContentSetsEx"}, + {0x00180000, nullptr, "GetBalance"}, + {0x001D0000, nullptr, "GetCustomerSupportCode"}, + {0x00210000, nullptr, "Initialize"}, + {0x00240282, nullptr, "CalculateContentsRequiredSize"}, + {0x00250000, nullptr, "RefreshServerTime"}, }; NIM_AOC_Interface::NIM_AOC_Interface() { diff --git a/src/core/hle/service/nim/nim_s.cpp b/src/core/hle/service/nim/nim_s.cpp index dcaa0255a..e2ba693c9 100644 --- a/src/core/hle/service/nim/nim_s.cpp +++ b/src/core/hle/service/nim/nim_s.cpp @@ -8,10 +8,10 @@ namespace Service { namespace NIM { const Interface::FunctionInfo FunctionTable[] = { - {0x000A0000, nullptr, "CheckSysupdateAvailableSOAP"}, - {0x0016020A, nullptr, "ListTitles"}, - {0x002D0042, nullptr, "DownloadTickets"}, - {0x00420240, nullptr, "StartDownload"}, + {0x000A0000, nullptr, "CheckSysupdateAvailableSOAP"}, + {0x0016020A, nullptr, "ListTitles"}, + {0x002D0042, nullptr, "DownloadTickets"}, + {0x00420240, nullptr, "StartDownload"}, }; NIM_S_Interface::NIM_S_Interface() { @@ -20,4 +20,3 @@ NIM_S_Interface::NIM_S_Interface() { } // namespace NIM } // namespace Service - diff --git a/src/core/hle/service/nim/nim_u.cpp b/src/core/hle/service/nim/nim_u.cpp index eae45ebc0..7e07d02e8 100644 --- a/src/core/hle/service/nim/nim_u.cpp +++ b/src/core/hle/service/nim/nim_u.cpp @@ -9,12 +9,12 @@ namespace Service { namespace NIM { const Interface::FunctionInfo FunctionTable[] = { - {0x00010000, nullptr, "StartSysUpdate"}, - {0x00020000, nullptr, "GetUpdateDownloadProgress"}, - {0x00040000, nullptr, "FinishTitlesInstall"}, - {0x00050000, nullptr, "CheckForSysUpdateEvent"}, - {0x00090000, CheckSysUpdateAvailable, "CheckSysUpdateAvailable"}, - {0x000A0000, nullptr, "GetState"}, + {0x00010000, nullptr, "StartSysUpdate"}, + {0x00020000, nullptr, "GetUpdateDownloadProgress"}, + {0x00040000, nullptr, "FinishTitlesInstall"}, + {0x00050000, nullptr, "CheckForSysUpdateEvent"}, + {0x00090000, CheckSysUpdateAvailable, "CheckSysUpdateAvailable"}, + {0x000A0000, nullptr, "GetState"}, }; NIM_U_Interface::NIM_U_Interface() { @@ -23,4 +23,3 @@ NIM_U_Interface::NIM_U_Interface() { } // namespace NIM } // namespace Service - diff --git a/src/core/hle/service/nim/nim_u.h b/src/core/hle/service/nim/nim_u.h index bc89dc0f3..c4b74985a 100644 --- a/src/core/hle/service/nim/nim_u.h +++ b/src/core/hle/service/nim/nim_u.h @@ -1,6 +1,6 @@ // Copyright 2015 Citra Emulator Project // Licensed under GPLv2 or any later version -// Refer to the license.txt file included.. +// Refer to the license.txt file included. #pragma once diff --git a/src/core/hle/service/ns_s.cpp b/src/core/hle/service/ns_s.cpp index 072918d62..6693f7c08 100644 --- a/src/core/hle/service/ns_s.cpp +++ b/src/core/hle/service/ns_s.cpp @@ -10,21 +10,21 @@ namespace NS_S { const Interface::FunctionInfo FunctionTable[] = { - {0x000100C0, nullptr, "LaunchFIRM"}, - {0x000200C0, nullptr, "LaunchTitle"}, - {0x00030000, nullptr, "TerminateApplication"}, - {0x00040040, nullptr, "TerminateProcess"}, - {0x000500C0, nullptr, "LaunchApplicationFIRM"}, - {0x00060042, nullptr, "SetFIRMParams4A0"}, - {0x00070042, nullptr, "CardUpdateInitialize"}, - {0x00080000, nullptr, "CardUpdateShutdown"}, - {0x000D0140, nullptr, "SetTWLBannerHMAC"}, - {0x000E0000, nullptr, "ShutdownAsync"}, - {0x00100180, nullptr, "RebootSystem"}, - {0x00110100, nullptr, "TerminateTitle"}, - {0x001200C0, nullptr, "SetApplicationCpuTimeLimit"}, - {0x00150140, nullptr, "LaunchApplication"}, - {0x00160000, nullptr, "RebootSystemClean"}, + {0x000100C0, nullptr, "LaunchFIRM"}, + {0x000200C0, nullptr, "LaunchTitle"}, + {0x00030000, nullptr, "TerminateApplication"}, + {0x00040040, nullptr, "TerminateProcess"}, + {0x000500C0, nullptr, "LaunchApplicationFIRM"}, + {0x00060042, nullptr, "SetFIRMParams4A0"}, + {0x00070042, nullptr, "CardUpdateInitialize"}, + {0x00080000, nullptr, "CardUpdateShutdown"}, + {0x000D0140, nullptr, "SetTWLBannerHMAC"}, + {0x000E0000, nullptr, "ShutdownAsync"}, + {0x00100180, nullptr, "RebootSystem"}, + {0x00110100, nullptr, "TerminateTitle"}, + {0x001200C0, nullptr, "SetApplicationCpuTimeLimit"}, + {0x00150140, nullptr, "LaunchApplication"}, + {0x00160000, nullptr, "RebootSystemClean"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/nwm_uds.cpp b/src/core/hle/service/nwm_uds.cpp index ae4640409..27e829209 100644 --- a/src/core/hle/service/nwm_uds.cpp +++ b/src/core/hle/service/nwm_uds.cpp @@ -4,7 +4,6 @@ #include "common/common_types.h" #include "common/logging/log.h" - #include "core/hle/kernel/event.h" #include "core/hle/service/nwm_uds.h" @@ -54,22 +53,23 @@ static void Shutdown(Service::Interface* self) { static void RecvBeaconBroadcastData(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); u32 out_buffer_size = cmd_buff[1]; - u32 unk1 = cmd_buff[2]; - u32 unk2 = cmd_buff[3]; - u32 mac_address = cmd_buff[4]; + u32 unk1 = cmd_buff[2]; + u32 unk2 = cmd_buff[3]; + u32 mac_address = cmd_buff[4]; - u32 unk3 = cmd_buff[6]; + u32 unk3 = cmd_buff[6]; - u32 wlan_comm_id = cmd_buff[15]; - u32 ctr_gen_id = cmd_buff[16]; - u32 value = cmd_buff[17]; - u32 input_handle = cmd_buff[18]; + u32 wlan_comm_id = cmd_buff[15]; + u32 ctr_gen_id = cmd_buff[16]; + u32 value = cmd_buff[17]; + u32 input_handle = cmd_buff[18]; u32 new_buffer_size = cmd_buff[19]; - u32 out_buffer_ptr = cmd_buff[20]; + u32 out_buffer_ptr = cmd_buff[20]; cmd_buff[1] = RESULT_SUCCESS.raw; - LOG_WARNING(Service_NWM, "(STUBBED) called out_buffer_size=0x%08X, unk1=0x%08X, unk2=0x%08X," + LOG_WARNING(Service_NWM, + "(STUBBED) called out_buffer_size=0x%08X, unk1=0x%08X, unk2=0x%08X," "mac_address=0x%08X, unk3=0x%08X, wlan_comm_id=0x%08X, ctr_gen_id=0x%08X," "value=%u, input_handle=0x%08X, new_buffer_size=0x%08X, out_buffer_ptr=0x%08X", out_buffer_size, unk1, unk2, mac_address, unk3, wlan_comm_id, ctr_gen_id, value, @@ -92,46 +92,47 @@ static void RecvBeaconBroadcastData(Service::Interface* self) { */ static void Initialize(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); - u32 unk1 = cmd_buff[1]; - u32 unk2 = cmd_buff[12]; - u32 value = cmd_buff[13]; + u32 unk1 = cmd_buff[1]; + u32 unk2 = cmd_buff[12]; + u32 value = cmd_buff[13]; u32 handle = cmd_buff[14]; cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[2] = 0; - cmd_buff[3] = Kernel::g_handle_table.Create(handle_event).MoveFrom(); //TODO(purpasmart): Verify if this is a event handle + cmd_buff[3] = Kernel::g_handle_table.Create(handle_event) + .MoveFrom(); // TODO(purpasmart): Verify if this is a event handle LOG_WARNING(Service_NWM, "(STUBBED) called unk1=0x%08X, unk2=0x%08X, value=%u, handle=0x%08X", unk1, unk2, value, handle); } const Interface::FunctionInfo FunctionTable[] = { - {0x00020000, nullptr, "Scrap"}, - {0x00030000, Shutdown, "Shutdown"}, - {0x00040402, nullptr, "CreateNetwork"}, - {0x00050040, nullptr, "EjectClient"}, - {0x00060000, nullptr, "EjectSpectator"}, - {0x00070080, nullptr, "UpdateNetworkAttribute"}, - {0x00080000, nullptr, "DestroyNetwork"}, - {0x000A0000, nullptr, "DisconnectNetwork"}, - {0x000B0000, nullptr, "GetConnectionStatus"}, - {0x000D0040, nullptr, "GetNodeInformation"}, - {0x000F0404, RecvBeaconBroadcastData, "RecvBeaconBroadcastData"}, - {0x00100042, nullptr, "SetBeaconAdditionalData"}, - {0x00110040, nullptr, "GetApplicationData"}, - {0x00120100, nullptr, "Bind"}, - {0x00130040, nullptr, "Unbind"}, - {0x001400C0, nullptr, "RecvBroadcastDataFrame"}, - {0x00150080, nullptr, "SetMaxSendDelay"}, - {0x00170182, nullptr, "SendTo"}, - {0x001A0000, nullptr, "GetChannel"}, - {0x001B0302, Initialize, "Initialize"}, - {0x001D0044, nullptr, "BeginHostingNetwork"}, - {0x001E0084, nullptr, "ConnectToNetwork"}, - {0x001F0006, nullptr, "DecryptBeaconData"}, - {0x00200040, nullptr, "Flush"}, - {0x00210080, nullptr, "SetProbeResponseParam"}, - {0x00220402, nullptr, "ScanOnConnection"}, + {0x00020000, nullptr, "Scrap"}, + {0x00030000, Shutdown, "Shutdown"}, + {0x00040402, nullptr, "CreateNetwork"}, + {0x00050040, nullptr, "EjectClient"}, + {0x00060000, nullptr, "EjectSpectator"}, + {0x00070080, nullptr, "UpdateNetworkAttribute"}, + {0x00080000, nullptr, "DestroyNetwork"}, + {0x000A0000, nullptr, "DisconnectNetwork"}, + {0x000B0000, nullptr, "GetConnectionStatus"}, + {0x000D0040, nullptr, "GetNodeInformation"}, + {0x000F0404, RecvBeaconBroadcastData, "RecvBeaconBroadcastData"}, + {0x00100042, nullptr, "SetBeaconAdditionalData"}, + {0x00110040, nullptr, "GetApplicationData"}, + {0x00120100, nullptr, "Bind"}, + {0x00130040, nullptr, "Unbind"}, + {0x001400C0, nullptr, "RecvBroadcastDataFrame"}, + {0x00150080, nullptr, "SetMaxSendDelay"}, + {0x00170182, nullptr, "SendTo"}, + {0x001A0000, nullptr, "GetChannel"}, + {0x001B0302, Initialize, "Initialize"}, + {0x001D0044, nullptr, "BeginHostingNetwork"}, + {0x001E0084, nullptr, "ConnectToNetwork"}, + {0x001F0006, nullptr, "DecryptBeaconData"}, + {0x00200040, nullptr, "Flush"}, + {0x00210080, nullptr, "SetProbeResponseParam"}, + {0x00220402, nullptr, "ScanOnConnection"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/pm_app.cpp b/src/core/hle/service/pm_app.cpp index 05d01bc48..7d91694f6 100644 --- a/src/core/hle/service/pm_app.cpp +++ b/src/core/hle/service/pm_app.cpp @@ -10,18 +10,18 @@ namespace PM_APP { const Interface::FunctionInfo FunctionTable[] = { - {0x00010140, nullptr, "LaunchTitle"}, - {0x00020082, nullptr, "LaunchFIRMSetParams"}, - {0x00030080, nullptr, "TerminateProcesse"}, - {0x00040100, nullptr, "TerminateProcessTID"}, - {0x000500C0, nullptr, "TerminateProcessTID_unknown"}, - {0x00070042, nullptr, "GetFIRMLaunchParams"}, - {0x00080100, nullptr, "GetTitleExheaderFlags"}, - {0x00090042, nullptr, "SetFIRMLaunchParams"}, - {0x000A0140, nullptr, "SetResourceLimit"}, - {0x000B0140, nullptr, "GetResourceLimitMax"}, - {0x000C0080, nullptr, "UnregisterProcess"}, - {0x000D0240, nullptr, "LaunchTitleUpdate"}, + {0x00010140, nullptr, "LaunchTitle"}, + {0x00020082, nullptr, "LaunchFIRMSetParams"}, + {0x00030080, nullptr, "TerminateProcesse"}, + {0x00040100, nullptr, "TerminateProcessTID"}, + {0x000500C0, nullptr, "TerminateProcessTID_unknown"}, + {0x00070042, nullptr, "GetFIRMLaunchParams"}, + {0x00080100, nullptr, "GetTitleExheaderFlags"}, + {0x00090042, nullptr, "SetFIRMLaunchParams"}, + {0x000A0140, nullptr, "SetResourceLimit"}, + {0x000B0140, nullptr, "GetResourceLimitMax"}, + {0x000C0080, nullptr, "UnregisterProcess"}, + {0x000D0240, nullptr, "LaunchTitleUpdate"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp index e2c17d93b..6e6b63329 100644 --- a/src/core/hle/service/ptm/ptm.cpp +++ b/src/core/hle/service/ptm/ptm.cpp @@ -3,7 +3,6 @@ // Refer to the license.txt file included. #include "common/logging/log.h" -#include "core/settings.h" #include "core/file_sys/file_backend.h" #include "core/hle/service/fs/archive.h" #include "core/hle/service/ptm/ptm.h" @@ -11,12 +10,13 @@ #include "core/hle/service/ptm/ptm_sysm.h" #include "core/hle/service/ptm/ptm_u.h" #include "core/hle/service/service.h" +#include "core/settings.h" namespace Service { namespace PTM { /// Values for the default gamecoin.dat file -static const GameCoin default_game_coin = { 0x4F00, 42, 0, 0, 0, 2014, 12, 29 }; +static const GameCoin default_game_coin = {0x4F00, 42, 0, 0, 0, 2014, 12, 29}; /// Id of the SharedExtData archive used by the PTM process static const std::vector<u8> ptm_shared_extdata_id = {0, 0, 0, 0, 0x0B, 0, 0, 0xF0, 0, 0, 0, 0}; @@ -51,7 +51,8 @@ void GetBatteryLevel(Service::Interface* self) { // it returns a valid result without implementing full functionality. cmd_buff[1] = RESULT_SUCCESS.raw; - cmd_buff[2] = static_cast<u32>(ChargeLevels::CompletelyFull); // Set to a completely full battery + cmd_buff[2] = + static_cast<u32>(ChargeLevels::CompletelyFull); // Set to a completely full battery LOG_WARNING(Service_PTM, "(STUBBED) called"); } @@ -94,7 +95,8 @@ void CheckNew3DS(Service::Interface* self) { const bool is_new_3ds = Settings::values.is_new_3ds; if (is_new_3ds) { - LOG_CRITICAL(Service_PTM, "The option 'is_new_3ds' is enabled as part of the 'System' settings. Citra does not fully support New 3DS emulation yet!"); + LOG_CRITICAL(Service_PTM, "The option 'is_new_3ds' is enabled as part of the 'System' " + "settings. Citra does not fully support New 3DS emulation yet!"); } cmd_buff[1] = RESULT_SUCCESS.raw; @@ -111,15 +113,19 @@ void Init() { shell_open = true; battery_is_charging = true; - // Open the SharedExtSaveData archive 0xF000000B and create the gamecoin.dat file if it doesn't exist + // Open the SharedExtSaveData archive 0xF000000B and create the gamecoin.dat file if it doesn't + // exist FileSys::Path archive_path(ptm_shared_extdata_id); - auto archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path); + auto archive_result = + Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path); // If the archive didn't exist, create the files inside if (archive_result.Code().description == ErrorDescription::FS_NotFormatted) { // Format the archive to create the directories - Service::FS::FormatArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, FileSys::ArchiveFormatInfo(), archive_path); + Service::FS::FormatArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, + FileSys::ArchiveFormatInfo(), archive_path); // Open it again to get a valid archive now that the folder exists - archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path); + archive_result = + Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path); ASSERT_MSG(archive_result.Succeeded(), "Could not open the PTM SharedExtSaveData archive!"); FileSys::Path gamecoin_path("gamecoin.dat"); @@ -127,18 +133,18 @@ void Init() { open_mode.write_flag.Assign(1); open_mode.create_flag.Assign(1); // Open the file and write the default gamecoin information - auto gamecoin_result = Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode); + auto gamecoin_result = + Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode); if (gamecoin_result.Succeeded()) { auto gamecoin = gamecoin_result.MoveFrom(); - gamecoin->backend->Write(0, sizeof(GameCoin), 1, reinterpret_cast<const u8*>(&default_game_coin)); + gamecoin->backend->Write(0, sizeof(GameCoin), 1, + reinterpret_cast<const u8*>(&default_game_coin)); gamecoin->backend->Close(); } } } -void Shutdown() { - -} +void Shutdown() {} } // namespace PTM } // namespace Service diff --git a/src/core/hle/service/ptm/ptm.h b/src/core/hle/service/ptm/ptm.h index 7ef8877c7..6e163a6f9 100644 --- a/src/core/hle/service/ptm/ptm.h +++ b/src/core/hle/service/ptm/ptm.h @@ -14,23 +14,24 @@ namespace PTM { /// Charge levels used by PTM functions enum class ChargeLevels : u32 { - CriticalBattery = 1, - LowBattery = 2, - HalfFull = 3, - MostlyFull = 4, - CompletelyFull = 5, + CriticalBattery = 1, + LowBattery = 2, + HalfFull = 3, + MostlyFull = 4, + CompletelyFull = 5, }; /** * Represents the gamecoin file structure in the SharedExtData archive - * More information in 3dbrew (http://www.3dbrew.org/wiki/Extdata#Shared_Extdata_0xf000000b_gamecoin.dat) + * More information in 3dbrew + * (http://www.3dbrew.org/wiki/Extdata#Shared_Extdata_0xf000000b_gamecoin.dat) */ struct GameCoin { - u32 magic; ///< Magic number: 0x4F00 - u16 total_coins; ///< Total Play Coins + u32 magic; ///< Magic number: 0x4F00 + u16 total_coins; ///< Total Play Coins u16 total_coins_on_date; ///< Total Play Coins obtained on the date stored below. - u32 step_count; ///< Total step count at the time a new Play Coin was obtained. - u32 last_step_count; ///< Step count for the day the last Play Coin was obtained + u32 step_count; ///< Total step count at the time a new Play Coin was obtained. + u32 last_step_count; ///< Step count for the day the last Play Coin was obtained u16 year; u8 month; u8 day; diff --git a/src/core/hle/service/ptm/ptm_play.cpp b/src/core/hle/service/ptm/ptm_play.cpp index ca5dd0403..2e0c6e1a3 100644 --- a/src/core/hle/service/ptm/ptm_play.cpp +++ b/src/core/hle/service/ptm/ptm_play.cpp @@ -8,10 +8,10 @@ namespace Service { namespace PTM { const Interface::FunctionInfo FunctionTable[] = { - {0x08070082, nullptr, "GetPlayHistory"}, - {0x08080000, nullptr, "GetPlayHistoryStart"}, - {0x08090000, nullptr, "GetPlayHistoryLength"}, - {0x080B0080, nullptr, "CalcPlayHistoryStart"}, + {0x08070082, nullptr, "GetPlayHistory"}, + {0x08080000, nullptr, "GetPlayHistoryStart"}, + {0x08090000, nullptr, "GetPlayHistoryLength"}, + {0x080B0080, nullptr, "CalcPlayHistoryStart"}, }; PTM_Play_Interface::PTM_Play_Interface() { diff --git a/src/core/hle/service/ptm/ptm_play.h b/src/core/hle/service/ptm/ptm_play.h index e5c3e04df..47f229581 100644 --- a/src/core/hle/service/ptm/ptm_play.h +++ b/src/core/hle/service/ptm/ptm_play.h @@ -13,9 +13,9 @@ class PTM_Play_Interface : public Service::Interface { public: PTM_Play_Interface(); -std::string GetPortName() const override { - return "ptm:play"; -} + std::string GetPortName() const override { + return "ptm:play"; + } }; } // namespace PTM diff --git a/src/core/hle/service/ptm/ptm_sysm.cpp b/src/core/hle/service/ptm/ptm_sysm.cpp index cc4ef1101..693158dbf 100644 --- a/src/core/hle/service/ptm/ptm_sysm.cpp +++ b/src/core/hle/service/ptm/ptm_sysm.cpp @@ -9,37 +9,37 @@ namespace Service { namespace PTM { const Interface::FunctionInfo FunctionTable[] = { - {0x040100C0, nullptr, "SetRtcAlarmEx"}, - {0x04020042, nullptr, "ReplySleepQuery"}, - {0x04030042, nullptr, "NotifySleepPreparationComplete"}, - {0x04040102, nullptr, "SetWakeupTrigger"}, - {0x04050000, nullptr, "GetAwakeReason"}, - {0x04060000, nullptr, "RequestSleep"}, - {0x040700C0, nullptr, "ShutdownAsync"}, - {0x04080000, nullptr, "Awake"}, - {0x04090080, nullptr, "RebootAsync"}, - {0x040A0000, CheckNew3DS, "CheckNew3DS"}, - {0x08010640, nullptr, "SetInfoLEDPattern"}, - {0x08020040, nullptr, "SetInfoLEDPatternHeader"}, - {0x08030000, nullptr, "GetInfoLEDStatus"}, - {0x08040040, nullptr, "SetBatteryEmptyLEDPattern"}, - {0x08050000, nullptr, "ClearStepHistory"}, - {0x080600C2, nullptr, "SetStepHistory"}, - {0x08070082, nullptr, "GetPlayHistory"}, - {0x08080000, nullptr, "GetPlayHistoryStart"}, - {0x08090000, nullptr, "GetPlayHistoryLength"}, - {0x080A0000, nullptr, "ClearPlayHistory"}, - {0x080B0080, nullptr, "CalcPlayHistoryStart"}, - {0x080C0080, nullptr, "SetUserTime"}, - {0x080D0000, nullptr, "InvalidateSystemTime"}, - {0x080E0140, nullptr, "NotifyPlayEvent"}, - {0x080F0000, IsLegacyPowerOff, "IsLegacyPowerOff"}, - {0x08100000, nullptr, "ClearLegacyPowerOff"}, - {0x08110000, GetShellState, "GetShellState"}, - {0x08120000, nullptr, "IsShutdownByBatteryEmpty"}, - {0x08130000, nullptr, "FormatSavedata"}, - {0x08140000, nullptr, "GetLegacyJumpProhibitedFlag"}, - {0x08180040, nullptr, "ConfigureNew3DSCPU"}, + {0x040100C0, nullptr, "SetRtcAlarmEx"}, + {0x04020042, nullptr, "ReplySleepQuery"}, + {0x04030042, nullptr, "NotifySleepPreparationComplete"}, + {0x04040102, nullptr, "SetWakeupTrigger"}, + {0x04050000, nullptr, "GetAwakeReason"}, + {0x04060000, nullptr, "RequestSleep"}, + {0x040700C0, nullptr, "ShutdownAsync"}, + {0x04080000, nullptr, "Awake"}, + {0x04090080, nullptr, "RebootAsync"}, + {0x040A0000, CheckNew3DS, "CheckNew3DS"}, + {0x08010640, nullptr, "SetInfoLEDPattern"}, + {0x08020040, nullptr, "SetInfoLEDPatternHeader"}, + {0x08030000, nullptr, "GetInfoLEDStatus"}, + {0x08040040, nullptr, "SetBatteryEmptyLEDPattern"}, + {0x08050000, nullptr, "ClearStepHistory"}, + {0x080600C2, nullptr, "SetStepHistory"}, + {0x08070082, nullptr, "GetPlayHistory"}, + {0x08080000, nullptr, "GetPlayHistoryStart"}, + {0x08090000, nullptr, "GetPlayHistoryLength"}, + {0x080A0000, nullptr, "ClearPlayHistory"}, + {0x080B0080, nullptr, "CalcPlayHistoryStart"}, + {0x080C0080, nullptr, "SetUserTime"}, + {0x080D0000, nullptr, "InvalidateSystemTime"}, + {0x080E0140, nullptr, "NotifyPlayEvent"}, + {0x080F0000, IsLegacyPowerOff, "IsLegacyPowerOff"}, + {0x08100000, nullptr, "ClearLegacyPowerOff"}, + {0x08110000, GetShellState, "GetShellState"}, + {0x08120000, nullptr, "IsShutdownByBatteryEmpty"}, + {0x08130000, nullptr, "FormatSavedata"}, + {0x08140000, nullptr, "GetLegacyJumpProhibitedFlag"}, + {0x08180040, nullptr, "ConfigureNew3DSCPU"}, }; PTM_Sysm_Interface::PTM_Sysm_Interface() { diff --git a/src/core/hle/service/ptm/ptm_u.cpp b/src/core/hle/service/ptm/ptm_u.cpp index 17e764866..65e868393 100644 --- a/src/core/hle/service/ptm/ptm_u.cpp +++ b/src/core/hle/service/ptm/ptm_u.cpp @@ -9,21 +9,21 @@ namespace Service { namespace PTM { const Interface::FunctionInfo FunctionTable[] = { - {0x00010002, nullptr, "RegisterAlarmClient"}, - {0x00020080, nullptr, "SetRtcAlarm"}, - {0x00030000, nullptr, "GetRtcAlarm"}, - {0x00040000, nullptr, "CancelRtcAlarm"}, - {0x00050000, GetAdapterState, "GetAdapterState"}, - {0x00060000, GetShellState, "GetShellState"}, - {0x00070000, GetBatteryLevel, "GetBatteryLevel"}, + {0x00010002, nullptr, "RegisterAlarmClient"}, + {0x00020080, nullptr, "SetRtcAlarm"}, + {0x00030000, nullptr, "GetRtcAlarm"}, + {0x00040000, nullptr, "CancelRtcAlarm"}, + {0x00050000, GetAdapterState, "GetAdapterState"}, + {0x00060000, GetShellState, "GetShellState"}, + {0x00070000, GetBatteryLevel, "GetBatteryLevel"}, {0x00080000, GetBatteryChargeState, "GetBatteryChargeState"}, - {0x00090000, nullptr, "GetPedometerState"}, - {0x000A0042, nullptr, "GetStepHistoryEntry"}, - {0x000B00C2, nullptr, "GetStepHistory"}, - {0x000C0000, GetTotalStepCount, "GetTotalStepCount"}, - {0x000D0040, nullptr, "SetPedometerRecordingMode"}, - {0x000E0000, nullptr, "GetPedometerRecordingMode"}, - {0x000F0084, nullptr, "GetStepHistoryAll"}, + {0x00090000, nullptr, "GetPedometerState"}, + {0x000A0042, nullptr, "GetStepHistoryEntry"}, + {0x000B00C2, nullptr, "GetStepHistory"}, + {0x000C0000, GetTotalStepCount, "GetTotalStepCount"}, + {0x000D0040, nullptr, "SetPedometerRecordingMode"}, + {0x000E0000, nullptr, "GetPedometerRecordingMode"}, + {0x000F0084, nullptr, "GetStepHistoryAll"}, }; PTM_U_Interface::PTM_U_Interface() { diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 5b8440b77..ca7eeac8a 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -4,42 +4,40 @@ #include "common/logging/log.h" #include "common/string_util.h" - -#include "core/hle/service/service.h" #include "core/hle/service/ac_u.h" #include "core/hle/service/act_a.h" #include "core/hle/service/act_u.h" -#include "core/hle/service/csnd_snd.h" -#include "core/hle/service/dsp_dsp.h" -#include "core/hle/service/err_f.h" -#include "core/hle/service/gsp_gpu.h" -#include "core/hle/service/gsp_lcd.h" -#include "core/hle/service/http_c.h" -#include "core/hle/service/mic_u.h" -#include "core/hle/service/ns_s.h" -#include "core/hle/service/nwm_uds.h" -#include "core/hle/service/pm_app.h" -#include "core/hle/service/soc_u.h" -#include "core/hle/service/srv.h" -#include "core/hle/service/ssl_c.h" -#include "core/hle/service/y2r_u.h" - #include "core/hle/service/am/am.h" #include "core/hle/service/apt/apt.h" #include "core/hle/service/boss/boss.h" #include "core/hle/service/cam/cam.h" #include "core/hle/service/cecd/cecd.h" +#include "core/hle/service/cfg/cfg.h" +#include "core/hle/service/csnd_snd.h" #include "core/hle/service/dlp/dlp.h" +#include "core/hle/service/dsp_dsp.h" +#include "core/hle/service/err_f.h" #include "core/hle/service/frd/frd.h" #include "core/hle/service/fs/archive.h" -#include "core/hle/service/cfg/cfg.h" +#include "core/hle/service/gsp_gpu.h" +#include "core/hle/service/gsp_lcd.h" #include "core/hle/service/hid/hid.h" +#include "core/hle/service/http_c.h" #include "core/hle/service/ir/ir.h" #include "core/hle/service/ldr_ro/ldr_ro.h" +#include "core/hle/service/mic_u.h" #include "core/hle/service/ndm/ndm.h" #include "core/hle/service/news/news.h" #include "core/hle/service/nim/nim.h" +#include "core/hle/service/ns_s.h" +#include "core/hle/service/nwm_uds.h" +#include "core/hle/service/pm_app.h" #include "core/hle/service/ptm/ptm.h" +#include "core/hle/service/service.h" +#include "core/hle/service/soc_u.h" +#include "core/hle/service/srv.h" +#include "core/hle/service/ssl_c.h" +#include "core/hle/service/y2r_u.h" namespace Service { @@ -50,11 +48,13 @@ std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_srv_services; * Creates a function string for logging, complete with the name (or header code, depending * on what's passed in) the port name, and all the cmd_buff arguments. */ -static std::string MakeFunctionString(const char* name, const char* port_name, const u32* cmd_buff) { +static std::string MakeFunctionString(const char* name, const char* port_name, + const u32* cmd_buff) { // Number of params == bits 0-5 + bits 6-11 int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F); - std::string function_string = Common::StringFromFormat("function '%s': port=%s", name, port_name); + std::string function_string = + Common::StringFromFormat("function '%s': port=%s", name, port_name); for (int i = 1; i <= num_params; ++i) { function_string += Common::StringFromFormat(", cmd_buff[%i]=0x%X", i, cmd_buff[i]); } @@ -66,14 +66,19 @@ ResultVal<bool> Interface::SyncRequest() { auto itr = m_functions.find(cmd_buff[0]); if (itr == m_functions.end() || itr->second.func == nullptr) { - std::string function_name = (itr == m_functions.end()) ? Common::StringFromFormat("0x%08X", cmd_buff[0]) : itr->second.name; - LOG_ERROR(Service, "unknown / unimplemented %s", MakeFunctionString(function_name.c_str(), GetPortName().c_str(), cmd_buff).c_str()); + std::string function_name = (itr == m_functions.end()) + ? Common::StringFromFormat("0x%08X", cmd_buff[0]) + : itr->second.name; + LOG_ERROR( + Service, "unknown / unimplemented %s", + MakeFunctionString(function_name.c_str(), GetPortName().c_str(), cmd_buff).c_str()); // TODO(bunnei): Hack - ignore error cmd_buff[1] = 0; return MakeResult<bool>(false); } - LOG_TRACE(Service, "%s", MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str()); + LOG_TRACE(Service, "%s", + MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str()); itr->second.func(this); @@ -163,6 +168,4 @@ void Shutdown() { g_kernel_named_ports.clear(); LOG_DEBUG(Service, "shutdown OK"); } - - } diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index f31135212..39b5ffaae 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -7,11 +7,8 @@ #include <cstddef> #include <string> #include <unordered_map> - #include <boost/container/flat_map.hpp> - #include "common/common_types.h" - #include "core/hle/kernel/session.h" #include "core/hle/result.h" @@ -28,13 +25,15 @@ class Interface : public Kernel::Session { // just something that encapsulates a session and acts as a helper to implement service // processes. public: - std::string GetName() const override { return GetPortName(); } + std::string GetName() const override { + return GetPortName(); + } typedef void (*Function)(Interface*); struct FunctionInfo { - u32 id; - Function func; + u32 id; + Function func; const char* name; }; @@ -49,7 +48,6 @@ public: ResultVal<bool> SyncRequest() override; protected: - /** * Registers the functions in the service */ @@ -62,7 +60,6 @@ protected: private: boost::container::flat_map<u32, FunctionInfo> m_functions; - }; /// Initialize ServiceManager diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp index 9b285567b..4279b67fb 100644 --- a/src/core/hle/service/soc_u.cpp +++ b/src/core/hle/service/soc_u.cpp @@ -6,53 +6,51 @@ #include <cstring> #include <unordered_map> #include <vector> - #include "common/assert.h" #include "common/bit_field.h" #include "common/common_types.h" #include "common/logging/log.h" #include "common/scope_exit.h" - #include "core/hle/kernel/session.h" #include "core/hle/result.h" #include "core/hle/service/soc_u.h" #include "core/memory.h" #ifdef _WIN32 - #include <winsock2.h> - #include <ws2tcpip.h> - - // MinGW does not define several errno constants - #ifndef _MSC_VER - #define EBADMSG 104 - #define ENODATA 120 - #define ENOMSG 122 - #define ENOSR 124 - #define ENOSTR 125 - #define ETIME 137 - #define EIDRM 2001 - #define ENOLINK 2002 - #endif // _MSC_VER +#include <winsock2.h> +#include <ws2tcpip.h> + +// MinGW does not define several errno constants +#ifndef _MSC_VER +#define EBADMSG 104 +#define ENODATA 120 +#define ENOMSG 122 +#define ENOSR 124 +#define ENOSTR 125 +#define ETIME 137 +#define EIDRM 2001 +#define ENOLINK 2002 +#endif // _MSC_VER #else - #include <cerrno> - #include <fcntl.h> - #include <netinet/in.h> - #include <netdb.h> - #include <poll.h> - #include <sys/socket.h> - #include <unistd.h> +#include <cerrno> +#include <fcntl.h> +#include <netdb.h> +#include <netinet/in.h> +#include <poll.h> +#include <sys/socket.h> +#include <unistd.h> #endif #ifdef _WIN32 -# define WSAEAGAIN WSAEWOULDBLOCK -# define WSAEMULTIHOP -1 // Invalid dummy value -# define ERRNO(x) WSA##x -# define GET_ERRNO WSAGetLastError() -# define poll(x, y, z) WSAPoll(x, y, z); +#define WSAEAGAIN WSAEWOULDBLOCK +#define WSAEMULTIHOP -1 // Invalid dummy value +#define ERRNO(x) WSA##x +#define GET_ERRNO WSAGetLastError() +#define poll(x, y, z) WSAPoll(x, y, z); #else -# define ERRNO(x) x -# define GET_ERRNO errno -# define closesocket(x) close(x) +#define ERRNO(x) x +#define GET_ERRNO errno +#define closesocket(x) close(x) #endif static const s32 SOCKET_ERROR_VALUE = -1; @@ -63,83 +61,83 @@ static const s32 SOCKET_ERROR_VALUE = -1; namespace SOC_U { /// Holds the translation from system network errors to 3DS network errors -static const std::unordered_map<int, int> error_map = { { - { E2BIG, 1 }, - { ERRNO(EACCES), 2 }, - { ERRNO(EADDRINUSE), 3 }, - { ERRNO(EADDRNOTAVAIL), 4 }, - { ERRNO(EAFNOSUPPORT), 5 }, - { ERRNO(EAGAIN), 6 }, - { ERRNO(EALREADY), 7 }, - { ERRNO(EBADF), 8 }, - { EBADMSG, 9 }, - { EBUSY, 10 }, - { ECANCELED, 11 }, - { ECHILD, 12 }, - { ERRNO(ECONNABORTED), 13 }, - { ERRNO(ECONNREFUSED), 14 }, - { ERRNO(ECONNRESET), 15 }, - { EDEADLK, 16 }, - { ERRNO(EDESTADDRREQ), 17 }, - { EDOM, 18 }, - { ERRNO(EDQUOT), 19 }, - { EEXIST, 20 }, - { ERRNO(EFAULT), 21 }, - { EFBIG, 22 }, - { ERRNO(EHOSTUNREACH), 23 }, - { EIDRM, 24 }, - { EILSEQ, 25 }, - { ERRNO(EINPROGRESS), 26 }, - { ERRNO(EINTR), 27 }, - { ERRNO(EINVAL), 28 }, - { EIO, 29 }, - { ERRNO(EISCONN), 30 }, - { EISDIR, 31 }, - { ERRNO(ELOOP), 32 }, - { ERRNO(EMFILE), 33 }, - { EMLINK, 34 }, - { ERRNO(EMSGSIZE), 35 }, - { ERRNO(EMULTIHOP), 36 }, - { ERRNO(ENAMETOOLONG), 37 }, - { ERRNO(ENETDOWN), 38 }, - { ERRNO(ENETRESET), 39 }, - { ERRNO(ENETUNREACH), 40 }, - { ENFILE, 41 }, - { ERRNO(ENOBUFS), 42 }, - { ENODATA, 43 }, - { ENODEV, 44 }, - { ENOENT, 45 }, - { ENOEXEC, 46 }, - { ENOLCK, 47 }, - { ENOLINK, 48 }, - { ENOMEM, 49 }, - { ENOMSG, 50 }, - { ERRNO(ENOPROTOOPT), 51 }, - { ENOSPC, 52 }, - { ENOSR, 53 }, - { ENOSTR, 54 }, - { ENOSYS, 55 }, - { ERRNO(ENOTCONN), 56 }, - { ENOTDIR, 57 }, - { ERRNO(ENOTEMPTY), 58 }, - { ERRNO(ENOTSOCK), 59 }, - { ENOTSUP, 60 }, - { ENOTTY, 61 }, - { ENXIO, 62 }, - { ERRNO(EOPNOTSUPP), 63 }, - { EOVERFLOW, 64 }, - { EPERM, 65 }, - { EPIPE, 66 }, - { EPROTO, 67 }, - { ERRNO(EPROTONOSUPPORT), 68 }, - { ERRNO(EPROTOTYPE), 69 }, - { ERANGE, 70 }, - { EROFS, 71 }, - { ESPIPE, 72 }, - { ESRCH, 73 }, - { ERRNO(ESTALE), 74 }, - { ETIME, 75 }, - { ERRNO(ETIMEDOUT), 76 } +static const std::unordered_map<int, int> error_map = {{ + {E2BIG, 1}, + {ERRNO(EACCES), 2}, + {ERRNO(EADDRINUSE), 3}, + {ERRNO(EADDRNOTAVAIL), 4}, + {ERRNO(EAFNOSUPPORT), 5}, + {ERRNO(EAGAIN), 6}, + {ERRNO(EALREADY), 7}, + {ERRNO(EBADF), 8}, + {EBADMSG, 9}, + {EBUSY, 10}, + {ECANCELED, 11}, + {ECHILD, 12}, + {ERRNO(ECONNABORTED), 13}, + {ERRNO(ECONNREFUSED), 14}, + {ERRNO(ECONNRESET), 15}, + {EDEADLK, 16}, + {ERRNO(EDESTADDRREQ), 17}, + {EDOM, 18}, + {ERRNO(EDQUOT), 19}, + {EEXIST, 20}, + {ERRNO(EFAULT), 21}, + {EFBIG, 22}, + {ERRNO(EHOSTUNREACH), 23}, + {EIDRM, 24}, + {EILSEQ, 25}, + {ERRNO(EINPROGRESS), 26}, + {ERRNO(EINTR), 27}, + {ERRNO(EINVAL), 28}, + {EIO, 29}, + {ERRNO(EISCONN), 30}, + {EISDIR, 31}, + {ERRNO(ELOOP), 32}, + {ERRNO(EMFILE), 33}, + {EMLINK, 34}, + {ERRNO(EMSGSIZE), 35}, + {ERRNO(EMULTIHOP), 36}, + {ERRNO(ENAMETOOLONG), 37}, + {ERRNO(ENETDOWN), 38}, + {ERRNO(ENETRESET), 39}, + {ERRNO(ENETUNREACH), 40}, + {ENFILE, 41}, + {ERRNO(ENOBUFS), 42}, + {ENODATA, 43}, + {ENODEV, 44}, + {ENOENT, 45}, + {ENOEXEC, 46}, + {ENOLCK, 47}, + {ENOLINK, 48}, + {ENOMEM, 49}, + {ENOMSG, 50}, + {ERRNO(ENOPROTOOPT), 51}, + {ENOSPC, 52}, + {ENOSR, 53}, + {ENOSTR, 54}, + {ENOSYS, 55}, + {ERRNO(ENOTCONN), 56}, + {ENOTDIR, 57}, + {ERRNO(ENOTEMPTY), 58}, + {ERRNO(ENOTSOCK), 59}, + {ENOTSUP, 60}, + {ENOTTY, 61}, + {ENXIO, 62}, + {ERRNO(EOPNOTSUPP), 63}, + {EOVERFLOW, 64}, + {EPERM, 65}, + {EPIPE, 66}, + {EPROTO, 67}, + {ERRNO(EPROTONOSUPPORT), 68}, + {ERRNO(EPROTOTYPE), 69}, + {ERANGE, 70}, + {EROFS, 71}, + {ESPIPE, 72}, + {ESRCH, 73}, + {ERRNO(ESTALE), 74}, + {ETIME, 75}, + {ERRNO(ETIMEDOUT), 76}, }}; /// Converts a network error from platform-specific to 3ds-specific @@ -153,21 +151,21 @@ static int TranslateError(int error) { /// Holds the translation from system network socket options to 3DS network socket options /// Note: -1 = No effect/unavailable -static const std::unordered_map<int, int> sockopt_map = { { - { 0x0004, SO_REUSEADDR }, - { 0x0080, -1 }, - { 0x0100, -1 }, - { 0x1001, SO_SNDBUF }, - { 0x1002, SO_RCVBUF }, - { 0x1003, -1 }, +static const std::unordered_map<int, int> sockopt_map = {{ + {0x0004, SO_REUSEADDR}, + {0x0080, -1}, + {0x0100, -1}, + {0x1001, SO_SNDBUF}, + {0x1002, SO_RCVBUF}, + {0x1003, -1}, #ifdef _WIN32 /// Unsupported in WinSock2 - { 0x1004, -1 }, + {0x1004, -1}, #else - { 0x1004, SO_RCVLOWAT }, + {0x1004, SO_RCVLOWAT}, #endif - { 0x1008, SO_TYPE }, - { 0x1009, SO_ERROR }, + {0x1008, SO_TYPE}, + {0x1009, SO_ERROR}, }}; /// Converts a socket option from 3ds-specific to platform-specific @@ -203,7 +201,8 @@ struct CTRPollFD { return *this; } - /// Translates the resulting events of a Poll operation from platform-specific to 3ds specific + /// Translates the resulting events of a Poll operation from platform-specific to 3ds + /// specific static Events TranslateTo3DS(u32 input_event) { Events ev = {}; if (input_event & POLLIN) @@ -221,7 +220,8 @@ struct CTRPollFD { return ev; } - /// Translates the resulting events of a Poll operation from 3ds specific to platform specific + /// Translates the resulting events of a Poll operation from 3ds specific to platform + /// specific static u32 TranslateToPlatform(Events input_event) { u32 ret = 0; if (input_event.pollin) @@ -239,7 +239,7 @@ struct CTRPollFD { return ret; } }; - Events events; ///< Events to poll for (input) + Events events; ///< Events to poll for (input) Events revents; ///< Events received (output) /// Converts a platform-specific pollfd to a 3ds specific structure @@ -265,17 +265,17 @@ struct CTRPollFD { union CTRSockAddr { /// Structure to represent a raw sockaddr struct { - u8 len; ///< The length of the entire structure, only the set fields count - u8 sa_family; ///< The address family of the sockaddr + u8 len; ///< The length of the entire structure, only the set fields count + u8 sa_family; ///< The address family of the sockaddr u8 sa_data[0x1A]; ///< The extra data, this varies, depending on the address family } raw; /// Structure to represent the 3ds' sockaddr_in structure struct CTRSockAddrIn { - u8 len; ///< The length of the entire structure + u8 len; ///< The length of the entire structure u8 sin_family; ///< The address family of the sockaddr_in - u16 sin_port; ///< The port associated with this sockaddr_in - u32 sin_addr; ///< The actual address of the sockaddr_in + u16 sin_port; ///< The port associated with this sockaddr_in + u32 sin_addr; ///< The actual address of the sockaddr_in } in; /// Convert a 3DS CTRSockAddr to a platform-specific sockaddr @@ -286,8 +286,7 @@ union CTRSockAddr { // We can not guarantee ABI compatibility between platforms so we copy the fields manually switch (result.sa_family) { - case AF_INET: - { + case AF_INET: { sockaddr_in* result_in = reinterpret_cast<sockaddr_in*>(&result); result_in->sin_port = ctr_addr.in.sin_port; result_in->sin_addr.s_addr = ctr_addr.in.sin_addr; @@ -307,8 +306,7 @@ union CTRSockAddr { result.raw.sa_family = static_cast<u8>(addr.sa_family); // We can not guarantee ABI compatibility between platforms so we copy the fields manually switch (result.raw.sa_family) { - case AF_INET: - { + case AF_INET: { sockaddr_in const* addr_in = reinterpret_cast<sockaddr_in const*>(&addr); result.raw.len = sizeof(CTRSockAddrIn); result.in.sin_port = addr_in->sin_port; @@ -341,24 +339,27 @@ static void Socket(Service::Interface* self) { // Only 0 is allowed according to 3dbrew, using 0 will let the OS decide which protocol to use if (protocol != 0) { - cmd_buffer[1] = UnimplementedFunction(ErrorModule::SOC).raw; // TODO(Subv): Correct error code + cmd_buffer[1] = + UnimplementedFunction(ErrorModule::SOC).raw; // TODO(Subv): Correct error code return; } if (domain != AF_INET) { - cmd_buffer[1] = UnimplementedFunction(ErrorModule::SOC).raw; // TODO(Subv): Correct error code + cmd_buffer[1] = + UnimplementedFunction(ErrorModule::SOC).raw; // TODO(Subv): Correct error code return; } if (type != SOCK_DGRAM && type != SOCK_STREAM) { - cmd_buffer[1] = UnimplementedFunction(ErrorModule::SOC).raw; // TODO(Subv): Correct error code + cmd_buffer[1] = + UnimplementedFunction(ErrorModule::SOC).raw; // TODO(Subv): Correct error code return; } u32 socket_handle = static_cast<u32>(::socket(domain, type, protocol)); if ((s32)socket_handle != SOCKET_ERROR_VALUE) - open_sockets[socket_handle] = { socket_handle, true }; + open_sockets[socket_handle] = {socket_handle, true}; int result = 0; if ((s32)socket_handle == SOCKET_ERROR_VALUE) @@ -406,8 +407,8 @@ static void Fcntl(Service::Interface* self) { int result = 0; u32 posix_ret = 0; // TODO: Check what hardware returns for F_SETFL (unspecified by POSIX) SCOPE_EXIT({ - cmd_buffer[1] = result; - cmd_buffer[2] = posix_ret; + cmd_buffer[1] = result; + cmd_buffer[2] = posix_ret; }); if (ctr_cmd == 3) { // F_GETFL @@ -493,7 +494,7 @@ static void Accept(Service::Interface* self) { u32 ret = static_cast<u32>(::accept(socket_handle, &addr, &addr_len)); if ((s32)ret != SOCKET_ERROR_VALUE) - open_sockets[ret] = { ret, true }; + open_sockets[ret] = {ret, true}; int result = 0; if ((s32)ret == SOCKET_ERROR_VALUE) { @@ -573,9 +574,11 @@ static void SendTo(Service::Interface* self) { int ret = -1; if (addr_len > 0) { sockaddr dest_addr = CTRSockAddr::ToPlatform(ctr_dest_addr); - ret = ::sendto(socket_handle, reinterpret_cast<const char*>(input_buff.data()), len, flags, &dest_addr, sizeof(dest_addr)); + ret = ::sendto(socket_handle, reinterpret_cast<const char*>(input_buff.data()), len, flags, + &dest_addr, sizeof(dest_addr)); } else { - ret = ::sendto(socket_handle, reinterpret_cast<const char*>(input_buff.data()), len, flags, nullptr, 0); + ret = ::sendto(socket_handle, reinterpret_cast<const char*>(input_buff.data()), len, flags, + nullptr, 0); } int result = 0; @@ -596,8 +599,7 @@ static void RecvFrom(Service::Interface* self) { u32 flags = cmd_buffer[3]; socklen_t addr_len = static_cast<socklen_t>(cmd_buffer[4]); - struct - { + struct { u32 output_buffer_descriptor; u32 output_buffer_addr; u32 address_buffer_descriptor; @@ -619,11 +621,13 @@ static void RecvFrom(Service::Interface* self) { std::vector<u8> output_buff(len); sockaddr src_addr; socklen_t src_addr_len = sizeof(src_addr); - int ret = ::recvfrom(socket_handle, reinterpret_cast<char*>(output_buff.data()), len, flags, &src_addr, &src_addr_len); + int ret = ::recvfrom(socket_handle, reinterpret_cast<char*>(output_buff.data()), len, flags, + &src_addr, &src_addr_len); if (ret >= 0 && buffer_parameters.output_src_address_buffer != 0 && src_addr_len > 0) { CTRSockAddr ctr_src_addr = CTRSockAddr::FromPlatform(src_addr); - Memory::WriteBlock(buffer_parameters.output_src_address_buffer, &ctr_src_addr, sizeof(ctr_src_addr)); + Memory::WriteBlock(buffer_parameters.output_src_address_buffer, &ctr_src_addr, + sizeof(ctr_src_addr)); } int result = 0; @@ -633,7 +637,8 @@ static void RecvFrom(Service::Interface* self) { total_received = 0; } else { // Write only the data we received to avoid overwriting parts of the buffer with zeros - Memory::WriteBlock(buffer_parameters.output_buffer_addr, output_buff.data(), total_received); + Memory::WriteBlock(buffer_parameters.output_buffer_addr, output_buff.data(), + total_received); } cmd_buffer[1] = result; @@ -648,7 +653,8 @@ static void Poll(Service::Interface* self) { VAddr input_fds_addr = cmd_buffer[6]; VAddr output_fds_addr = cmd_buffer[0x104 >> 2]; - if (!Memory::IsValidVirtualAddress(input_fds_addr) || !Memory::IsValidVirtualAddress(output_fds_addr)) { + if (!Memory::IsValidVirtualAddress(input_fds_addr) || + !Memory::IsValidVirtualAddress(output_fds_addr)) { cmd_buffer[1] = -1; // TODO(Subv): Find correct error code. return; } @@ -656,7 +662,8 @@ static void Poll(Service::Interface* self) { std::vector<CTRPollFD> ctr_fds(nfds); Memory::ReadBlock(input_fds_addr, ctr_fds.data(), nfds * sizeof(CTRPollFD)); - // The 3ds_pollfd and the pollfd structures may be different (Windows/Linux have different sizes) + // The 3ds_pollfd and the pollfd structures may be different (Windows/Linux have different + // sizes) // so we have to copy the data std::vector<pollfd> platform_pollfd(nfds); std::transform(ctr_fds.begin(), ctr_fds.end(), platform_pollfd.begin(), CTRPollFD::ToPlatform); @@ -664,7 +671,8 @@ static void Poll(Service::Interface* self) { const int ret = ::poll(platform_pollfd.data(), nfds, timeout); // Now update the output pollfd structure - std::transform(platform_pollfd.begin(), platform_pollfd.end(), ctr_fds.begin(), CTRPollFD::FromPlatform); + std::transform(platform_pollfd.begin(), platform_pollfd.end(), ctr_fds.begin(), + CTRPollFD::FromPlatform); Memory::WriteBlock(output_fds_addr, ctr_fds.data(), nfds * sizeof(CTRPollFD)); @@ -775,7 +783,7 @@ static void Connect(Service::Interface* self) { } static void InitializeSockets(Service::Interface* self) { - // TODO(Subv): Implement +// TODO(Subv): Implement #ifdef _WIN32 WSADATA data; WSAStartup(MAKEWORD(2, 2), &data); @@ -808,7 +816,7 @@ static void GetSockOpt(Service::Interface* self) { int ret = -1; int err = 0; - if(optname < 0) { + if (optname < 0) { #ifdef _WIN32 err = WSAEINVAL; #else @@ -818,7 +826,7 @@ static void GetSockOpt(Service::Interface* self) { // 0x100 = static buffer offset (bytes) // + 0x4 = 2nd pointer (u32) position // >> 2 = convert to u32 offset instead of byte offset (cmd_buffer = u32*) - char* optval = reinterpret_cast<char *>(Memory::GetPointer(cmd_buffer[0x104 >> 2])); + char* optval = reinterpret_cast<char*>(Memory::GetPointer(cmd_buffer[0x104 >> 2])); ret = ::getsockopt(socket_handle, level, optname, optval, &optlen); err = 0; @@ -842,7 +850,7 @@ static void SetSockOpt(Service::Interface* self) { int ret = -1; int err = 0; - if(optname < 0) { + if (optname < 0) { #ifdef _WIN32 err = WSAEINVAL; #else @@ -850,7 +858,7 @@ static void SetSockOpt(Service::Interface* self) { #endif } else { socklen_t optlen = static_cast<socklen_t>(cmd_buffer[4]); - const char* optval = reinterpret_cast<const char *>(Memory::GetPointer(cmd_buffer[8])); + const char* optval = reinterpret_cast<const char*>(Memory::GetPointer(cmd_buffer[8])); ret = static_cast<u32>(::setsockopt(socket_handle, level, optname, optval, optlen)); err = 0; @@ -865,39 +873,39 @@ static void SetSockOpt(Service::Interface* self) { } const Interface::FunctionInfo FunctionTable[] = { - {0x00010044, InitializeSockets, "InitializeSockets"}, - {0x000200C2, Socket, "Socket"}, - {0x00030082, Listen, "Listen"}, - {0x00040082, Accept, "Accept"}, - {0x00050084, Bind, "Bind"}, - {0x00060084, Connect, "Connect"}, - {0x00070104, nullptr, "recvfrom_other"}, - {0x00080102, RecvFrom, "RecvFrom"}, - {0x00090106, nullptr, "sendto_other"}, - {0x000A0106, SendTo, "SendTo"}, - {0x000B0042, Close, "Close"}, - {0x000C0082, Shutdown, "Shutdown"}, - {0x000D0082, nullptr, "GetHostByName"}, - {0x000E00C2, nullptr, "GetHostByAddr"}, - {0x000F0106, nullptr, "GetAddrInfo"}, - {0x00100102, nullptr, "GetNameInfo"}, - {0x00110102, GetSockOpt, "GetSockOpt"}, - {0x00120104, SetSockOpt, "SetSockOpt"}, - {0x001300C2, Fcntl, "Fcntl"}, - {0x00140084, Poll, "Poll"}, - {0x00150042, nullptr, "SockAtMark"}, - {0x00160000, GetHostId, "GetHostId"}, - {0x00170082, GetSockName, "GetSockName"}, - {0x00180082, GetPeerName, "GetPeerName"}, - {0x00190000, ShutdownSockets, "ShutdownSockets"}, - {0x001A00C0, nullptr, "GetNetworkOpt"}, - {0x001B0040, nullptr, "ICMPSocket"}, - {0x001C0104, nullptr, "ICMPPing"}, - {0x001D0040, nullptr, "ICMPCancel"}, - {0x001E0040, nullptr, "ICMPClose"}, - {0x001F0040, nullptr, "GetResolverInfo"}, - {0x00210002, nullptr, "CloseSockets"}, - {0x00230040, nullptr, "AddGlobalSocket"}, + {0x00010044, InitializeSockets, "InitializeSockets"}, + {0x000200C2, Socket, "Socket"}, + {0x00030082, Listen, "Listen"}, + {0x00040082, Accept, "Accept"}, + {0x00050084, Bind, "Bind"}, + {0x00060084, Connect, "Connect"}, + {0x00070104, nullptr, "recvfrom_other"}, + {0x00080102, RecvFrom, "RecvFrom"}, + {0x00090106, nullptr, "sendto_other"}, + {0x000A0106, SendTo, "SendTo"}, + {0x000B0042, Close, "Close"}, + {0x000C0082, Shutdown, "Shutdown"}, + {0x000D0082, nullptr, "GetHostByName"}, + {0x000E00C2, nullptr, "GetHostByAddr"}, + {0x000F0106, nullptr, "GetAddrInfo"}, + {0x00100102, nullptr, "GetNameInfo"}, + {0x00110102, GetSockOpt, "GetSockOpt"}, + {0x00120104, SetSockOpt, "SetSockOpt"}, + {0x001300C2, Fcntl, "Fcntl"}, + {0x00140084, Poll, "Poll"}, + {0x00150042, nullptr, "SockAtMark"}, + {0x00160000, GetHostId, "GetHostId"}, + {0x00170082, GetSockName, "GetSockName"}, + {0x00180082, GetPeerName, "GetPeerName"}, + {0x00190000, ShutdownSockets, "ShutdownSockets"}, + {0x001A00C0, nullptr, "GetNetworkOpt"}, + {0x001B0040, nullptr, "ICMPSocket"}, + {0x001C0104, nullptr, "ICMPPing"}, + {0x001D0040, nullptr, "ICMPCancel"}, + {0x001E0040, nullptr, "ICMPClose"}, + {0x001F0040, nullptr, "GetResolverInfo"}, + {0x00210002, nullptr, "CloseSockets"}, + {0x00230040, nullptr, "AddGlobalSocket"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/soc_u.h b/src/core/hle/service/soc_u.h index a091f597c..8d02ed30f 100644 --- a/src/core/hle/service/soc_u.h +++ b/src/core/hle/service/soc_u.h @@ -5,7 +5,6 @@ #pragma once #include <string> - #include "core/hle/service/service.h" //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp index 3c05f836b..b25be413a 100644 --- a/src/core/hle/service/srv.cpp +++ b/src/core/hle/service/srv.cpp @@ -4,9 +4,8 @@ #include "common/common_types.h" #include "common/logging/log.h" - -#include "core/hle/service/srv.h" #include "core/hle/kernel/event.h" +#include "core/hle/service/srv.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // Namespace SRV @@ -28,13 +27,14 @@ static void RegisterClient(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); if (cmd_buff[1] != IPC::CallingPidDesc()) { - cmd_buff[0] = IPC::MakeHeader(0x0, 0x1, 0); //0x40 + cmd_buff[0] = IPC::MakeHeader(0x0, 0x1, 0); // 0x40 cmd_buff[1] = ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS, - ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw; + ErrorSummary::WrongArgument, ErrorLevel::Permanent) + .raw; return; } - cmd_buff[0] = IPC::MakeHeader(0x1, 0x1, 0); //0x10040 - cmd_buff[1] = RESULT_SUCCESS.raw; // No error + cmd_buff[0] = IPC::MakeHeader(0x1, 0x1, 0); // 0x10040 + cmd_buff[1] = RESULT_SUCCESS.raw; // No error LOG_WARNING(Service_SRV, "(STUBBED) called"); } @@ -56,7 +56,7 @@ static void EnableNotification(Service::Interface* self) { event_handle->Clear(); cmd_buff[0] = IPC::MakeHeader(0x2, 0x1, 0x2); // 0x20042 - cmd_buff[1] = RESULT_SUCCESS.raw; // No error + cmd_buff[1] = RESULT_SUCCESS.raw; // No error cmd_buff[2] = IPC::CopyHandleDesc(1); cmd_buff[3] = Kernel::g_handle_table.Create(event_handle).MoveFrom(); LOG_WARNING(Service_SRV, "(STUBBED) called"); @@ -105,7 +105,7 @@ static void Subscribe(Service::Interface* self) { u32 notification_id = cmd_buff[1]; cmd_buff[0] = IPC::MakeHeader(0x9, 0x1, 0); // 0x90040 - cmd_buff[1] = RESULT_SUCCESS.raw; // No error + cmd_buff[1] = RESULT_SUCCESS.raw; // No error LOG_WARNING(Service_SRV, "(STUBBED) called, notification_id=0x%X", notification_id); } @@ -124,7 +124,7 @@ static void Unsubscribe(Service::Interface* self) { u32 notification_id = cmd_buff[1]; cmd_buff[0] = IPC::MakeHeader(0xA, 0x1, 0); // 0xA0040 - cmd_buff[1] = RESULT_SUCCESS.raw; // No error + cmd_buff[1] = RESULT_SUCCESS.raw; // No error LOG_WARNING(Service_SRV, "(STUBBED) called, notification_id=0x%X", notification_id); } @@ -145,25 +145,26 @@ static void PublishToSubscriber(Service::Interface* self) { u8 flags = cmd_buff[2] & 0xFF; cmd_buff[0] = IPC::MakeHeader(0xC, 0x1, 0); // 0xC0040 - cmd_buff[1] = RESULT_SUCCESS.raw; // No error - LOG_WARNING(Service_SRV, "(STUBBED) called, notification_id=0x%X, flags=%u", notification_id, flags); + cmd_buff[1] = RESULT_SUCCESS.raw; // No error + LOG_WARNING(Service_SRV, "(STUBBED) called, notification_id=0x%X, flags=%u", notification_id, + flags); } const Interface::FunctionInfo FunctionTable[] = { - {0x00010002, RegisterClient, "RegisterClient"}, - {0x00020000, EnableNotification, "EnableNotification"}, - {0x00030100, nullptr, "RegisterService"}, - {0x000400C0, nullptr, "UnregisterService"}, - {0x00050100, GetServiceHandle, "GetServiceHandle"}, - {0x000600C2, nullptr, "RegisterPort"}, - {0x000700C0, nullptr, "UnregisterPort"}, - {0x00080100, nullptr, "GetPort"}, - {0x00090040, Subscribe, "Subscribe"}, - {0x000A0040, Unsubscribe, "Unsubscribe"}, - {0x000B0000, nullptr, "ReceiveNotification"}, - {0x000C0080, PublishToSubscriber, "PublishToSubscriber"}, - {0x000D0040, nullptr, "PublishAndGetSubscriber"}, - {0x000E00C0, nullptr, "IsServiceRegistered"}, + {0x00010002, RegisterClient, "RegisterClient"}, + {0x00020000, EnableNotification, "EnableNotification"}, + {0x00030100, nullptr, "RegisterService"}, + {0x000400C0, nullptr, "UnregisterService"}, + {0x00050100, GetServiceHandle, "GetServiceHandle"}, + {0x000600C2, nullptr, "RegisterPort"}, + {0x000700C0, nullptr, "UnregisterPort"}, + {0x00080100, nullptr, "GetPort"}, + {0x00090040, Subscribe, "Subscribe"}, + {0x000A0040, Unsubscribe, "Unsubscribe"}, + {0x000B0000, nullptr, "ReceiveNotification"}, + {0x000C0080, PublishToSubscriber, "PublishToSubscriber"}, + {0x000D0040, nullptr, "PublishAndGetSubscriber"}, + {0x000E00C0, nullptr, "IsServiceRegistered"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/ssl_c.cpp b/src/core/hle/service/ssl_c.cpp index a8aff1abf..abab1d271 100644 --- a/src/core/hle/service/ssl_c.cpp +++ b/src/core/hle/service/ssl_c.cpp @@ -3,7 +3,6 @@ // Refer to the license.txt file included. #include <random> - #include "common/common_types.h" #include "core/hle/service/ssl_c.h" @@ -37,7 +36,8 @@ static void GenerateRandomData(Service::Interface* self) { u32 i = 0; while (i < size) { if ((i % 4) == 0) { - // The random number generator returns 4 bytes worth of data, so generate new random data when i == 0 and when i is divisible by 4 + // The random number generator returns 4 bytes worth of data, so generate new random + // data when i == 0 and when i is divisible by 4 data = rand_gen(); } @@ -59,26 +59,26 @@ static void GenerateRandomData(Service::Interface* self) { } const Interface::FunctionInfo FunctionTable[] = { - {0x00010002, Initialize, "Initialize"}, - {0x000200C2, nullptr, "CreateContext"}, - {0x00030000, nullptr, "CreateRootCertChain"}, - {0x00040040, nullptr, "DestroyRootCertChain"}, - {0x00050082, nullptr, "AddTrustedRootCA"}, - {0x00060080, nullptr, "RootCertChainAddDefaultCert"}, - {0x00070080, nullptr, "RootCertChainRemoveCert"}, - {0x000E0040, nullptr, "OpenDefaultClientCertContext"}, - {0x000F0040, nullptr, "CloseClientCertContext"}, - {0x00110042, GenerateRandomData, "GenerateRandomData"}, - {0x00120042, nullptr, "InitializeConnectionSession"}, - {0x00130040, nullptr, "StartConnection"}, - {0x00140040, nullptr, "StartConnectionGetOut"}, - {0x00150082, nullptr, "Read"}, - {0x00170082, nullptr, "Write"}, - {0x00180080, nullptr, "ContextSetRootCertChain"}, - {0x00190080, nullptr, "ContextSetClientCert"}, - {0x001B0080, nullptr, "ContextClearOpt"}, - {0x001E0040, nullptr, "DestroyContext"}, - {0x001F0082, nullptr, "ContextInitSharedmem"} + {0x00010002, Initialize, "Initialize"}, + {0x000200C2, nullptr, "CreateContext"}, + {0x00030000, nullptr, "CreateRootCertChain"}, + {0x00040040, nullptr, "DestroyRootCertChain"}, + {0x00050082, nullptr, "AddTrustedRootCA"}, + {0x00060080, nullptr, "RootCertChainAddDefaultCert"}, + {0x00070080, nullptr, "RootCertChainRemoveCert"}, + {0x000E0040, nullptr, "OpenDefaultClientCertContext"}, + {0x000F0040, nullptr, "CloseClientCertContext"}, + {0x00110042, GenerateRandomData, "GenerateRandomData"}, + {0x00120042, nullptr, "InitializeConnectionSession"}, + {0x00130040, nullptr, "StartConnection"}, + {0x00140040, nullptr, "StartConnectionGetOut"}, + {0x00150082, nullptr, "Read"}, + {0x00170082, nullptr, "Write"}, + {0x00180080, nullptr, "ContextSetRootCertChain"}, + {0x00190080, nullptr, "ContextSetClientCert"}, + {0x001B0080, nullptr, "ContextClearOpt"}, + {0x001E0040, nullptr, "DestroyContext"}, + {0x001F0082, nullptr, "ContextInitSharedmem"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index d16578f87..097e09d28 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp @@ -3,11 +3,9 @@ // Refer to the license.txt file included. #include <cstring> - #include "common/common_funcs.h" #include "common/common_types.h" #include "common/logging/log.h" - #include "core/hle/kernel/event.h" #include "core/hle/kernel/kernel.h" #include "core/hle/service/y2r_u.h" @@ -39,16 +37,16 @@ static u32 transfer_end_interrupt_enabled = 0; static u32 spacial_dithering_enabled = 0; static const CoefficientSet standard_coefficients[4] = { - {{ 0x100, 0x166, 0xB6, 0x58, 0x1C5, -0x166F, 0x10EE, -0x1C5B }}, // ITU_Rec601 - {{ 0x100, 0x193, 0x77, 0x2F, 0x1DB, -0x1933, 0xA7C, -0x1D51 }}, // ITU_Rec709 - {{ 0x12A, 0x198, 0xD0, 0x64, 0x204, -0x1BDE, 0x10F2, -0x229B }}, // ITU_Rec601_Scaling - {{ 0x12A, 0x1CA, 0x88, 0x36, 0x21C, -0x1F04, 0x99C, -0x2421 }}, // ITU_Rec709_Scaling + {{0x100, 0x166, 0xB6, 0x58, 0x1C5, -0x166F, 0x10EE, -0x1C5B}}, // ITU_Rec601 + {{0x100, 0x193, 0x77, 0x2F, 0x1DB, -0x1933, 0xA7C, -0x1D51}}, // ITU_Rec709 + {{0x12A, 0x198, 0xD0, 0x64, 0x204, -0x1BDE, 0x10F2, -0x229B}}, // ITU_Rec601_Scaling + {{0x12A, 0x1CA, 0x88, 0x36, 0x21C, -0x1F04, 0x99C, -0x2421}}, // ITU_Rec709_Scaling }; ResultCode ConversionConfiguration::SetInputLineWidth(u16 width) { if (width == 0 || width > 1024 || width % 8 != 0) { return ResultCode(ErrorDescription::OutOfRange, ErrorModule::CAM, - ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E053FD + ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E053FD } // Note: The hardware uses the register value 0 to represent a width of 1024, so for a width of @@ -61,7 +59,7 @@ ResultCode ConversionConfiguration::SetInputLineWidth(u16 width) { ResultCode ConversionConfiguration::SetInputLines(u16 lines) { if (lines == 0 || lines > 1024) { return ResultCode(ErrorDescription::OutOfRange, ErrorModule::CAM, - ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E053FD + ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E053FD } // Note: In what appears to be a bug, the `camera` module does not set the hardware register at @@ -73,11 +71,12 @@ ResultCode ConversionConfiguration::SetInputLines(u16 lines) { return RESULT_SUCCESS; } -ResultCode ConversionConfiguration::SetStandardCoefficient(StandardCoefficient standard_coefficient) { +ResultCode ConversionConfiguration::SetStandardCoefficient( + StandardCoefficient standard_coefficient) { size_t index = static_cast<size_t>(standard_coefficient); if (index >= ARRAY_SIZE(standard_coefficients)) { return ResultCode(ErrorDescription::InvalidEnumValue, ErrorModule::CAM, - ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E053ED + ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E053ED } std::memcpy(coefficients.data(), standard_coefficients[index].data(), sizeof(coefficients)); @@ -294,8 +293,10 @@ static void SetSendingY(Service::Interface* self) { cmd_buff[0] = IPC::MakeHeader(0x10, 1, 0); cmd_buff[1] = RESULT_SUCCESS.raw; - LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, src_process_handle=0x%08X", - conversion.src_Y.image_size, conversion.src_Y.transfer_unit, conversion.src_Y.gap, cmd_buff[6]); + LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, " + "src_process_handle=0x%08X", + conversion.src_Y.image_size, conversion.src_Y.transfer_unit, conversion.src_Y.gap, + cmd_buff[6]); } static void SetSendingU(Service::Interface* self) { @@ -309,8 +310,10 @@ static void SetSendingU(Service::Interface* self) { cmd_buff[0] = IPC::MakeHeader(0x11, 1, 0); cmd_buff[1] = RESULT_SUCCESS.raw; - LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, src_process_handle=0x%08X", - conversion.src_U.image_size, conversion.src_U.transfer_unit, conversion.src_U.gap, cmd_buff[6]); + LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, " + "src_process_handle=0x%08X", + conversion.src_U.image_size, conversion.src_U.transfer_unit, conversion.src_U.gap, + cmd_buff[6]); } static void SetSendingV(Service::Interface* self) { @@ -324,8 +327,10 @@ static void SetSendingV(Service::Interface* self) { cmd_buff[0] = IPC::MakeHeader(0x12, 1, 0); cmd_buff[1] = RESULT_SUCCESS.raw; - LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, src_process_handle=0x%08X", - conversion.src_V.image_size, conversion.src_V.transfer_unit, conversion.src_V.gap, cmd_buff[6]); + LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, " + "src_process_handle=0x%08X", + conversion.src_V.image_size, conversion.src_V.transfer_unit, conversion.src_V.gap, + cmd_buff[6]); } static void SetSendingYUYV(Service::Interface* self) { @@ -339,8 +344,10 @@ static void SetSendingYUYV(Service::Interface* self) { cmd_buff[0] = IPC::MakeHeader(0x13, 1, 0); cmd_buff[1] = RESULT_SUCCESS.raw; - LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, src_process_handle=0x%08X", - conversion.src_YUYV.image_size, conversion.src_YUYV.transfer_unit, conversion.src_YUYV.gap, cmd_buff[6]); + LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, " + "src_process_handle=0x%08X", + conversion.src_YUYV.image_size, conversion.src_YUYV.transfer_unit, + conversion.src_YUYV.gap, cmd_buff[6]); } /** @@ -418,8 +425,10 @@ static void SetReceiving(Service::Interface* self) { cmd_buff[0] = IPC::MakeHeader(0x18, 1, 0); cmd_buff[1] = RESULT_SUCCESS.raw; - LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, dst_process_handle=0x%08X", - conversion.dst.image_size, conversion.dst.transfer_unit, conversion.dst.gap, cmd_buff[6]); + LOG_DEBUG(Service_Y2R, "called image_size=0x%08X, transfer_unit=%hu, transfer_stride=%hu, " + "dst_process_handle=0x%08X", + conversion.dst.image_size, conversion.dst.transfer_unit, conversion.dst.gap, + cmd_buff[6]); } /** @@ -486,8 +495,8 @@ static void SetCoefficient(Service::Interface* self) { cmd_buff[1] = RESULT_SUCCESS.raw; LOG_DEBUG(Service_Y2R, "called coefficients=[%hX, %hX, %hX, %hX, %hX, %hX, %hX, %hX]", - coefficients[0], coefficients[1], coefficients[2], coefficients[3], - coefficients[4], coefficients[5], coefficients[6], coefficients[7]); + coefficients[0], coefficients[1], coefficients[2], coefficients[3], coefficients[4], + coefficients[5], coefficients[6], coefficients[7]); } static void GetCoefficient(Service::Interface* self) { @@ -575,8 +584,10 @@ static void StartConversion(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); // dst_image_size would seem to be perfect for this, but it doesn't include the gap :( - u32 total_output_size = conversion.input_lines * (conversion.dst.transfer_unit + conversion.dst.gap); - Memory::RasterizerFlushAndInvalidateRegion(Memory::VirtualToPhysicalAddress(conversion.dst.address), total_output_size); + u32 total_output_size = + conversion.input_lines * (conversion.dst.transfer_unit + conversion.dst.gap); + Memory::RasterizerFlushAndInvalidateRegion( + Memory::VirtualToPhysicalAddress(conversion.dst.address), total_output_size); HW::Y2R::PerformConversion(conversion); @@ -648,10 +659,13 @@ cleanup: cmd_buff[0] = IPC::MakeHeader(0x29, 1, 0); cmd_buff[1] = result.raw; - LOG_DEBUG(Service_Y2R, "called input_format=%hhu output_format=%hhu rotation=%hhu block_alignment=%hhu " - "input_line_width=%hu input_lines=%hu standard_coefficient=%hhu reserved=%hhu alpha=%hX", - params->input_format, params->output_format, params->rotation, params->block_alignment, - params->input_line_width, params->input_lines, params->standard_coefficient, params->padding, params->alpha); + LOG_DEBUG( + Service_Y2R, + "called input_format=%hhu output_format=%hhu rotation=%hhu block_alignment=%hhu " + "input_line_width=%hu input_lines=%hu standard_coefficient=%hhu reserved=%hhu alpha=%hX", + params->input_format, params->output_format, params->rotation, params->block_alignment, + params->input_line_width, params->input_lines, params->standard_coefficient, + params->padding, params->alpha); } static void PingProcess(Service::Interface* self) { @@ -699,7 +713,6 @@ static void DriverFinalize(Service::Interface* self) { LOG_DEBUG(Service_Y2R, "called"); } - static void GetPackageParameter(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); @@ -711,51 +724,51 @@ static void GetPackageParameter(Service::Interface* self) { } const Interface::FunctionInfo FunctionTable[] = { - {0x00010040, SetInputFormat, "SetInputFormat"}, - {0x00020000, GetInputFormat, "GetInputFormat"}, - {0x00030040, SetOutputFormat, "SetOutputFormat"}, - {0x00040000, GetOutputFormat, "GetOutputFormat"}, - {0x00050040, SetRotation, "SetRotation"}, - {0x00060000, GetRotation, "GetRotation"}, - {0x00070040, SetBlockAlignment, "SetBlockAlignment"}, - {0x00080000, GetBlockAlignment, "GetBlockAlignment"}, - {0x00090040, SetSpacialDithering, "SetSpacialDithering"}, - {0x000A0000, GetSpacialDithering, "GetSpacialDithering"}, - {0x000B0040, SetTemporalDithering, "SetTemporalDithering"}, - {0x000C0000, GetTemporalDithering, "GetTemporalDithering"}, + {0x00010040, SetInputFormat, "SetInputFormat"}, + {0x00020000, GetInputFormat, "GetInputFormat"}, + {0x00030040, SetOutputFormat, "SetOutputFormat"}, + {0x00040000, GetOutputFormat, "GetOutputFormat"}, + {0x00050040, SetRotation, "SetRotation"}, + {0x00060000, GetRotation, "GetRotation"}, + {0x00070040, SetBlockAlignment, "SetBlockAlignment"}, + {0x00080000, GetBlockAlignment, "GetBlockAlignment"}, + {0x00090040, SetSpacialDithering, "SetSpacialDithering"}, + {0x000A0000, GetSpacialDithering, "GetSpacialDithering"}, + {0x000B0040, SetTemporalDithering, "SetTemporalDithering"}, + {0x000C0000, GetTemporalDithering, "GetTemporalDithering"}, {0x000D0040, SetTransferEndInterrupt, "SetTransferEndInterrupt"}, {0x000E0000, GetTransferEndInterrupt, "GetTransferEndInterrupt"}, - {0x000F0000, GetTransferEndEvent, "GetTransferEndEvent"}, - {0x00100102, SetSendingY, "SetSendingY"}, - {0x00110102, SetSendingU, "SetSendingU"}, - {0x00120102, SetSendingV, "SetSendingV"}, - {0x00130102, SetSendingYUYV, "SetSendingYUYV"}, - {0x00140000, IsFinishedSendingYuv, "IsFinishedSendingYuv"}, - {0x00150000, IsFinishedSendingY, "IsFinishedSendingY"}, - {0x00160000, IsFinishedSendingU, "IsFinishedSendingU"}, - {0x00170000, IsFinishedSendingV, "IsFinishedSendingV"}, - {0x00180102, SetReceiving, "SetReceiving"}, - {0x00190000, IsFinishedReceiving, "IsFinishedReceiving"}, - {0x001A0040, SetInputLineWidth, "SetInputLineWidth"}, - {0x001B0000, GetInputLineWidth, "GetInputLineWidth"}, - {0x001C0040, SetInputLines, "SetInputLines"}, - {0x001D0000, GetInputLines, "GetInputLines"}, - {0x001E0100, SetCoefficient, "SetCoefficient"}, - {0x001F0000, GetCoefficient, "GetCoefficient"}, - {0x00200040, SetStandardCoefficient, "SetStandardCoefficient"}, - {0x00210040, GetStandardCoefficient, "GetStandardCoefficient"}, - {0x00220040, SetAlpha, "SetAlpha"}, - {0x00230000, GetAlpha, "GetAlpha"}, - {0x00240200, SetDitheringWeightParams,"SetDitheringWeightParams"}, - {0x00250000, GetDitheringWeightParams,"GetDitheringWeightParams"}, - {0x00260000, StartConversion, "StartConversion"}, - {0x00270000, StopConversion, "StopConversion"}, - {0x00280000, IsBusyConversion, "IsBusyConversion"}, - {0x002901C0, SetPackageParameter, "SetPackageParameter"}, - {0x002A0000, PingProcess, "PingProcess"}, - {0x002B0000, DriverInitialize, "DriverInitialize"}, - {0x002C0000, DriverFinalize, "DriverFinalize"}, - {0x002D0000, GetPackageParameter, "GetPackageParameter"}, + {0x000F0000, GetTransferEndEvent, "GetTransferEndEvent"}, + {0x00100102, SetSendingY, "SetSendingY"}, + {0x00110102, SetSendingU, "SetSendingU"}, + {0x00120102, SetSendingV, "SetSendingV"}, + {0x00130102, SetSendingYUYV, "SetSendingYUYV"}, + {0x00140000, IsFinishedSendingYuv, "IsFinishedSendingYuv"}, + {0x00150000, IsFinishedSendingY, "IsFinishedSendingY"}, + {0x00160000, IsFinishedSendingU, "IsFinishedSendingU"}, + {0x00170000, IsFinishedSendingV, "IsFinishedSendingV"}, + {0x00180102, SetReceiving, "SetReceiving"}, + {0x00190000, IsFinishedReceiving, "IsFinishedReceiving"}, + {0x001A0040, SetInputLineWidth, "SetInputLineWidth"}, + {0x001B0000, GetInputLineWidth, "GetInputLineWidth"}, + {0x001C0040, SetInputLines, "SetInputLines"}, + {0x001D0000, GetInputLines, "GetInputLines"}, + {0x001E0100, SetCoefficient, "SetCoefficient"}, + {0x001F0000, GetCoefficient, "GetCoefficient"}, + {0x00200040, SetStandardCoefficient, "SetStandardCoefficient"}, + {0x00210040, GetStandardCoefficient, "GetStandardCoefficient"}, + {0x00220040, SetAlpha, "SetAlpha"}, + {0x00230000, GetAlpha, "GetAlpha"}, + {0x00240200, SetDitheringWeightParams, "SetDitheringWeightParams"}, + {0x00250000, GetDitheringWeightParams, "GetDitheringWeightParams"}, + {0x00260000, StartConversion, "StartConversion"}, + {0x00270000, StopConversion, "StopConversion"}, + {0x00280000, IsBusyConversion, "IsBusyConversion"}, + {0x002901C0, SetPackageParameter, "SetPackageParameter"}, + {0x002A0000, PingProcess, "PingProcess"}, + {0x002B0000, DriverInitialize, "DriverInitialize"}, + {0x002C0000, DriverFinalize, "DriverFinalize"}, + {0x002D0000, GetPackageParameter, "GetPackageParameter"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/y2r_u.h b/src/core/hle/service/y2r_u.h index 95fa2fdb7..1b47b5322 100644 --- a/src/core/hle/service/y2r_u.h +++ b/src/core/hle/service/y2r_u.h @@ -6,9 +6,7 @@ #include <array> #include <string> - #include "common/common_types.h" - #include "core/hle/result.h" #include "core/hle/service/service.h" diff --git a/src/core/hle/shared_page.cpp b/src/core/hle/shared_page.cpp index 4d9272923..d0d92487d 100644 --- a/src/core/hle/shared_page.cpp +++ b/src/core/hle/shared_page.cpp @@ -5,7 +5,6 @@ #include <chrono> #include <cstring> #include <ctime> - #include "core/core_timing.h" #include "core/hle/shared_page.h" @@ -52,8 +51,8 @@ static u64 GetSystemTime() { } static void UpdateTimeCallback(u64 userdata, int cycles_late) { - DateTime& date_time = shared_page.date_time_counter % 2 ? - shared_page.date_time_0 : shared_page.date_time_1; + DateTime& date_time = + shared_page.date_time_counter % 2 ? shared_page.date_time_0 : shared_page.date_time_1; date_time.date_time = GetSystemTime(); date_time.update_tick = CoreTiming::GetTicks(); @@ -74,7 +73,8 @@ void Init() { // Some games wait until this value becomes 0x1, before asking running_hw shared_page.unknown_value = 0x1; - update_time_event = CoreTiming::RegisterEvent("SharedPage::UpdateTimeCallback", UpdateTimeCallback); + update_time_event = + CoreTiming::RegisterEvent("SharedPage::UpdateTimeCallback", UpdateTimeCallback); CoreTiming::ScheduleEvent(0, update_time_event); } diff --git a/src/core/hle/shared_page.h b/src/core/hle/shared_page.h index cd9246726..106e47efc 100644 --- a/src/core/hle/shared_page.h +++ b/src/core/hle/shared_page.h @@ -13,7 +13,6 @@ #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" - #include "core/memory.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -32,27 +31,28 @@ static_assert(sizeof(DateTime) == 0x20, "Datetime size is wrong"); struct SharedPageDef { // Most of these names are taken from the 3dbrew page linked above. - u32_le date_time_counter; // 0 - u8 running_hw; // 4 + u32_le date_time_counter; // 0 + u8 running_hw; // 4 /// "Microcontroller hardware info" - u8 mcu_hw_info; // 5 + u8 mcu_hw_info; // 5 INSERT_PADDING_BYTES(0x20 - 0x6); // 6 DateTime date_time_0; // 20 DateTime date_time_1; // 40 - u8 wifi_macaddr[6]; // 60 - u8 wifi_link_level; // 66 - u8 wifi_unknown2; // 67 + u8 wifi_macaddr[6]; // 60 + u8 wifi_link_level; // 66 + u8 wifi_unknown2; // 67 INSERT_PADDING_BYTES(0x80 - 0x68); // 68 float_le sliderstate_3d; // 80 - u8 ledstate_3d; // 84 + u8 ledstate_3d; // 84 INSERT_PADDING_BYTES(1); // 85 - u8 unknown_value; // 86 + u8 unknown_value; // 86 INSERT_PADDING_BYTES(0xA0 - 0x87); // 87 - u64_le menu_title_id; // A0 - u64_le active_menu_title_id; // A8 + u64_le menu_title_id; // A0 + u64_le active_menu_title_id; // A8 INSERT_PADDING_BYTES(0x1000 - 0xB0); // B0 }; -static_assert(sizeof(SharedPageDef) == Memory::SHARED_PAGE_SIZE, "Shared page structure size is wrong"); +static_assert(sizeof(SharedPageDef) == Memory::SHARED_PAGE_SIZE, + "Shared page structure size is wrong"); extern SharedPageDef shared_page; diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 5d71d5619..02b397eba 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp @@ -3,16 +3,14 @@ // Refer to the license.txt file included. #include <map> - #include "common/logging/log.h" #include "common/microprofile.h" #include "common/scope_exit.h" #include "common/string_util.h" #include "common/symbols.h" - -#include "core/core_timing.h" #include "core/arm/arm_interface.h" - +#include "core/core_timing.h" +#include "core/hle/function_wrappers.h" #include "core/hle/kernel/address_arbiter.h" #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/event.h" @@ -26,8 +24,6 @@ #include "core/hle/kernel/thread.h" #include "core/hle/kernel/timer.h" #include "core/hle/kernel/vm_manager.h" - -#include "core/hle/function_wrappers.h" #include "core/hle/result.h" #include "core/hle/service/service.h" @@ -40,43 +36,46 @@ using Kernel::ERR_INVALID_HANDLE; namespace SVC { const ResultCode ERR_NOT_FOUND(ErrorDescription::NotFound, ErrorModule::Kernel, - ErrorSummary::NotFound, ErrorLevel::Permanent); // 0xD88007FA + ErrorSummary::NotFound, ErrorLevel::Permanent); // 0xD88007FA const ResultCode ERR_PORT_NAME_TOO_LONG(ErrorDescription(30), ErrorModule::OS, - ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E0181E - -const ResultCode ERR_MISALIGNED_ADDRESS{ // 0xE0E01BF1 - ErrorDescription::MisalignedAddress, ErrorModule::OS, - ErrorSummary::InvalidArgument, ErrorLevel::Usage}; -const ResultCode ERR_MISALIGNED_SIZE{ // 0xE0E01BF2 - ErrorDescription::MisalignedSize, ErrorModule::OS, - ErrorSummary::InvalidArgument, ErrorLevel::Usage}; -const ResultCode ERR_INVALID_COMBINATION{ // 0xE0E01BEE - ErrorDescription::InvalidCombination, ErrorModule::OS, - ErrorSummary::InvalidArgument, ErrorLevel::Usage}; + ErrorSummary::InvalidArgument, + ErrorLevel::Usage); // 0xE0E0181E + +const ResultCode ERR_MISALIGNED_ADDRESS{// 0xE0E01BF1 + ErrorDescription::MisalignedAddress, ErrorModule::OS, + ErrorSummary::InvalidArgument, ErrorLevel::Usage}; +const ResultCode ERR_MISALIGNED_SIZE{// 0xE0E01BF2 + ErrorDescription::MisalignedSize, ErrorModule::OS, + ErrorSummary::InvalidArgument, ErrorLevel::Usage}; +const ResultCode ERR_INVALID_COMBINATION{// 0xE0E01BEE + ErrorDescription::InvalidCombination, ErrorModule::OS, + ErrorSummary::InvalidArgument, ErrorLevel::Usage}; enum ControlMemoryOperation { - MEMOP_FREE = 1, + MEMOP_FREE = 1, MEMOP_RESERVE = 2, // This operation seems to be unsupported in the kernel - MEMOP_COMMIT = 3, - MEMOP_MAP = 4, - MEMOP_UNMAP = 5, + MEMOP_COMMIT = 3, + MEMOP_MAP = 4, + MEMOP_UNMAP = 5, MEMOP_PROTECT = 6, MEMOP_OPERATION_MASK = 0xFF, - MEMOP_REGION_APP = 0x100, + MEMOP_REGION_APP = 0x100, MEMOP_REGION_SYSTEM = 0x200, - MEMOP_REGION_BASE = 0x300, - MEMOP_REGION_MASK = 0xF00, + MEMOP_REGION_BASE = 0x300, + MEMOP_REGION_MASK = 0xF00, MEMOP_LINEAR = 0x10000, }; /// Map application or GSP heap memory -static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 addr1, u32 size, u32 permissions) { +static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 addr1, u32 size, + u32 permissions) { using namespace Kernel; - LOG_DEBUG(Kernel_SVC,"called operation=0x%08X, addr0=0x%08X, addr1=0x%08X, size=0x%X, permissions=0x%08X", - operation, addr0, addr1, size, permissions); + LOG_DEBUG(Kernel_SVC, + "called operation=0x%08X, addr0=0x%08X, addr1=0x%08X, size=0x%X, permissions=0x%08X", + operation, addr0, addr1, size, permissions); if ((addr0 & Memory::PAGE_MASK) != 0 || (addr1 & Memory::PAGE_MASK) != 0) { return ERR_MISALIGNED_ADDRESS; @@ -89,7 +88,8 @@ static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 add operation &= ~MEMOP_REGION_MASK; if (region != 0) { - LOG_WARNING(Kernel_SVC, "ControlMemory with specified region not supported, region=%X", region); + LOG_WARNING(Kernel_SVC, "ControlMemory with specified region not supported, region=%X", + region); } if ((permissions & (u32)MemoryPermission::ReadWrite) != permissions) { @@ -100,15 +100,17 @@ static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 add auto& process = *g_current_process; switch (operation & MEMOP_OPERATION_MASK) { - case MEMOP_FREE: - { - // TODO(Subv): What happens if an application tries to FREE a block of memory that has a SharedMemory pointing to it? + case MEMOP_FREE: { + // TODO(Subv): What happens if an application tries to FREE a block of memory that has a + // SharedMemory pointing to it? if (addr0 >= Memory::HEAP_VADDR && addr0 < Memory::HEAP_VADDR_END) { ResultCode result = process.HeapFree(addr0, size); - if (result.IsError()) return result; + if (result.IsError()) + return result; } else if (addr0 >= process.GetLinearHeapBase() && addr0 < process.GetLinearHeapLimit()) { ResultCode result = process.LinearFree(addr0, size); - if (result.IsError()) return result; + if (result.IsError()) + return result; } else { return ERR_INVALID_ADDRESS; } @@ -116,8 +118,7 @@ static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 add break; } - case MEMOP_COMMIT: - { + case MEMOP_COMMIT: { if (operation & MEMOP_LINEAR) { CASCADE_RESULT(*out_addr, process.LinearAllocate(addr0, size, vma_permissions)); } else { @@ -126,23 +127,26 @@ static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 add break; } - case MEMOP_MAP: // TODO: This is just a hack to avoid regressions until memory aliasing is implemented - { - CASCADE_RESULT(*out_addr, process.HeapAllocate(addr0, size, vma_permissions)); - break; - } + case MEMOP_MAP: // TODO: This is just a hack to avoid regressions until memory aliasing is + // implemented + { + CASCADE_RESULT(*out_addr, process.HeapAllocate(addr0, size, vma_permissions)); + break; + } - case MEMOP_UNMAP: // TODO: This is just a hack to avoid regressions until memory aliasing is implemented - { - ResultCode result = process.HeapFree(addr0, size); - if (result.IsError()) return result; - break; - } + case MEMOP_UNMAP: // TODO: This is just a hack to avoid regressions until memory aliasing is + // implemented + { + ResultCode result = process.HeapFree(addr0, size); + if (result.IsError()) + return result; + break; + } - case MEMOP_PROTECT: - { + case MEMOP_PROTECT: { ResultCode result = process.vm_manager.ReprotectRange(addr0, size, vma_permissions); - if (result.IsError()) return result; + if (result.IsError()) + return result; break; } @@ -161,8 +165,9 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o using Kernel::SharedMemory; using Kernel::MemoryPermission; - LOG_TRACE(Kernel_SVC, "called memblock=0x%08X, addr=0x%08X, mypermissions=0x%08X, otherpermission=%d", - handle, addr, permissions, other_permissions); + LOG_TRACE(Kernel_SVC, + "called memblock=0x%08X, addr=0x%08X, mypermissions=0x%08X, otherpermission=%d", + handle, addr, permissions, other_permissions); SharedPtr<SharedMemory> shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle); if (shared_memory == nullptr) @@ -179,12 +184,13 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o case MemoryPermission::ReadWriteExecute: case MemoryPermission::DontCare: return shared_memory->Map(Kernel::g_current_process.get(), addr, permissions_type, - static_cast<MemoryPermission>(other_permissions)); + static_cast<MemoryPermission>(other_permissions)); default: LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions); } - return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); + return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::OS, + ErrorSummary::InvalidArgument, ErrorLevel::Usage); } static ResultCode UnmapMemoryBlock(Handle handle, u32 addr) { @@ -249,7 +255,7 @@ static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) { return ERR_INVALID_HANDLE; LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s:%s), nanoseconds=%lld", handle, - object->GetTypeName().c_str(), object->GetName().c_str(), nano_seconds); + object->GetTypeName().c_str(), object->GetName().c_str(), nano_seconds); HLE::Reschedule(__func__); @@ -257,7 +263,7 @@ static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) { if (object->ShouldWait()) { object->AddWaitingThread(thread); - Kernel::WaitCurrentThread_WaitSynchronization({ object }, false, false); + Kernel::WaitCurrentThread_WaitSynchronization({object}, false, false); // Create an event to wake the thread up after the specified nanosecond delay has passed thread->WakeAfterDelay(nano_seconds); @@ -272,7 +278,8 @@ static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) { } /// Wait for the given handles to synchronize, timeout after the specified nanoseconds -static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, bool wait_all, s64 nano_seconds) { +static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, bool wait_all, + s64 nano_seconds) { bool wait_thread = !wait_all; int handle_index = 0; Kernel::Thread* thread = Kernel::GetCurrentThread(); @@ -281,7 +288,8 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou // Check if 'handles' is invalid if (handles == nullptr) - return ResultCode(ErrorDescription::InvalidPointer, ErrorModule::Kernel, ErrorSummary::InvalidArgument, ErrorLevel::Permanent); + return ResultCode(ErrorDescription::InvalidPointer, ErrorModule::Kernel, + ErrorSummary::InvalidArgument, ErrorLevel::Permanent); // NOTE: on real hardware, there is no nullptr check for 'out' (tested with firmware 4.4). If // this happens, the running application will crash. @@ -289,7 +297,8 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou // Check if 'handle_count' is invalid if (handle_count < 0) - return ResultCode(ErrorDescription::OutOfRange, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); + return ResultCode(ErrorDescription::OutOfRange, ErrorModule::OS, + ErrorSummary::InvalidArgument, ErrorLevel::Usage); // If 'handle_count' is non-zero, iterate through each handle and wait the current thread if // necessary @@ -329,7 +338,9 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou } } - SCOPE_EXIT({HLE::Reschedule("WaitSynchronizationN");}); // Reschedule after putting the threads to sleep. + SCOPE_EXIT({ + HLE::Reschedule("WaitSynchronizationN"); + }); // Reschedule after putting the threads to sleep. // If thread should wait, then set its state to waiting if (wait_thread) { @@ -386,18 +397,19 @@ static ResultCode CreateAddressArbiter(Handle* out_handle) { } /// Arbitrate address -static ResultCode ArbitrateAddress(Handle handle, u32 address, u32 type, u32 value, s64 nanoseconds) { +static ResultCode ArbitrateAddress(Handle handle, u32 address, u32 type, u32 value, + s64 nanoseconds) { using Kernel::AddressArbiter; LOG_TRACE(Kernel_SVC, "called handle=0x%08X, address=0x%08X, type=0x%08X, value=0x%08X", handle, - address, type, value); + address, type, value); SharedPtr<AddressArbiter> arbiter = Kernel::g_handle_table.Get<AddressArbiter>(handle); if (arbiter == nullptr) return ERR_INVALID_HANDLE; - auto res = arbiter->ArbitrateAddress(static_cast<Kernel::ArbitrationType>(type), - address, value, nanoseconds); + auto res = arbiter->ArbitrateAddress(static_cast<Kernel::ArbitrationType>(type), address, value, + nanoseconds); return res; } @@ -406,10 +418,18 @@ static void Break(u8 break_reason) { LOG_CRITICAL(Debug_Emulated, "Emulated program broke execution!"); std::string reason_str; switch (break_reason) { - case 0: reason_str = "PANIC"; break; - case 1: reason_str = "ASSERT"; break; - case 2: reason_str = "USER"; break; - default: reason_str = "UNKNOWN"; break; + case 0: + reason_str = "PANIC"; + break; + case 1: + reason_str = "ASSERT"; + break; + case 2: + reason_str = "USER"; + break; + default: + reason_str = "UNKNOWN"; + break; } LOG_CRITICAL(Debug_Emulated, "Break reason: %s", reason_str.c_str()); } @@ -423,7 +443,8 @@ static void OutputDebugString(const char* string) { static ResultCode GetResourceLimit(Handle* resource_limit, Handle process_handle) { LOG_TRACE(Kernel_SVC, "called process=0x%08X", process_handle); - SharedPtr<Kernel::Process> process = Kernel::g_handle_table.Get<Kernel::Process>(process_handle); + SharedPtr<Kernel::Process> process = + Kernel::g_handle_table.Get<Kernel::Process>(process_handle); if (process == nullptr) return ERR_INVALID_HANDLE; @@ -433,12 +454,13 @@ static ResultCode GetResourceLimit(Handle* resource_limit, Handle process_handle } /// Get resource limit current values -static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_limit_handle, u32* names, - u32 name_count) { +static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_limit_handle, + u32* names, u32 name_count) { LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d", - resource_limit_handle, names, name_count); + resource_limit_handle, names, name_count); - SharedPtr<Kernel::ResourceLimit> resource_limit = Kernel::g_handle_table.Get<Kernel::ResourceLimit>(resource_limit_handle); + SharedPtr<Kernel::ResourceLimit> resource_limit = + Kernel::g_handle_table.Get<Kernel::ResourceLimit>(resource_limit_handle); if (resource_limit == nullptr) return ERR_INVALID_HANDLE; @@ -450,11 +472,12 @@ static ResultCode GetResourceLimitCurrentValues(s64* values, Handle resource_lim /// Get resource limit max values static ResultCode GetResourceLimitLimitValues(s64* values, Handle resource_limit_handle, u32* names, - u32 name_count) { + u32 name_count) { LOG_TRACE(Kernel_SVC, "called resource_limit=%08X, names=%p, name_count=%d", - resource_limit_handle, names, name_count); + resource_limit_handle, names, name_count); - SharedPtr<Kernel::ResourceLimit> resource_limit = Kernel::g_handle_table.Get<Kernel::ResourceLimit>(resource_limit_handle); + SharedPtr<Kernel::ResourceLimit> resource_limit = + Kernel::g_handle_table.Get<Kernel::ResourceLimit>(resource_limit_handle); if (resource_limit == nullptr) return ERR_INVALID_HANDLE; @@ -465,7 +488,8 @@ static ResultCode GetResourceLimitLimitValues(s64* values, Handle resource_limit } /// Creates a new thread -static ResultCode CreateThread(Handle* out_handle, s32 priority, u32 entry_point, u32 arg, u32 stack_top, s32 processor_id) { +static ResultCode CreateThread(Handle* out_handle, s32 priority, u32 entry_point, u32 arg, + u32 stack_top, s32 processor_id) { using Kernel::Thread; std::string name; @@ -499,20 +523,23 @@ static ResultCode CreateThread(Handle* out_handle, s32 priority, u32 entry_point } if (processor_id == THREADPROCESSORID_1 || processor_id == THREADPROCESSORID_ALL || - (processor_id == THREADPROCESSORID_DEFAULT && Kernel::g_current_process->ideal_processor == THREADPROCESSORID_1)) { - LOG_WARNING(Kernel_SVC, "Newly created thread is allowed to be run in the SysCore, unimplemented."); + (processor_id == THREADPROCESSORID_DEFAULT && + Kernel::g_current_process->ideal_processor == THREADPROCESSORID_1)) { + LOG_WARNING(Kernel_SVC, + "Newly created thread is allowed to be run in the SysCore, unimplemented."); } - CASCADE_RESULT(SharedPtr<Thread> thread, Kernel::Thread::Create( - name, entry_point, priority, arg, processor_id, stack_top)); + CASCADE_RESULT(SharedPtr<Thread> thread, Kernel::Thread::Create(name, entry_point, priority, + arg, processor_id, stack_top)); - thread->context.fpscr = FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO; // 0x03C00000 + thread->context.fpscr = + FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO; // 0x03C00000 CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(thread))); LOG_TRACE(Kernel_SVC, "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, " - "threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X", entry_point, - name.c_str(), arg, stack_top, priority, processor_id, *out_handle); + "threadpriority=0x%08X, processorid=0x%08X : created handle=0x%08X", + entry_point, name.c_str(), arg, stack_top, priority, processor_id, *out_handle); return RESULT_SUCCESS; } @@ -552,7 +579,7 @@ static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) { CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(mutex))); LOG_TRACE(Kernel_SVC, "called initial_locked=%s : created handle=0x%08X", - initial_locked ? "true" : "false", *out_handle); + initial_locked ? "true" : "false", *out_handle); return RESULT_SUCCESS; } @@ -576,7 +603,8 @@ static ResultCode ReleaseMutex(Handle handle) { static ResultCode GetProcessId(u32* process_id, Handle process_handle) { LOG_TRACE(Kernel_SVC, "called process=0x%08X", process_handle); - const SharedPtr<Kernel::Process> process = Kernel::g_handle_table.Get<Kernel::Process>(process_handle); + const SharedPtr<Kernel::Process> process = + Kernel::g_handle_table.Get<Kernel::Process>(process_handle); if (process == nullptr) return ERR_INVALID_HANDLE; @@ -588,7 +616,8 @@ static ResultCode GetProcessId(u32* process_id, Handle process_handle) { static ResultCode GetProcessIdOfThread(u32* process_id, Handle thread_handle) { LOG_TRACE(Kernel_SVC, "called thread=0x%08X", thread_handle); - const SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(thread_handle); + const SharedPtr<Kernel::Thread> thread = + Kernel::g_handle_table.Get<Kernel::Thread>(thread_handle); if (thread == nullptr) return ERR_INVALID_HANDLE; @@ -620,7 +649,7 @@ static ResultCode CreateSemaphore(Handle* out_handle, s32 initial_count, s32 max CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(semaphore))); LOG_TRACE(Kernel_SVC, "called initial_count=%d, max_count=%d, created handle=0x%08X", - initial_count, max_count, *out_handle); + initial_count, max_count, *out_handle); return RESULT_SUCCESS; } @@ -640,7 +669,8 @@ static ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) } /// Query process memory -static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* page_info, Handle process_handle, u32 addr) { +static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* page_info, + Handle process_handle, u32 addr) { using Kernel::Process; Kernel::SharedPtr<Process> process = Kernel::g_handle_table.Get<Process>(process_handle); if (process == nullptr) @@ -649,7 +679,8 @@ static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* page_inf auto vma = process->vm_manager.FindVMA(addr); if (vma == Kernel::g_current_process->vm_manager.vma_map.end()) - return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); + return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::OS, + ErrorSummary::InvalidArgument, ErrorLevel::Usage); memory_info->base_address = vma->second.base; memory_info->permission = static_cast<u32>(vma->second.permissions); @@ -673,8 +704,8 @@ static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) { SharedPtr<Event> evt = Event::Create(static_cast<Kernel::ResetType>(reset_type)); CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(evt))); - LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", - reset_type, *out_handle); + LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", reset_type, + *out_handle); return RESULT_SUCCESS; } @@ -719,8 +750,8 @@ static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) { SharedPtr<Timer> timer = Timer::Create(static_cast<Kernel::ResetType>(reset_type)); CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(timer))); - LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", - reset_type, *out_handle); + LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", reset_type, + *out_handle); return RESULT_SUCCESS; } @@ -783,17 +814,19 @@ static void SleepThread(s64 nanoseconds) { static s64 GetSystemTick() { s64 result = CoreTiming::GetTicks(); // Advance time to defeat dumb games (like Cubic Ninja) that busy-wait for the frame to end. - Core::g_app_core->AddTicks(150); // Measured time between two calls on a 9.2 o3DS with Ninjhax 1.1b + Core::g_app_core->AddTicks( + 150); // Measured time between two calls on a 9.2 o3DS with Ninjhax 1.1b return result; } /// Creates a memory block at the specified address with the specified permissions and size static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 my_permission, - u32 other_permission) { + u32 other_permission) { using Kernel::SharedMemory; if (size % Memory::PAGE_SIZE != 0) - return ResultCode(ErrorDescription::MisalignedSize, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); + return ResultCode(ErrorDescription::MisalignedSize, ErrorModule::OS, + ErrorSummary::InvalidArgument, ErrorLevel::Usage); SharedPtr<SharedMemory> shared_memory = nullptr; @@ -818,25 +851,29 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 ErrorSummary::InvalidArgument, ErrorLevel::Usage); if (addr < Memory::PROCESS_IMAGE_VADDR || addr + size > Memory::SHARED_MEMORY_VADDR_END) { - return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::OS, ErrorSummary::InvalidArgument, ErrorLevel::Usage); + return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::OS, + ErrorSummary::InvalidArgument, ErrorLevel::Usage); } // When trying to create a memory block with address = 0, // if the process has the Shared Device Memory flag in the exheader, - // then we have to allocate from the same region as the caller process instead of the BASE region. + // then we have to allocate from the same region as the caller process instead of the BASE + // region. Kernel::MemoryRegion region = Kernel::MemoryRegion::BASE; if (addr == 0 && Kernel::g_current_process->flags.shared_device_mem) region = Kernel::g_current_process->flags.memory_region; - shared_memory = SharedMemory::Create(Kernel::g_current_process, size, - static_cast<MemoryPermission>(my_permission), static_cast<MemoryPermission>(other_permission), addr, region); + shared_memory = SharedMemory::Create( + Kernel::g_current_process, size, static_cast<MemoryPermission>(my_permission), + static_cast<MemoryPermission>(other_permission), addr, region); CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(shared_memory))); LOG_WARNING(Kernel_SVC, "called addr=0x%08X", addr); return RESULT_SUCCESS; } -static ResultCode CreatePort(Handle* server_port, Handle* client_port, const char* name, u32 max_sessions) { +static ResultCode CreatePort(Handle* server_port, Handle* client_port, const char* name, + u32 max_sessions) { // TODO(Subv): Implement named ports. ASSERT_MSG(name == nullptr, "Named ports are currently unimplemented"); @@ -845,9 +882,12 @@ static ResultCode CreatePort(Handle* server_port, Handle* client_port, const cha using Kernel::SharedPtr; auto ports = ServerPort::CreatePortPair(max_sessions); - CASCADE_RESULT(*client_port, Kernel::g_handle_table.Create(std::move(std::get<SharedPtr<ClientPort>>(ports)))); - // Note: The 3DS kernel also leaks the client port handle if the server port handle fails to be created. - CASCADE_RESULT(*server_port, Kernel::g_handle_table.Create(std::move(std::get<SharedPtr<ServerPort>>(ports)))); + CASCADE_RESULT(*client_port, Kernel::g_handle_table.Create( + std::move(std::get<SharedPtr<ClientPort>>(ports)))); + // Note: The 3DS kernel also leaks the client port handle if the server port handle fails to be + // created. + CASCADE_RESULT(*server_port, Kernel::g_handle_table.Create( + std::move(std::get<SharedPtr<ServerPort>>(ports)))); LOG_TRACE(Kernel_SVC, "called max_sessions=%u", max_sessions); return RESULT_SUCCESS; @@ -862,9 +902,9 @@ static ResultCode GetSystemInfo(s64* out, u32 type, s32 param) { case SystemInfoType::REGION_MEMORY_USAGE: switch ((SystemInfoMemUsageRegion)param) { case SystemInfoMemUsageRegion::ALL: - *out = Kernel::GetMemoryRegion(Kernel::MemoryRegion::APPLICATION)->used - + Kernel::GetMemoryRegion(Kernel::MemoryRegion::SYSTEM)->used - + Kernel::GetMemoryRegion(Kernel::MemoryRegion::BASE)->used; + *out = Kernel::GetMemoryRegion(Kernel::MemoryRegion::APPLICATION)->used + + Kernel::GetMemoryRegion(Kernel::MemoryRegion::SYSTEM)->used + + Kernel::GetMemoryRegion(Kernel::MemoryRegion::BASE)->used; break; case SystemInfoMemUsageRegion::APPLICATION: *out = Kernel::GetMemoryRegion(Kernel::MemoryRegion::APPLICATION)->used; @@ -912,7 +952,7 @@ static ResultCode GetProcessInfo(s64* out, Handle process_handle, u32 type) { // TODO(yuriks): Type 0 returns a slightly higher number than type 2, but I'm not sure // what's the difference between them. *out = process->heap_used + process->linear_heap_used + process->misc_memory_used; - if(*out % Memory::PAGE_SIZE != 0) { + if (*out % Memory::PAGE_SIZE != 0) { LOG_ERROR(Kernel_SVC, "called, memory size not page-aligned"); return ERR_MISALIGNED_SIZE; } @@ -935,12 +975,12 @@ static ResultCode GetProcessInfo(s64* out, Handle process_handle, u32 type) { if (type >= 21 && type <= 23) { return ResultCode( // 0xE0E01BF4 - ErrorDescription::NotImplemented, ErrorModule::OS, - ErrorSummary::InvalidArgument, ErrorLevel::Usage); + ErrorDescription::NotImplemented, ErrorModule::OS, ErrorSummary::InvalidArgument, + ErrorLevel::Usage); } else { return ResultCode( // 0xD8E007ED - ErrorDescription::InvalidEnumValue, ErrorModule::Kernel, - ErrorSummary::InvalidArgument, ErrorLevel::Permanent); + ErrorDescription::InvalidEnumValue, ErrorModule::Kernel, + ErrorSummary::InvalidArgument, ErrorLevel::Permanent); } break; } @@ -949,142 +989,142 @@ static ResultCode GetProcessInfo(s64* out, Handle process_handle, u32 type) { } namespace { - struct FunctionDef { - using Func = void(); +struct FunctionDef { + using Func = void(); - u32 id; - Func* func; - const char* name; - }; + u32 id; + Func* func; + const char* name; +}; } static const FunctionDef SVC_Table[] = { - {0x00, nullptr, "Unknown"}, - {0x01, HLE::Wrap<ControlMemory>, "ControlMemory"}, - {0x02, HLE::Wrap<QueryMemory>, "QueryMemory"}, - {0x03, nullptr, "ExitProcess"}, - {0x04, nullptr, "GetProcessAffinityMask"}, - {0x05, nullptr, "SetProcessAffinityMask"}, - {0x06, nullptr, "GetProcessIdealProcessor"}, - {0x07, nullptr, "SetProcessIdealProcessor"}, - {0x08, HLE::Wrap<CreateThread>, "CreateThread"}, - {0x09, ExitThread, "ExitThread"}, - {0x0A, HLE::Wrap<SleepThread>, "SleepThread"}, - {0x0B, HLE::Wrap<GetThreadPriority>, "GetThreadPriority"}, - {0x0C, HLE::Wrap<SetThreadPriority>, "SetThreadPriority"}, - {0x0D, nullptr, "GetThreadAffinityMask"}, - {0x0E, nullptr, "SetThreadAffinityMask"}, - {0x0F, nullptr, "GetThreadIdealProcessor"}, - {0x10, nullptr, "SetThreadIdealProcessor"}, - {0x11, nullptr, "GetCurrentProcessorNumber"}, - {0x12, nullptr, "Run"}, - {0x13, HLE::Wrap<CreateMutex>, "CreateMutex"}, - {0x14, HLE::Wrap<ReleaseMutex>, "ReleaseMutex"}, - {0x15, HLE::Wrap<CreateSemaphore>, "CreateSemaphore"}, - {0x16, HLE::Wrap<ReleaseSemaphore>, "ReleaseSemaphore"}, - {0x17, HLE::Wrap<CreateEvent>, "CreateEvent"}, - {0x18, HLE::Wrap<SignalEvent>, "SignalEvent"}, - {0x19, HLE::Wrap<ClearEvent>, "ClearEvent"}, - {0x1A, HLE::Wrap<CreateTimer>, "CreateTimer"}, - {0x1B, HLE::Wrap<SetTimer>, "SetTimer"}, - {0x1C, HLE::Wrap<CancelTimer>, "CancelTimer"}, - {0x1D, HLE::Wrap<ClearTimer>, "ClearTimer"}, - {0x1E, HLE::Wrap<CreateMemoryBlock>, "CreateMemoryBlock"}, - {0x1F, HLE::Wrap<MapMemoryBlock>, "MapMemoryBlock"}, - {0x20, HLE::Wrap<UnmapMemoryBlock>, "UnmapMemoryBlock"}, + {0x00, nullptr, "Unknown"}, + {0x01, HLE::Wrap<ControlMemory>, "ControlMemory"}, + {0x02, HLE::Wrap<QueryMemory>, "QueryMemory"}, + {0x03, nullptr, "ExitProcess"}, + {0x04, nullptr, "GetProcessAffinityMask"}, + {0x05, nullptr, "SetProcessAffinityMask"}, + {0x06, nullptr, "GetProcessIdealProcessor"}, + {0x07, nullptr, "SetProcessIdealProcessor"}, + {0x08, HLE::Wrap<CreateThread>, "CreateThread"}, + {0x09, ExitThread, "ExitThread"}, + {0x0A, HLE::Wrap<SleepThread>, "SleepThread"}, + {0x0B, HLE::Wrap<GetThreadPriority>, "GetThreadPriority"}, + {0x0C, HLE::Wrap<SetThreadPriority>, "SetThreadPriority"}, + {0x0D, nullptr, "GetThreadAffinityMask"}, + {0x0E, nullptr, "SetThreadAffinityMask"}, + {0x0F, nullptr, "GetThreadIdealProcessor"}, + {0x10, nullptr, "SetThreadIdealProcessor"}, + {0x11, nullptr, "GetCurrentProcessorNumber"}, + {0x12, nullptr, "Run"}, + {0x13, HLE::Wrap<CreateMutex>, "CreateMutex"}, + {0x14, HLE::Wrap<ReleaseMutex>, "ReleaseMutex"}, + {0x15, HLE::Wrap<CreateSemaphore>, "CreateSemaphore"}, + {0x16, HLE::Wrap<ReleaseSemaphore>, "ReleaseSemaphore"}, + {0x17, HLE::Wrap<CreateEvent>, "CreateEvent"}, + {0x18, HLE::Wrap<SignalEvent>, "SignalEvent"}, + {0x19, HLE::Wrap<ClearEvent>, "ClearEvent"}, + {0x1A, HLE::Wrap<CreateTimer>, "CreateTimer"}, + {0x1B, HLE::Wrap<SetTimer>, "SetTimer"}, + {0x1C, HLE::Wrap<CancelTimer>, "CancelTimer"}, + {0x1D, HLE::Wrap<ClearTimer>, "ClearTimer"}, + {0x1E, HLE::Wrap<CreateMemoryBlock>, "CreateMemoryBlock"}, + {0x1F, HLE::Wrap<MapMemoryBlock>, "MapMemoryBlock"}, + {0x20, HLE::Wrap<UnmapMemoryBlock>, "UnmapMemoryBlock"}, {0x21, HLE::Wrap<CreateAddressArbiter>, "CreateAddressArbiter"}, - {0x22, HLE::Wrap<ArbitrateAddress>, "ArbitrateAddress"}, - {0x23, HLE::Wrap<CloseHandle>, "CloseHandle"}, + {0x22, HLE::Wrap<ArbitrateAddress>, "ArbitrateAddress"}, + {0x23, HLE::Wrap<CloseHandle>, "CloseHandle"}, {0x24, HLE::Wrap<WaitSynchronization1>, "WaitSynchronization1"}, {0x25, HLE::Wrap<WaitSynchronizationN>, "WaitSynchronizationN"}, - {0x26, nullptr, "SignalAndWait"}, - {0x27, HLE::Wrap<DuplicateHandle>, "DuplicateHandle"}, - {0x28, HLE::Wrap<GetSystemTick>, "GetSystemTick"}, - {0x29, nullptr, "GetHandleInfo"}, - {0x2A, HLE::Wrap<GetSystemInfo>, "GetSystemInfo"}, - {0x2B, HLE::Wrap<GetProcessInfo>, "GetProcessInfo"}, - {0x2C, nullptr, "GetThreadInfo"}, - {0x2D, HLE::Wrap<ConnectToPort>, "ConnectToPort"}, - {0x2E, nullptr, "SendSyncRequest1"}, - {0x2F, nullptr, "SendSyncRequest2"}, - {0x30, nullptr, "SendSyncRequest3"}, - {0x31, nullptr, "SendSyncRequest4"}, - {0x32, HLE::Wrap<SendSyncRequest>, "SendSyncRequest"}, - {0x33, nullptr, "OpenProcess"}, - {0x34, nullptr, "OpenThread"}, - {0x35, HLE::Wrap<GetProcessId>, "GetProcessId"}, + {0x26, nullptr, "SignalAndWait"}, + {0x27, HLE::Wrap<DuplicateHandle>, "DuplicateHandle"}, + {0x28, HLE::Wrap<GetSystemTick>, "GetSystemTick"}, + {0x29, nullptr, "GetHandleInfo"}, + {0x2A, HLE::Wrap<GetSystemInfo>, "GetSystemInfo"}, + {0x2B, HLE::Wrap<GetProcessInfo>, "GetProcessInfo"}, + {0x2C, nullptr, "GetThreadInfo"}, + {0x2D, HLE::Wrap<ConnectToPort>, "ConnectToPort"}, + {0x2E, nullptr, "SendSyncRequest1"}, + {0x2F, nullptr, "SendSyncRequest2"}, + {0x30, nullptr, "SendSyncRequest3"}, + {0x31, nullptr, "SendSyncRequest4"}, + {0x32, HLE::Wrap<SendSyncRequest>, "SendSyncRequest"}, + {0x33, nullptr, "OpenProcess"}, + {0x34, nullptr, "OpenThread"}, + {0x35, HLE::Wrap<GetProcessId>, "GetProcessId"}, {0x36, HLE::Wrap<GetProcessIdOfThread>, "GetProcessIdOfThread"}, - {0x37, HLE::Wrap<GetThreadId>, "GetThreadId"}, - {0x38, HLE::Wrap<GetResourceLimit>, "GetResourceLimit"}, + {0x37, HLE::Wrap<GetThreadId>, "GetThreadId"}, + {0x38, HLE::Wrap<GetResourceLimit>, "GetResourceLimit"}, {0x39, HLE::Wrap<GetResourceLimitLimitValues>, "GetResourceLimitLimitValues"}, {0x3A, HLE::Wrap<GetResourceLimitCurrentValues>, "GetResourceLimitCurrentValues"}, - {0x3B, nullptr, "GetThreadContext"}, - {0x3C, HLE::Wrap<Break>, "Break"}, - {0x3D, HLE::Wrap<OutputDebugString>, "OutputDebugString"}, - {0x3E, nullptr, "ControlPerformanceCounter"}, - {0x3F, nullptr, "Unknown"}, - {0x40, nullptr, "Unknown"}, - {0x41, nullptr, "Unknown"}, - {0x42, nullptr, "Unknown"}, - {0x43, nullptr, "Unknown"}, - {0x44, nullptr, "Unknown"}, - {0x45, nullptr, "Unknown"}, - {0x46, nullptr, "Unknown"}, - {0x47, HLE::Wrap<CreatePort>, "CreatePort"}, - {0x48, nullptr, "CreateSessionToPort"}, - {0x49, nullptr, "CreateSession"}, - {0x4A, nullptr, "AcceptSession"}, - {0x4B, nullptr, "ReplyAndReceive1"}, - {0x4C, nullptr, "ReplyAndReceive2"}, - {0x4D, nullptr, "ReplyAndReceive3"}, - {0x4E, nullptr, "ReplyAndReceive4"}, - {0x4F, nullptr, "ReplyAndReceive"}, - {0x50, nullptr, "BindInterrupt"}, - {0x51, nullptr, "UnbindInterrupt"}, - {0x52, nullptr, "InvalidateProcessDataCache"}, - {0x53, nullptr, "StoreProcessDataCache"}, - {0x54, nullptr, "FlushProcessDataCache"}, - {0x55, nullptr, "StartInterProcessDma"}, - {0x56, nullptr, "StopDma"}, - {0x57, nullptr, "GetDmaState"}, - {0x58, nullptr, "RestartDma"}, - {0x59, nullptr, "Unknown"}, - {0x5A, nullptr, "Unknown"}, - {0x5B, nullptr, "Unknown"}, - {0x5C, nullptr, "Unknown"}, - {0x5D, nullptr, "Unknown"}, - {0x5E, nullptr, "Unknown"}, - {0x5F, nullptr, "Unknown"}, - {0x60, nullptr, "DebugActiveProcess"}, - {0x61, nullptr, "BreakDebugProcess"}, - {0x62, nullptr, "TerminateDebugProcess"}, - {0x63, nullptr, "GetProcessDebugEvent"}, - {0x64, nullptr, "ContinueDebugEvent"}, - {0x65, nullptr, "GetProcessList"}, - {0x66, nullptr, "GetThreadList"}, - {0x67, nullptr, "GetDebugThreadContext"}, - {0x68, nullptr, "SetDebugThreadContext"}, - {0x69, nullptr, "QueryDebugProcessMemory"}, - {0x6A, nullptr, "ReadProcessMemory"}, - {0x6B, nullptr, "WriteProcessMemory"}, - {0x6C, nullptr, "SetHardwareBreakPoint"}, - {0x6D, nullptr, "GetDebugThreadParam"}, - {0x6E, nullptr, "Unknown"}, - {0x6F, nullptr, "Unknown"}, - {0x70, nullptr, "ControlProcessMemory"}, - {0x71, nullptr, "MapProcessMemory"}, - {0x72, nullptr, "UnmapProcessMemory"}, - {0x73, nullptr, "CreateCodeSet"}, - {0x74, nullptr, "RandomStub"}, - {0x75, nullptr, "CreateProcess"}, - {0x76, nullptr, "TerminateProcess"}, - {0x77, nullptr, "SetProcessResourceLimits"}, - {0x78, nullptr, "CreateResourceLimit"}, - {0x79, nullptr, "SetResourceLimitValues"}, - {0x7A, nullptr, "AddCodeSegment"}, - {0x7B, nullptr, "Backdoor"}, - {0x7C, nullptr, "KernelSetState"}, - {0x7D, HLE::Wrap<QueryProcessMemory>, "QueryProcessMemory"}, + {0x3B, nullptr, "GetThreadContext"}, + {0x3C, HLE::Wrap<Break>, "Break"}, + {0x3D, HLE::Wrap<OutputDebugString>, "OutputDebugString"}, + {0x3E, nullptr, "ControlPerformanceCounter"}, + {0x3F, nullptr, "Unknown"}, + {0x40, nullptr, "Unknown"}, + {0x41, nullptr, "Unknown"}, + {0x42, nullptr, "Unknown"}, + {0x43, nullptr, "Unknown"}, + {0x44, nullptr, "Unknown"}, + {0x45, nullptr, "Unknown"}, + {0x46, nullptr, "Unknown"}, + {0x47, HLE::Wrap<CreatePort>, "CreatePort"}, + {0x48, nullptr, "CreateSessionToPort"}, + {0x49, nullptr, "CreateSession"}, + {0x4A, nullptr, "AcceptSession"}, + {0x4B, nullptr, "ReplyAndReceive1"}, + {0x4C, nullptr, "ReplyAndReceive2"}, + {0x4D, nullptr, "ReplyAndReceive3"}, + {0x4E, nullptr, "ReplyAndReceive4"}, + {0x4F, nullptr, "ReplyAndReceive"}, + {0x50, nullptr, "BindInterrupt"}, + {0x51, nullptr, "UnbindInterrupt"}, + {0x52, nullptr, "InvalidateProcessDataCache"}, + {0x53, nullptr, "StoreProcessDataCache"}, + {0x54, nullptr, "FlushProcessDataCache"}, + {0x55, nullptr, "StartInterProcessDma"}, + {0x56, nullptr, "StopDma"}, + {0x57, nullptr, "GetDmaState"}, + {0x58, nullptr, "RestartDma"}, + {0x59, nullptr, "Unknown"}, + {0x5A, nullptr, "Unknown"}, + {0x5B, nullptr, "Unknown"}, + {0x5C, nullptr, "Unknown"}, + {0x5D, nullptr, "Unknown"}, + {0x5E, nullptr, "Unknown"}, + {0x5F, nullptr, "Unknown"}, + {0x60, nullptr, "DebugActiveProcess"}, + {0x61, nullptr, "BreakDebugProcess"}, + {0x62, nullptr, "TerminateDebugProcess"}, + {0x63, nullptr, "GetProcessDebugEvent"}, + {0x64, nullptr, "ContinueDebugEvent"}, + {0x65, nullptr, "GetProcessList"}, + {0x66, nullptr, "GetThreadList"}, + {0x67, nullptr, "GetDebugThreadContext"}, + {0x68, nullptr, "SetDebugThreadContext"}, + {0x69, nullptr, "QueryDebugProcessMemory"}, + {0x6A, nullptr, "ReadProcessMemory"}, + {0x6B, nullptr, "WriteProcessMemory"}, + {0x6C, nullptr, "SetHardwareBreakPoint"}, + {0x6D, nullptr, "GetDebugThreadParam"}, + {0x6E, nullptr, "Unknown"}, + {0x6F, nullptr, "Unknown"}, + {0x70, nullptr, "ControlProcessMemory"}, + {0x71, nullptr, "MapProcessMemory"}, + {0x72, nullptr, "UnmapProcessMemory"}, + {0x73, nullptr, "CreateCodeSet"}, + {0x74, nullptr, "RandomStub"}, + {0x75, nullptr, "CreateProcess"}, + {0x76, nullptr, "TerminateProcess"}, + {0x77, nullptr, "SetProcessResourceLimits"}, + {0x78, nullptr, "CreateResourceLimit"}, + {0x79, nullptr, "SetResourceLimitValues"}, + {0x7A, nullptr, "AddCodeSegment"}, + {0x7B, nullptr, "Backdoor"}, + {0x7C, nullptr, "KernelSetState"}, + {0x7D, HLE::Wrap<QueryProcessMemory>, "QueryProcessMemory"}, }; static const FunctionDef* GetSVCInfo(u32 func_num) { diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp index a4dfb7e43..0e6b91e3a 100644 --- a/src/core/hw/gpu.cpp +++ b/src/core/hw/gpu.cpp @@ -5,34 +5,26 @@ #include <cstring> #include <numeric> #include <type_traits> - #include "common/color.h" #include "common/common_types.h" #include "common/logging/log.h" #include "common/microprofile.h" #include "common/vector_math.h" - -#include "core/settings.h" -#include "core/memory.h" #include "core/core_timing.h" - #include "core/hle/service/gsp_gpu.h" #include "core/hle/service/hid/hid.h" - -#include "core/hw/hw.h" #include "core/hw/gpu.h" - +#include "core/hw/hw.h" +#include "core/memory.h" +#include "core/settings.h" #include "core/tracer/recorder.h" - #include "video_core/command_processor.h" +#include "video_core/debug_utils/debug_utils.h" #include "video_core/rasterizer_interface.h" #include "video_core/renderer_base.h" #include "video_core/utils.h" #include "video_core/video_core.h" -#include "video_core/debug_utils/debug_utils.h" - - namespace GPU { Regs g_regs; @@ -49,7 +41,7 @@ static u64 frame_count; static bool last_skip_frame; template <typename T> -inline void Read(T &var, const u32 raw_addr) { +inline void Read(T& var, const u32 raw_addr) { u32 addr = raw_addr - HW::VADDR_GPU; u32 index = addr / 4; @@ -105,8 +97,7 @@ inline void Write(u32 addr, const T data) { // Memory fills are triggered once the fill value is written. case GPU_REG_INDEX_WORKAROUND(memory_fill_config[0].trigger, 0x00004 + 0x3): - case GPU_REG_INDEX_WORKAROUND(memory_fill_config[1].trigger, 0x00008 + 0x3): - { + case GPU_REG_INDEX_WORKAROUND(memory_fill_config[1].trigger, 0x00008 + 0x3): { const bool is_second_filler = (index != GPU_REG_INDEX(memory_fill_config[0].trigger)); auto& config = g_regs.memory_fill_config[is_second_filler]; @@ -125,7 +116,9 @@ inline void Write(u32 addr, const T data) { // regions that were between surfaces or within the touching // ones for cpu to manually fill here. if (!VideoCore::g_renderer->Rasterizer()->AccelerateFill(config)) { - Memory::RasterizerFlushAndInvalidateRegion(config.GetStartAddress(), config.GetEndAddress() - config.GetStartAddress()); + Memory::RasterizerFlushAndInvalidateRegion(config.GetStartAddress(), + config.GetEndAddress() - + config.GetStartAddress()); if (config.fill_24bit) { // fill with 24-bit values @@ -150,7 +143,8 @@ inline void Write(u32 addr, const T data) { } } - LOG_TRACE(HW_GPU, "MemoryFill from 0x%08x to 0x%08x", config.GetStartAddress(), config.GetEndAddress()); + LOG_TRACE(HW_GPU, "MemoryFill from 0x%08x to 0x%08x", config.GetStartAddress(), + config.GetEndAddress()); if (!is_second_filler) { GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC0); @@ -167,15 +161,15 @@ inline void Write(u32 addr, const T data) { break; } - case GPU_REG_INDEX(display_transfer_config.trigger): - { + case GPU_REG_INDEX(display_transfer_config.trigger): { MICROPROFILE_SCOPE(GPU_DisplayTransfer); const auto& config = g_regs.display_transfer_config; if (config.trigger & 1) { if (Pica::g_debug_context) - Pica::g_debug_context->OnEvent(Pica::DebugContext::Event::IncomingDisplayTransfer, nullptr); + Pica::g_debug_context->OnEvent(Pica::DebugContext::Event::IncomingDisplayTransfer, + nullptr); if (!VideoCore::g_renderer->Rasterizer()->AccelerateDisplayTransfer(config)) { u8* src_pointer = Memory::GetPhysicalPointer(config.GetPhysicalInputAddress()); @@ -187,17 +181,23 @@ inline void Write(u32 addr, const T data) { u32 output_width = config.texture_copy.output_width * 16; u32 output_gap = config.texture_copy.output_gap * 16; - size_t contiguous_input_size = config.texture_copy.size / input_width * (input_width + input_gap); - Memory::RasterizerFlushRegion(config.GetPhysicalInputAddress(), static_cast<u32>(contiguous_input_size)); + size_t contiguous_input_size = + config.texture_copy.size / input_width * (input_width + input_gap); + Memory::RasterizerFlushRegion(config.GetPhysicalInputAddress(), + static_cast<u32>(contiguous_input_size)); - size_t contiguous_output_size = config.texture_copy.size / output_width * (output_width + output_gap); - Memory::RasterizerFlushAndInvalidateRegion(config.GetPhysicalOutputAddress(), static_cast<u32>(contiguous_output_size)); + size_t contiguous_output_size = + config.texture_copy.size / output_width * (output_width + output_gap); + Memory::RasterizerFlushAndInvalidateRegion( + config.GetPhysicalOutputAddress(), + static_cast<u32>(contiguous_output_size)); u32 remaining_size = config.texture_copy.size; u32 remaining_input = input_width; u32 remaining_output = output_width; while (remaining_size > 0) { - u32 copy_size = std::min({ remaining_input, remaining_output, remaining_size }); + u32 copy_size = + std::min({remaining_input, remaining_output, remaining_size}); std::memcpy(dst_pointer, src_pointer, copy_size); src_pointer += copy_size; @@ -217,10 +217,11 @@ inline void Write(u32 addr, const T data) { } } - LOG_TRACE(HW_GPU, "TextureCopy: 0x%X bytes from 0x%08X(%u+%u)-> 0x%08X(%u+%u), flags 0x%08X", - config.texture_copy.size, - config.GetPhysicalInputAddress(), input_width, input_gap, - config.GetPhysicalOutputAddress(), output_width, output_gap, + LOG_TRACE( + HW_GPU, + "TextureCopy: 0x%X bytes from 0x%08X(%u+%u)-> 0x%08X(%u+%u), flags 0x%08X", + config.texture_copy.size, config.GetPhysicalInputAddress(), input_width, + input_gap, config.GetPhysicalOutputAddress(), output_width, output_gap, config.flags); GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PPF); @@ -228,7 +229,8 @@ inline void Write(u32 addr, const T data) { } if (config.scaling > config.ScaleXY) { - LOG_CRITICAL(HW_GPU, "Unimplemented display transfer scaling mode %u", config.scaling.Value()); + LOG_CRITICAL(HW_GPU, "Unimplemented display transfer scaling mode %u", + config.scaling.Value()); UNIMPLEMENTED(); break; } @@ -245,11 +247,14 @@ inline void Write(u32 addr, const T data) { u32 output_width = config.output_width >> horizontal_scale; u32 output_height = config.output_height >> vertical_scale; - u32 input_size = config.input_width * config.input_height * GPU::Regs::BytesPerPixel(config.input_format); - u32 output_size = output_width * output_height * GPU::Regs::BytesPerPixel(config.output_format); + u32 input_size = config.input_width * config.input_height * + GPU::Regs::BytesPerPixel(config.input_format); + u32 output_size = + output_width * output_height * GPU::Regs::BytesPerPixel(config.output_format); Memory::RasterizerFlushRegion(config.GetPhysicalInputAddress(), input_size); - Memory::RasterizerFlushAndInvalidateRegion(config.GetPhysicalOutputAddress(), output_size); + Memory::RasterizerFlushAndInvalidateRegion(config.GetPhysicalOutputAddress(), + output_size); for (u32 y = 0; y < output_height; ++y) { for (u32 x = 0; x < output_width; ++x) { @@ -278,11 +283,14 @@ inline void Write(u32 addr, const T data) { u32 coarse_y = y & ~7; u32 stride = output_width * dst_bytes_per_pixel; - src_offset = (input_x + input_y * config.input_width) * src_bytes_per_pixel; - dst_offset = VideoCore::GetMortonOffset(x, y, dst_bytes_per_pixel) + coarse_y * stride; + src_offset = + (input_x + input_y * config.input_width) * src_bytes_per_pixel; + dst_offset = VideoCore::GetMortonOffset(x, y, dst_bytes_per_pixel) + + coarse_y * stride; } else { // Both input and output are linear - src_offset = (input_x + input_y * config.input_width) * src_bytes_per_pixel; + src_offset = + (input_x + input_y * config.input_width) * src_bytes_per_pixel; dst_offset = (x + y * output_width) * dst_bytes_per_pixel; } } else { @@ -291,7 +299,9 @@ inline void Write(u32 addr, const T data) { u32 coarse_y = input_y & ~7; u32 stride = config.input_width * src_bytes_per_pixel; - src_offset = VideoCore::GetMortonOffset(input_x, input_y, src_bytes_per_pixel) + coarse_y * stride; + src_offset = VideoCore::GetMortonOffset(input_x, input_y, + src_bytes_per_pixel) + + coarse_y * stride; dst_offset = (x + y * output_width) * dst_bytes_per_pixel; } else { // Both input and output are tiled @@ -301,20 +311,27 @@ inline void Write(u32 addr, const T data) { u32 in_coarse_y = input_y & ~7; u32 in_stride = config.input_width * src_bytes_per_pixel; - src_offset = VideoCore::GetMortonOffset(input_x, input_y, src_bytes_per_pixel) + in_coarse_y * in_stride; - dst_offset = VideoCore::GetMortonOffset(x, y, dst_bytes_per_pixel) + out_coarse_y * out_stride; + src_offset = VideoCore::GetMortonOffset(input_x, input_y, + src_bytes_per_pixel) + + in_coarse_y * in_stride; + dst_offset = VideoCore::GetMortonOffset(x, y, dst_bytes_per_pixel) + + out_coarse_y * out_stride; } } const u8* src_pixel = src_pointer + src_offset; src_color = DecodePixel(config.input_format, src_pixel); if (config.scaling == config.ScaleX) { - Math::Vec4<u8> pixel = DecodePixel(config.input_format, src_pixel + src_bytes_per_pixel); + Math::Vec4<u8> pixel = + DecodePixel(config.input_format, src_pixel + src_bytes_per_pixel); src_color = ((src_color + pixel) / 2).Cast<u8>(); } else if (config.scaling == config.ScaleXY) { - Math::Vec4<u8> pixel1 = DecodePixel(config.input_format, src_pixel + 1 * src_bytes_per_pixel); - Math::Vec4<u8> pixel2 = DecodePixel(config.input_format, src_pixel + 2 * src_bytes_per_pixel); - Math::Vec4<u8> pixel3 = DecodePixel(config.input_format, src_pixel + 3 * src_bytes_per_pixel); + Math::Vec4<u8> pixel1 = DecodePixel( + config.input_format, src_pixel + 1 * src_bytes_per_pixel); + Math::Vec4<u8> pixel2 = DecodePixel( + config.input_format, src_pixel + 2 * src_bytes_per_pixel); + Math::Vec4<u8> pixel3 = DecodePixel( + config.input_format, src_pixel + 3 * src_bytes_per_pixel); src_color = (((src_color + pixel1) + (pixel2 + pixel3)) / 4).Cast<u8>(); } @@ -341,17 +358,20 @@ inline void Write(u32 addr, const T data) { break; default: - LOG_ERROR(HW_GPU, "Unknown destination framebuffer format %x", config.output_format.Value()); + LOG_ERROR(HW_GPU, "Unknown destination framebuffer format %x", + config.output_format.Value()); break; } } } - LOG_TRACE(HW_GPU, "DisplayTriggerTransfer: 0x%08x bytes from 0x%08x(%ux%u)-> 0x%08x(%ux%u), dst format %x, flags 0x%08X", - config.output_height * output_width * GPU::Regs::BytesPerPixel(config.output_format), - config.GetPhysicalInputAddress(), config.input_width.Value(), config.input_height.Value(), - config.GetPhysicalOutputAddress(), output_width, output_height, - config.output_format.Value(), config.flags); + LOG_TRACE(HW_GPU, "DisplayTriggerTransfer: 0x%08x bytes from 0x%08x(%ux%u)-> " + "0x%08x(%ux%u), dst format %x, flags 0x%08X", + config.output_height * output_width * + GPU::Regs::BytesPerPixel(config.output_format), + config.GetPhysicalInputAddress(), config.input_width.Value(), + config.input_height.Value(), config.GetPhysicalOutputAddress(), + output_width, output_height, config.output_format.Value(), config.flags); } g_regs.display_transfer_config.trigger = 0; @@ -361,17 +381,16 @@ inline void Write(u32 addr, const T data) { } // Seems like writing to this register triggers processing - case GPU_REG_INDEX(command_processor_config.trigger): - { + case GPU_REG_INDEX(command_processor_config.trigger): { const auto& config = g_regs.command_processor_config; - if (config.trigger & 1) - { + if (config.trigger & 1) { MICROPROFILE_SCOPE(GPU_CmdlistProcessing); u32* buffer = (u32*)Memory::GetPhysicalPointer(config.GetPhysicalAddress()); if (Pica::g_debug_context && Pica::g_debug_context->recorder) { - Pica::g_debug_context->recorder->MemoryAccessed((u8*)buffer, config.size * sizeof(u32), config.GetPhysicalAddress()); + Pica::g_debug_context->recorder->MemoryAccessed( + (u8*)buffer, config.size * sizeof(u32), config.GetPhysicalAddress()); } Pica::CommandProcessor::ProcessCommandList(buffer, config.size); @@ -389,16 +408,17 @@ inline void Write(u32 addr, const T data) { // This is happening *after* handling the write to make sure we properly catch all memory reads. if (Pica::g_debug_context && Pica::g_debug_context->recorder) { // addr + GPU VBase - IO VBase + IO PBase - Pica::g_debug_context->recorder->RegisterWritten<T>(addr + 0x1EF00000 - 0x1EC00000 + 0x10100000, data); + Pica::g_debug_context->recorder->RegisterWritten<T>( + addr + 0x1EF00000 - 0x1EC00000 + 0x10100000, data); } } // Explicitly instantiate template functions because we aren't defining this in the header: -template void Read<u64>(u64 &var, const u32 addr); -template void Read<u32>(u32 &var, const u32 addr); -template void Read<u16>(u16 &var, const u32 addr); -template void Read<u8>(u8 &var, const u32 addr); +template void Read<u64>(u64& var, const u32 addr); +template void Read<u32>(u32& var, const u32 addr); +template void Read<u16>(u16& var, const u32 addr); +template void Read<u8>(u8& var, const u32 addr); template void Write<u64>(u32 addr, const u64 data); template void Write<u32>(u32 addr, const u32 data); @@ -417,8 +437,9 @@ static void VBlankCallback(u64 userdata, int cycles_late) { // - If frameskip == 0 (disabled), always swap buffers // - If frameskip == 1, swap buffers every other frame (starting from the first frame) // - If frameskip > 1, swap buffers every frameskip^n frames (starting from the second frame) - if ((((Settings::values.frame_skip != 1) ^ last_skip_frame) && last_skip_frame != g_skip_frame) || - Settings::values.frame_skip == 0) { + if ((((Settings::values.frame_skip != 1) ^ last_skip_frame) && + last_skip_frame != g_skip_frame) || + Settings::values.frame_skip == 0) { VideoCore::g_renderer->SwapBuffers(); } @@ -448,12 +469,12 @@ void Init() { // .. or at least these are the ones used by system applets. // There's probably a smarter way to come up with addresses // like this which does not require hardcoding. - framebuffer_top.address_left1 = 0x181E6000; - framebuffer_top.address_left2 = 0x1822C800; + framebuffer_top.address_left1 = 0x181E6000; + framebuffer_top.address_left2 = 0x1822C800; framebuffer_top.address_right1 = 0x18273000; framebuffer_top.address_right2 = 0x182B9800; - framebuffer_sub.address_left1 = 0x1848F000; - framebuffer_sub.address_left2 = 0x184C7800; + framebuffer_sub.address_left1 = 0x1848F000; + framebuffer_sub.address_left2 = 0x184C7800; framebuffer_top.width.Assign(240); framebuffer_top.height.Assign(400); diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h index da4c345b4..32ddc5697 100644 --- a/src/core/hw/gpu.h +++ b/src/core/hw/gpu.h @@ -6,7 +6,6 @@ #include <cstddef> #include <type_traits> - #include "common/assert.h" #include "common/bit_field.h" #include "common/common_funcs.h" @@ -17,7 +16,8 @@ namespace GPU { // Returns index corresponding to the Regs member labeled by field_name // TODO: Due to Visual studio bug 209229, offsetof does not return constant expressions // when used with array elements (e.g. GPU_REG_INDEX(memory_fill_config[0])). -// For details cf. https://connect.microsoft.com/VisualStudio/feedback/details/209229/offsetof-does-not-produce-a-constant-expression-for-array-members +// For details cf. +// https://connect.microsoft.com/VisualStudio/feedback/details/209229/offsetof-does-not-produce-a-constant-expression-for-array-members // Hopefully, this will be fixed sometime in the future. // For lack of better alternatives, we currently hardcode the offsets when constant // expressions are needed via GPU_REG_INDEX_WORKAROUND (on sane compilers, static_asserts @@ -30,8 +30,9 @@ namespace GPU { // really is this annoying. This macro just forwards its first argument to GPU_REG_INDEX // and then performs a (no-op) cast to size_t iff the second argument matches the expected // field offset. Otherwise, the compiler will fail to compile this code. -#define GPU_REG_INDEX_WORKAROUND(field_name, backup_workaround_index) \ - ((typename std::enable_if<backup_workaround_index == GPU_REG_INDEX(field_name), size_t>::type)GPU_REG_INDEX(field_name)) +#define GPU_REG_INDEX_WORKAROUND(field_name, backup_workaround_index) \ + ((typename std::enable_if<backup_workaround_index == GPU_REG_INDEX(field_name), size_t>::type) \ + GPU_REG_INDEX(field_name)) #endif // MMIO region 0x1EFxxxxx @@ -44,18 +45,18 @@ struct Regs { // support for that. #define ASSERT_MEMBER_SIZE(name, size_in_bytes) #else -#define ASSERT_MEMBER_SIZE(name, size_in_bytes) \ - static_assert(sizeof(name) == size_in_bytes, \ +#define ASSERT_MEMBER_SIZE(name, size_in_bytes) \ + static_assert(sizeof(name) == size_in_bytes, \ "Structure size and register block length don't match") #endif // Components are laid out in reverse byte order, most significant bits first. enum class PixelFormat : u32 { - RGBA8 = 0, - RGB8 = 1, + RGBA8 = 0, + RGB8 = 1, RGB565 = 2, RGB5A1 = 3, - RGBA4 = 4, + RGBA4 = 4, }; /** @@ -88,8 +89,8 @@ struct Regs { BitField<0, 16, u32> value_16bit; // TODO: Verify component order - BitField< 0, 8, u32> value_24bit_r; - BitField< 8, 8, u32> value_24bit_g; + BitField<0, 8, u32> value_24bit_r; + BitField<8, 8, u32> value_24bit_g; BitField<16, 8, u32> value_24bit_b; }; @@ -126,7 +127,7 @@ struct Regs { union { u32 size; - BitField< 0, 16, u32> width; + BitField<0, 16, u32> width; BitField<16, 16, u32> height; }; @@ -138,7 +139,7 @@ struct Regs { union { u32 format; - BitField< 0, 3, PixelFormat> color_format; + BitField<0, 3, PixelFormat> color_format; }; INSERT_PADDING_WORDS(0x1); @@ -180,35 +181,37 @@ struct Regs { union { u32 output_size; - BitField< 0, 16, u32> output_width; + BitField<0, 16, u32> output_width; BitField<16, 16, u32> output_height; }; union { u32 input_size; - BitField< 0, 16, u32> input_width; + BitField<0, 16, u32> input_width; BitField<16, 16, u32> input_height; }; enum ScalingMode : u32 { - NoScale = 0, // Doesn't scale the image - ScaleX = 1, // Downscales the image in half in the X axis and applies a box filter - ScaleXY = 2, // Downscales the image in half in both the X and Y axes and applies a box filter + NoScale = 0, // Doesn't scale the image + ScaleX = 1, // Downscales the image in half in the X axis and applies a box filter + ScaleXY = + 2, // Downscales the image in half in both the X and Y axes and applies a box filter }; union { u32 flags; - BitField< 0, 1, u32> flip_vertically; // flips input data vertically - BitField< 1, 1, u32> input_linear; // Converts from linear to tiled format - BitField< 2, 1, u32> crop_input_lines; - BitField< 3, 1, u32> is_texture_copy; // Copies the data without performing any processing and respecting texture copy fields - BitField< 5, 1, u32> dont_swizzle; - BitField< 8, 3, PixelFormat> input_format; + BitField<0, 1, u32> flip_vertically; // flips input data vertically + BitField<1, 1, u32> input_linear; // Converts from linear to tiled format + BitField<2, 1, u32> crop_input_lines; + BitField<3, 1, u32> is_texture_copy; // Copies the data without performing any + // processing and respecting texture copy fields + BitField<5, 1, u32> dont_swizzle; + BitField<8, 3, PixelFormat> input_format; BitField<12, 3, PixelFormat> output_format; /// Uses some kind of 32x32 block swizzling mode, instead of the usual 8x8 one. - BitField<16, 1, u32> block_32; // TODO(yuriks): unimplemented + BitField<16, 1, u32> block_32; // TODO(yuriks): unimplemented BitField<24, 2, ScalingMode> scaling; // Determines the scaling mode of the transfer }; @@ -225,14 +228,14 @@ struct Regs { union { u32 input_size; - BitField< 0, 16, u32> input_width; + BitField<0, 16, u32> input_width; BitField<16, 16, u32> input_gap; }; union { u32 output_size; - BitField< 0, 16, u32> output_width; + BitField<0, 16, u32> output_width; BitField<16, 16, u32> output_gap; }; } texture_copy; @@ -267,12 +270,12 @@ struct Regs { return sizeof(Regs) / sizeof(u32); } - const u32& operator [] (int index) const { + const u32& operator[](int index) const { const u32* content = reinterpret_cast<const u32*>(this); return content[index]; } - u32& operator [] (int index) { + u32& operator[](int index) { u32* content = reinterpret_cast<u32*>(this); return content[index]; } @@ -294,28 +297,29 @@ static_assert(std::is_standard_layout<Regs>::value, "Structure does not use stan // is technically allowed since C++11. This macro should be enabled once MSVC adds // support for that. #ifndef _MSC_VER -#define ASSERT_REG_POSITION(field_name, position) \ - static_assert(offsetof(Regs, field_name) == position * 4, \ - "Field "#field_name" has invalid position") - -ASSERT_REG_POSITION(memory_fill_config[0], 0x00004); -ASSERT_REG_POSITION(memory_fill_config[1], 0x00008); -ASSERT_REG_POSITION(framebuffer_config[0], 0x00117); -ASSERT_REG_POSITION(framebuffer_config[1], 0x00157); -ASSERT_REG_POSITION(display_transfer_config, 0x00300); +#define ASSERT_REG_POSITION(field_name, position) \ + static_assert(offsetof(Regs, field_name) == position * 4, \ + "Field " #field_name " has invalid position") + +ASSERT_REG_POSITION(memory_fill_config[0], 0x00004); +ASSERT_REG_POSITION(memory_fill_config[1], 0x00008); +ASSERT_REG_POSITION(framebuffer_config[0], 0x00117); +ASSERT_REG_POSITION(framebuffer_config[1], 0x00157); +ASSERT_REG_POSITION(display_transfer_config, 0x00300); ASSERT_REG_POSITION(command_processor_config, 0x00638); #undef ASSERT_REG_POSITION #endif // !defined(_MSC_VER) -// The total number of registers is chosen arbitrarily, but let's make sure it's not some odd value anyway. +// The total number of registers is chosen arbitrarily, but let's make sure it's not some odd value +// anyway. static_assert(sizeof(Regs) == 0x1000 * sizeof(u32), "Invalid total size of register set"); extern Regs g_regs; extern bool g_skip_frame; template <typename T> -void Read(T &var, const u32 addr); +void Read(T& var, const u32 addr); template <typename T> void Write(u32 addr, const T data); @@ -326,5 +330,4 @@ void Init(); /// Shutdown hardware void Shutdown(); - } // namespace diff --git a/src/core/hw/hw.cpp b/src/core/hw/hw.cpp index b5fdbf9c1..9ff8825b2 100644 --- a/src/core/hw/hw.cpp +++ b/src/core/hw/hw.cpp @@ -4,15 +4,14 @@ #include "common/common_types.h" #include "common/logging/log.h" - -#include "core/hw/hw.h" #include "core/hw/gpu.h" +#include "core/hw/hw.h" #include "core/hw/lcd.h" namespace HW { template <typename T> -inline void Read(T &var, const u32 addr) { +inline void Read(T& var, const u32 addr) { switch (addr & 0xFFFFF000) { case VADDR_GPU: case VADDR_GPU + 0x1000: @@ -71,10 +70,10 @@ inline void Write(u32 addr, const T data) { // Explicitly instantiate template functions because we aren't defining this in the header: -template void Read<u64>(u64 &var, const u32 addr); -template void Read<u32>(u32 &var, const u32 addr); -template void Read<u16>(u16 &var, const u32 addr); -template void Read<u8>(u8 &var, const u32 addr); +template void Read<u64>(u64& var, const u32 addr); +template void Read<u32>(u32& var, const u32 addr); +template void Read<u16>(u16& var, const u32 addr); +template void Read<u8>(u8& var, const u32 addr); template void Write<u64>(u32 addr, const u64 data); template void Write<u32>(u32 addr, const u32 data); @@ -82,8 +81,7 @@ template void Write<u16>(u32 addr, const u16 data); template void Write<u8>(u32 addr, const u8 data); /// Update hardware -void Update() { -} +void Update() {} /// Initialize hardware void Init() { @@ -98,5 +96,4 @@ void Shutdown() { LCD::Shutdown(); LOG_DEBUG(HW, "shutdown OK"); } - } diff --git a/src/core/hw/hw.h b/src/core/hw/hw.h index d65608910..a3c5d2ea3 100644 --- a/src/core/hw/hw.h +++ b/src/core/hw/hw.h @@ -10,30 +10,30 @@ namespace HW { /// Beginnings of IO register regions, in the user VA space. enum : u32 { - VADDR_HASH = 0x1EC01000, - VADDR_CSND = 0x1EC03000, - VADDR_DSP = 0x1EC40000, - VADDR_PDN = 0x1EC41000, - VADDR_CODEC = 0x1EC41000, - VADDR_SPI = 0x1EC42000, - VADDR_SPI_2 = 0x1EC43000, // Only used under TWL_FIRM? - VADDR_I2C = 0x1EC44000, - VADDR_CODEC_2 = 0x1EC45000, - VADDR_HID = 0x1EC46000, - VADDR_GPIO = 0x1EC47000, - VADDR_I2C_2 = 0x1EC48000, - VADDR_SPI_3 = 0x1EC60000, - VADDR_I2C_3 = 0x1EC61000, - VADDR_MIC = 0x1EC62000, - VADDR_PXI = 0x1EC63000, - VADDR_LCD = 0x1ED02000, - VADDR_DSP_2 = 0x1ED03000, - VADDR_HASH_2 = 0x1EE01000, - VADDR_GPU = 0x1EF00000, + VADDR_HASH = 0x1EC01000, + VADDR_CSND = 0x1EC03000, + VADDR_DSP = 0x1EC40000, + VADDR_PDN = 0x1EC41000, + VADDR_CODEC = 0x1EC41000, + VADDR_SPI = 0x1EC42000, + VADDR_SPI_2 = 0x1EC43000, // Only used under TWL_FIRM? + VADDR_I2C = 0x1EC44000, + VADDR_CODEC_2 = 0x1EC45000, + VADDR_HID = 0x1EC46000, + VADDR_GPIO = 0x1EC47000, + VADDR_I2C_2 = 0x1EC48000, + VADDR_SPI_3 = 0x1EC60000, + VADDR_I2C_3 = 0x1EC61000, + VADDR_MIC = 0x1EC62000, + VADDR_PXI = 0x1EC63000, + VADDR_LCD = 0x1ED02000, + VADDR_DSP_2 = 0x1ED03000, + VADDR_HASH_2 = 0x1EE01000, + VADDR_GPU = 0x1EF00000, }; template <typename T> -void Read(T &var, const u32 addr); +void Read(T& var, const u32 addr); template <typename T> void Write(u32 addr, const T data); diff --git a/src/core/hw/lcd.cpp b/src/core/hw/lcd.cpp index 6f93709e3..2aa89de18 100644 --- a/src/core/hw/lcd.cpp +++ b/src/core/hw/lcd.cpp @@ -3,13 +3,10 @@ // Refer to the license.txt file included. #include <cstring> - #include "common/common_types.h" #include "common/logging/log.h" - #include "core/hw/hw.h" #include "core/hw/lcd.h" - #include "core/tracer/recorder.h" #include "video_core/debug_utils/debug_utils.h" @@ -18,7 +15,7 @@ namespace LCD { Regs g_regs; template <typename T> -inline void Read(T &var, const u32 raw_addr) { +inline void Read(T& var, const u32 raw_addr) { u32 addr = raw_addr - HW::VADDR_LCD; u32 index = addr / 4; @@ -48,16 +45,17 @@ inline void Write(u32 addr, const T data) { // This is happening *after* handling the write to make sure we properly catch all memory reads. if (Pica::g_debug_context && Pica::g_debug_context->recorder) { // addr + GPU VBase - IO VBase + IO PBase - Pica::g_debug_context->recorder->RegisterWritten<T>(addr + HW::VADDR_LCD - 0x1EC00000 + 0x10100000, data); + Pica::g_debug_context->recorder->RegisterWritten<T>( + addr + HW::VADDR_LCD - 0x1EC00000 + 0x10100000, data); } } // Explicitly instantiate template functions because we aren't defining this in the header: -template void Read<u64>(u64 &var, const u32 addr); -template void Read<u32>(u32 &var, const u32 addr); -template void Read<u16>(u16 &var, const u32 addr); -template void Read<u8>(u8 &var, const u32 addr); +template void Read<u64>(u64& var, const u32 addr); +template void Read<u32>(u32& var, const u32 addr); +template void Read<u16>(u16& var, const u32 addr); +template void Read<u8>(u8& var, const u32 addr); template void Write<u64>(u32 addr, const u64 data); template void Write<u32>(u32 addr, const u32 data); diff --git a/src/core/hw/lcd.h b/src/core/hw/lcd.h index 57029c5e8..191fd44af 100644 --- a/src/core/hw/lcd.h +++ b/src/core/hw/lcd.h @@ -6,7 +6,6 @@ #include <cstddef> #include <type_traits> - #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" @@ -42,16 +41,15 @@ struct Regs { return sizeof(Regs) / sizeof(u32); } - const u32& operator [] (int index) const { + const u32& operator[](int index) const { const u32* content = reinterpret_cast<const u32*>(this); return content[index]; } - u32& operator [] (int index) { + u32& operator[](int index) { u32* content = reinterpret_cast<u32*>(this); return content[index]; } - }; static_assert(std::is_standard_layout<Regs>::value, "Structure does not use standard layout"); @@ -59,14 +57,14 @@ static_assert(std::is_standard_layout<Regs>::value, "Structure does not use stan // is technically allowed since C++11. This macro should be enabled once MSVC adds // support for that. #ifndef _MSC_VER -#define ASSERT_REG_POSITION(field_name, position) \ - static_assert(offsetof(Regs, field_name) == position * 4, \ - "Field "#field_name" has invalid position") +#define ASSERT_REG_POSITION(field_name, position) \ + static_assert(offsetof(Regs, field_name) == position * 4, \ + "Field " #field_name " has invalid position") -ASSERT_REG_POSITION(color_fill_top, 0x81); -ASSERT_REG_POSITION(backlight_top, 0x90); +ASSERT_REG_POSITION(color_fill_top, 0x81); +ASSERT_REG_POSITION(backlight_top, 0x90); ASSERT_REG_POSITION(color_fill_bottom, 0x281); -ASSERT_REG_POSITION(backlight_bottom, 0x290); +ASSERT_REG_POSITION(backlight_bottom, 0x290); #undef ASSERT_REG_POSITION #endif // !defined(_MSC_VER) @@ -74,7 +72,7 @@ ASSERT_REG_POSITION(backlight_bottom, 0x290); extern Regs g_regs; template <typename T> -void Read(T &var, const u32 addr); +void Read(T& var, const u32 addr); template <typename T> void Write(u32 addr, const T data); diff --git a/src/core/hw/y2r.cpp b/src/core/hw/y2r.cpp index 083391e83..6a6c707a2 100644 --- a/src/core/hw/y2r.cpp +++ b/src/core/hw/y2r.cpp @@ -6,13 +6,11 @@ #include <array> #include <cstddef> #include <memory> - #include "common/assert.h" #include "common/color.h" #include "common/common_types.h" #include "common/math_util.h" #include "common/vector_math.h" - #include "core/hle/service/y2r_u.h" #include "core/hw/y2r.h" #include "core/memory.h" @@ -27,9 +25,9 @@ static const size_t TILE_SIZE = 8 * 8; using ImageTile = std::array<u32, TILE_SIZE>; /// Converts a image strip from the source YUV format into individual 8x8 RGB32 tiles. -static void ConvertYUVToRGB(InputFormat input_format, - const u8* input_Y, const u8* input_U, const u8* input_V, ImageTile output[], - unsigned int width, unsigned int height, const CoefficientSet& coefficients) { +static void ConvertYUVToRGB(InputFormat input_format, const u8* input_Y, const u8* input_U, + const u8* input_V, ImageTile output[], unsigned int width, + unsigned int height, const CoefficientSet& coefficients) { for (unsigned int y = 0; y < height; ++y) { for (unsigned int x = 0; x < width; ++x) { @@ -58,11 +56,11 @@ static void ConvertYUVToRGB(InputFormat input_format, // This conversion process is bit-exact with hardware, as far as could be tested. auto& c = coefficients; - s32 cY = c[0]*Y; + s32 cY = c[0] * Y; - s32 r = cY + c[1]*V; - s32 g = cY - c[3]*U - c[2]*V; - s32 b = cY + c[4]*U; + s32 r = cY + c[1] * V; + s32 g = cY - c[2] * V - c[3] * U; + s32 b = cY + c[4] * U; const s32 rounding_offset = 0x18; r = (r >> 3) + c[5] + rounding_offset; @@ -74,14 +72,14 @@ static void ConvertYUVToRGB(InputFormat input_format, u32* out = &output[tile][y * 8 + tile_x]; using MathUtil::Clamp; - *out = ((u32)Clamp(r >> 5, 0, 0xFF) << 24) | - ((u32)Clamp(g >> 5, 0, 0xFF) << 16) | + *out = ((u32)Clamp(r >> 5, 0, 0xFF) << 24) | ((u32)Clamp(g >> 5, 0, 0xFF) << 16) | ((u32)Clamp(b >> 5, 0, 0xFF) << 8); } } } -/// Simulates an incoming CDMA transfer. The N parameter is used to automatically convert 16-bit formats to 8-bit. +/// Simulates an incoming CDMA transfer. The N parameter is used to automatically convert 16-bit +/// formats to 8-bit. template <size_t N> static void ReceiveData(u8* output, ConversionBuffer& buf, size_t amount_of_data) { const u8* input = Memory::GetPointer(buf.address); @@ -103,9 +101,10 @@ static void ReceiveData(u8* output, ConversionBuffer& buf, size_t amount_of_data } } -/// Convert intermediate RGB32 format to the final output format while simulating an outgoing CDMA transfer. +/// Convert intermediate RGB32 format to the final output format while simulating an outgoing CDMA +/// transfer. static void SendData(const u32* input, ConversionBuffer& buf, int amount_of_data, - OutputFormat output_format, u8 alpha) { + OutputFormat output_format, u8 alpha) { u8* output = Memory::GetPointer(buf.address); @@ -113,9 +112,7 @@ static void SendData(const u32* input, ConversionBuffer& buf, int amount_of_data u8* unit_end = output + buf.transfer_unit; while (output < unit_end) { u32 color = *input++; - Math::Vec4<u8> col_vec{ - (u8)(color >> 24), (u8)(color >> 16), (u8)(color >> 8), alpha - }; + Math::Vec4<u8> col_vec{(u8)(color >> 24), (u8)(color >> 16), (u8)(color >> 8), alpha}; switch (output_format) { case OutputFormat::RGBA8: @@ -145,7 +142,8 @@ static void SendData(const u32* input, ConversionBuffer& buf, int amount_of_data } } -static const u8 linear_lut[64] = { +static const u8 linear_lut[TILE_SIZE] = { + // clang-format off 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, @@ -154,9 +152,11 @@ static const u8 linear_lut[64] = { 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + // clang-format on }; -static const u8 morton_lut[64] = { +static const u8 morton_lut[TILE_SIZE] = { + // clang-format off 0, 1, 4, 5, 16, 17, 20, 21, 2, 3, 6, 7, 18, 19, 22, 23, 8, 9, 12, 13, 24, 25, 28, 29, @@ -165,15 +165,18 @@ static const u8 morton_lut[64] = { 34, 35, 38, 39, 50, 51, 54, 55, 40, 41, 44, 45, 56, 57, 60, 61, 42, 43, 46, 47, 58, 59, 62, 63, + // clang-format on }; -static void RotateTile0(const ImageTile& input, ImageTile& output, int height, const u8 out_map[64]) { +static void RotateTile0(const ImageTile& input, ImageTile& output, int height, + const u8 out_map[64]) { for (int i = 0; i < height * 8; ++i) { output[out_map[i]] = input[i]; } } -static void RotateTile90(const ImageTile& input, ImageTile& output, int height, const u8 out_map[64]) { +static void RotateTile90(const ImageTile& input, ImageTile& output, int height, + const u8 out_map[64]) { int out_i = 0; for (int x = 0; x < 8; ++x) { for (int y = height - 1; y >= 0; --y) { @@ -182,16 +185,18 @@ static void RotateTile90(const ImageTile& input, ImageTile& output, int height, } } -static void RotateTile180(const ImageTile& input, ImageTile& output, int height, const u8 out_map[64]) { +static void RotateTile180(const ImageTile& input, ImageTile& output, int height, + const u8 out_map[64]) { int out_i = 0; for (int i = height * 8 - 1; i >= 0; --i) { output[out_map[out_i++]] = input[i]; } } -static void RotateTile270(const ImageTile& input, ImageTile& output, int height, const u8 out_map[64]) { +static void RotateTile270(const ImageTile& input, ImageTile& output, int height, + const u8 out_map[64]) { int out_i = 0; - for (int x = 8-1; x >= 0; --x) { + for (int x = 8 - 1; x >= 0; --x) { for (int y = 0; y < height; ++y) { output[out_map[out_i++]] = input[y * 8 + x]; } @@ -274,9 +279,11 @@ void PerformConversion(ConversionConfiguration& cvt) { const u8* tile_remap = nullptr; switch (cvt.block_alignment) { case BlockAlignment::Linear: - tile_remap = linear_lut; break; + tile_remap = linear_lut; + break; case BlockAlignment::Block8x8: - tile_remap = morton_lut; break; + tile_remap = morton_lut; + break; } for (unsigned int y = 0; y < cvt.input_lines; y += 8) { @@ -320,7 +327,7 @@ void PerformConversion(ConversionConfiguration& cvt) { // Note(yuriks): If additional optimization is required, input_format can be moved to a // template parameter, so that its dispatch can be moved to outside the inner loop. ConvertYUVToRGB(cvt.input_format, input_Y, input_U, input_V, tiles.get(), - cvt.input_line_width, row_height, cvt.coefficients); + cvt.input_line_width, row_height, cvt.coefficients); u32* output_buffer = reinterpret_cast<u32*>(data_buffer.get()); @@ -367,9 +374,9 @@ void PerformConversion(ConversionConfiguration& cvt) { // Note(yuriks): If additional optimization is required, output_format can be moved to a // template parameter, so that its dispatch can be moved to outside the inner loop. - SendData(reinterpret_cast<u32*>(data_buffer.get()), cvt.dst, (int)row_data_size, cvt.output_format, (u8)cvt.alpha); + SendData(reinterpret_cast<u32*>(data_buffer.get()), cvt.dst, (int)row_data_size, + cvt.output_format, (u8)cvt.alpha); } } - } } diff --git a/src/core/hw/y2r.h b/src/core/hw/y2r.h index 729e1eee3..6b6e71bec 100644 --- a/src/core/hw/y2r.h +++ b/src/core/hw/y2r.h @@ -3,13 +3,12 @@ // Refer to the license.txt file included. namespace Y2R_U { - struct ConversionConfiguration; +struct ConversionConfiguration; } namespace HW { namespace Y2R { void PerformConversion(Y2R_U::ConversionConfiguration& cvt); - } } diff --git a/src/core/loader/3dsx.cpp b/src/core/loader/3dsx.cpp index a16411e14..1c10740a0 100644 --- a/src/core/loader/3dsx.cpp +++ b/src/core/loader/3dsx.cpp @@ -4,9 +4,7 @@ #include <algorithm> #include <vector> - #include "common/logging/log.h" - #include "core/file_sys/archive_romfs.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/resource_limit.h" @@ -37,20 +35,14 @@ namespace Loader { * The BSS section must be cleared manually by the application. */ -enum THREEDSX_Error { - ERROR_NONE = 0, - ERROR_READ = 1, - ERROR_FILE = 2, - ERROR_ALLOC = 3 -}; +enum THREEDSX_Error { ERROR_NONE = 0, ERROR_READ = 1, ERROR_FILE = 2, ERROR_ALLOC = 3 }; static const u32 RELOCBUFSIZE = 512; static const unsigned int NUM_SEGMENTS = 3; // File header #pragma pack(1) -struct THREEDSX_Header -{ +struct THREEDSX_Header { u32 magic; u16 header_size, reloc_hdr_size; u32 format_ver; @@ -66,11 +58,11 @@ struct THREEDSX_Header }; // Relocation header: all fields (even extra unknown fields) are guaranteed to be relocation counts. -struct THREEDSX_RelocHdr -{ +struct THREEDSX_RelocHdr { // # of absolute relocations (that is, fix address to post-relocation memory layout) u32 cross_segment_absolute; - // # of cross-segment relative relocations (that is, 32bit signed offsets that need to be patched) + // # of cross-segment relative relocations (that is, 32bit signed offsets that need to be + // patched) u32 cross_segment_relative; // more? @@ -80,21 +72,18 @@ struct THREEDSX_RelocHdr }; // Relocation entry: from the current pointer, skip X words and patch Y words -struct THREEDSX_Reloc -{ +struct THREEDSX_Reloc { u16 skip, patch; }; #pragma pack() -struct THREEloadinfo -{ +struct THREEloadinfo { u8* seg_ptrs[3]; // code, rodata & data u32 seg_addrs[3]; u32 seg_sizes[3]; }; -static u32 TranslateAddr(u32 addr, const THREEloadinfo *loadinfo, u32* offsets) -{ +static u32 TranslateAddr(u32 addr, const THREEloadinfo* loadinfo, u32* offsets) { if (addr < offsets[0]) return loadinfo->seg_addrs[0] + addr; if (addr < offsets[1]) @@ -105,8 +94,8 @@ static u32 TranslateAddr(u32 addr, const THREEloadinfo *loadinfo, u32* offsets) using Kernel::SharedPtr; using Kernel::CodeSet; -static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, SharedPtr<CodeSet>* out_codeset) -{ +static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, + SharedPtr<CodeSet>* out_codeset) { if (!file.IsOpen()) return ERROR_FILE; @@ -118,13 +107,14 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared return ERROR_READ; THREEloadinfo loadinfo; - //loadinfo segments must be a multiple of 0x1000 - loadinfo.seg_sizes[0] = (hdr.code_seg_size + 0xFFF) &~0xFFF; - loadinfo.seg_sizes[1] = (hdr.rodata_seg_size + 0xFFF) &~0xFFF; - loadinfo.seg_sizes[2] = (hdr.data_seg_size + 0xFFF) &~0xFFF; - u32 offsets[2] = { loadinfo.seg_sizes[0], loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1] }; + // loadinfo segments must be a multiple of 0x1000 + loadinfo.seg_sizes[0] = (hdr.code_seg_size + 0xFFF) & ~0xFFF; + loadinfo.seg_sizes[1] = (hdr.rodata_seg_size + 0xFFF) & ~0xFFF; + loadinfo.seg_sizes[2] = (hdr.data_seg_size + 0xFFF) & ~0xFFF; + u32 offsets[2] = {loadinfo.seg_sizes[0], loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1]}; u32 n_reloc_tables = hdr.reloc_hdr_size / sizeof(u32); - std::vector<u8> program_image(loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1] + loadinfo.seg_sizes[2]); + std::vector<u8> program_image(loadinfo.seg_sizes[0] + loadinfo.seg_sizes[1] + + loadinfo.seg_sizes[2]); loadinfo.seg_addrs[0] = base_addr; loadinfo.seg_addrs[1] = loadinfo.seg_addrs[0] + loadinfo.seg_sizes[0]; @@ -149,7 +139,8 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared return ERROR_READ; if (file.ReadBytes(loadinfo.seg_ptrs[1], hdr.rodata_seg_size) != hdr.rodata_seg_size) return ERROR_READ; - if (file.ReadBytes(loadinfo.seg_ptrs[2], hdr.data_seg_size - hdr.bss_size) != hdr.data_seg_size - hdr.bss_size) + if (file.ReadBytes(loadinfo.seg_ptrs[2], hdr.data_seg_size - hdr.bss_size) != + hdr.data_seg_size - hdr.bss_size) return ERROR_READ; // BSS clear @@ -157,11 +148,12 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared // Relocate the segments for (unsigned int current_segment = 0; current_segment < NUM_SEGMENTS; ++current_segment) { - for (unsigned current_segment_reloc_table = 0; current_segment_reloc_table < n_reloc_tables; current_segment_reloc_table++) { + for (unsigned current_segment_reloc_table = 0; current_segment_reloc_table < n_reloc_tables; + current_segment_reloc_table++) { u32 n_relocs = relocs[current_segment * n_reloc_tables + current_segment_reloc_table]; if (current_segment_reloc_table >= 2) { // We are not using this table - ignore it because we don't know what it dose - file.Seek(n_relocs*sizeof(THREEDSX_Reloc), SEEK_CUR); + file.Seek(n_relocs * sizeof(THREEDSX_Reloc), SEEK_CUR); continue; } THREEDSX_Reloc reloc_table[RELOCBUFSIZE]; @@ -173,17 +165,20 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared u32 remaining = std::min(RELOCBUFSIZE, n_relocs); n_relocs -= remaining; - if (file.ReadBytes(reloc_table, remaining * sizeof(THREEDSX_Reloc)) != remaining * sizeof(THREEDSX_Reloc)) + if (file.ReadBytes(reloc_table, remaining * sizeof(THREEDSX_Reloc)) != + remaining * sizeof(THREEDSX_Reloc)) return ERROR_READ; - for (unsigned current_inprogress = 0; current_inprogress < remaining && pos < end_pos; current_inprogress++) { + for (unsigned current_inprogress = 0; + current_inprogress < remaining && pos < end_pos; current_inprogress++) { const auto& table = reloc_table[current_inprogress]; LOG_TRACE(Loader, "(t=%d,skip=%u,patch=%u)", current_segment_reloc_table, static_cast<u32>(table.skip), static_cast<u32>(table.patch)); pos += table.skip; s32 num_patches = table.patch; while (0 < num_patches && pos < end_pos) { - u32 in_addr = static_cast<u32>(reinterpret_cast<u8*>(pos) - program_image.data()); + u32 in_addr = + static_cast<u32>(reinterpret_cast<u8*>(pos) - program_image.data()); u32 addr = TranslateAddr(*pos, &loadinfo, offsets); LOG_TRACE(Loader, "Patching %08X <-- rel(%08X,%d) (%08X)", base_addr + in_addr, addr, current_segment_reloc_table, *pos); @@ -195,7 +190,7 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared *pos = static_cast<u32>(addr - in_addr); break; default: - break; //this should never happen + break; // this should never happen } pos++; num_patches--; @@ -209,23 +204,24 @@ static THREEDSX_Error Load3DSXFile(FileUtil::IOFile& file, u32 base_addr, Shared SharedPtr<CodeSet> code_set = CodeSet::Create("", 0); code_set->code.offset = loadinfo.seg_ptrs[0] - program_image.data(); - code_set->code.addr = loadinfo.seg_addrs[0]; - code_set->code.size = loadinfo.seg_sizes[0]; + code_set->code.addr = loadinfo.seg_addrs[0]; + code_set->code.size = loadinfo.seg_sizes[0]; code_set->rodata.offset = loadinfo.seg_ptrs[1] - program_image.data(); - code_set->rodata.addr = loadinfo.seg_addrs[1]; - code_set->rodata.size = loadinfo.seg_sizes[1]; + code_set->rodata.addr = loadinfo.seg_addrs[1]; + code_set->rodata.size = loadinfo.seg_sizes[1]; code_set->data.offset = loadinfo.seg_ptrs[2] - program_image.data(); - code_set->data.addr = loadinfo.seg_addrs[2]; - code_set->data.size = loadinfo.seg_sizes[2]; + code_set->data.addr = loadinfo.seg_addrs[2]; + code_set->data.size = loadinfo.seg_sizes[2]; code_set->entrypoint = code_set->code.addr; code_set->memory = std::make_shared<std::vector<u8>>(std::move(program_image)); LOG_DEBUG(Loader, "code size: 0x%X", loadinfo.seg_sizes[0]); LOG_DEBUG(Loader, "rodata size: 0x%X", loadinfo.seg_sizes[1]); - LOG_DEBUG(Loader, "data size: 0x%X (including 0x%X of bss)", loadinfo.seg_sizes[2], hdr.bss_size); + LOG_DEBUG(Loader, "data size: 0x%X (including 0x%X of bss)", loadinfo.seg_sizes[2], + hdr.bss_size); *out_codeset = code_set; return ERROR_NONE; @@ -260,17 +256,20 @@ ResultStatus AppLoader_THREEDSX::Load() { Kernel::g_current_process->address_mappings = default_address_mappings; // Attach the default resource limit (APPLICATION) to the process - Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); + Kernel::g_current_process->resource_limit = + Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); Kernel::g_current_process->Run(48, Kernel::DEFAULT_STACK_SIZE); - Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*this), Service::FS::ArchiveIdCode::RomFS); + Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*this), + Service::FS::ArchiveIdCode::RomFS); is_loaded = true; return ResultStatus::Success; } -ResultStatus AppLoader_THREEDSX::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) { +ResultStatus AppLoader_THREEDSX::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, + u64& offset, u64& size) { if (!file.IsOpen()) return ResultStatus::Error; diff --git a/src/core/loader/3dsx.h b/src/core/loader/3dsx.h index 90b20c61c..cfcc21cc4 100644 --- a/src/core/loader/3dsx.h +++ b/src/core/loader/3dsx.h @@ -5,7 +5,6 @@ #pragma once #include <string> - #include "common/common_types.h" #include "core/loader/loader.h" @@ -17,7 +16,8 @@ namespace Loader { /// Loads an 3DSX file class AppLoader_THREEDSX final : public AppLoader { public: - AppLoader_THREEDSX(FileUtil::IOFile&& file, const std::string& filename, const std::string& filepath) + AppLoader_THREEDSX(FileUtil::IOFile&& file, const std::string& filename, + const std::string& filepath) : AppLoader(std::move(file)), filename(std::move(filename)), filepath(filepath) {} /** @@ -55,7 +55,8 @@ public: * @param size Size of the RomFS in bytes * @return ResultStatus result of function */ - ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) override; + ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, + u64& size) override; private: std::string filename; diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 69df94324..8eb5200ab 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -3,14 +3,12 @@ // Refer to the license.txt file included. #include <cstring> -#include <string> #include <memory> - +#include <string> #include "common/common_types.h" #include "common/file_util.h" #include "common/logging/log.h" #include "common/symbols.h" - #include "core/hle/kernel/process.h" #include "core/hle/kernel/resource_limit.h" #include "core/loader/elf.h" @@ -24,112 +22,111 @@ using Kernel::CodeSet; // File type enum ElfType { - ET_NONE = 0, - ET_REL = 1, - ET_EXEC = 2, - ET_DYN = 3, - ET_CORE = 4, + ET_NONE = 0, + ET_REL = 1, + ET_EXEC = 2, + ET_DYN = 3, + ET_CORE = 4, ET_LOPROC = 0xFF00, ET_HIPROC = 0xFFFF, }; // Machine/Architecture enum ElfMachine { - EM_NONE = 0, - EM_M32 = 1, + EM_NONE = 0, + EM_M32 = 1, EM_SPARC = 2, - EM_386 = 3, - EM_68K = 4, - EM_88K = 5, - EM_860 = 7, - EM_MIPS = 8 + EM_386 = 3, + EM_68K = 4, + EM_88K = 5, + EM_860 = 7, + EM_MIPS = 8 }; // File version -#define EV_NONE 0 +#define EV_NONE 0 #define EV_CURRENT 1 // Identification index -#define EI_MAG0 0 -#define EI_MAG1 1 -#define EI_MAG2 2 -#define EI_MAG3 3 -#define EI_CLASS 4 -#define EI_DATA 5 +#define EI_MAG0 0 +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 #define EI_VERSION 6 -#define EI_PAD 7 +#define EI_PAD 7 #define EI_NIDENT 16 // Sections constants // Section types -#define SHT_NULL 0 -#define SHT_PROGBITS 1 -#define SHT_SYMTAB 2 -#define SHT_STRTAB 3 -#define SHT_RELA 4 -#define SHT_HASH 5 -#define SHT_DYNAMIC 6 -#define SHT_NOTE 7 -#define SHT_NOBITS 8 -#define SHT_REL 9 -#define SHT_SHLIB 10 -#define SHT_DYNSYM 11 +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 #define SHT_LOPROC 0x70000000 #define SHT_HIPROC 0x7FFFFFFF #define SHT_LOUSER 0x80000000 #define SHT_HIUSER 0xFFFFFFFF // Section flags -enum ElfSectionFlags -{ - SHF_WRITE = 0x1, - SHF_ALLOC = 0x2, +enum ElfSectionFlags { + SHF_WRITE = 0x1, + SHF_ALLOC = 0x2, SHF_EXECINSTR = 0x4, - SHF_MASKPROC = 0xF0000000, + SHF_MASKPROC = 0xF0000000, }; // Segment types -#define PT_NULL 0 -#define PT_LOAD 1 -#define PT_DYNAMIC 2 -#define PT_INTERP 3 -#define PT_NOTE 4 -#define PT_SHLIB 5 -#define PT_PHDR 6 -#define PT_LOPROC 0x70000000 -#define PT_HIPROC 0x7FFFFFFF +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7FFFFFFF // Segment flags -#define PF_X 0x1 -#define PF_W 0x2 -#define PF_R 0x4 +#define PF_X 0x1 +#define PF_W 0x2 +#define PF_R 0x4 #define PF_MASKPROC 0xF0000000 -typedef unsigned int Elf32_Addr; +typedef unsigned int Elf32_Addr; typedef unsigned short Elf32_Half; -typedef unsigned int Elf32_Off; -typedef signed int Elf32_Sword; -typedef unsigned int Elf32_Word; +typedef unsigned int Elf32_Off; +typedef signed int Elf32_Sword; +typedef unsigned int Elf32_Word; //////////////////////////////////////////////////////////////////////////////////////////////////// // ELF file header struct Elf32_Ehdr { unsigned char e_ident[EI_NIDENT]; - Elf32_Half e_type; - Elf32_Half e_machine; - Elf32_Word e_version; - Elf32_Addr e_entry; - Elf32_Off e_phoff; - Elf32_Off e_shoff; - Elf32_Word e_flags; - Elf32_Half e_ehsize; - Elf32_Half e_phentsize; - Elf32_Half e_phnum; - Elf32_Half e_shentsize; - Elf32_Half e_shnum; - Elf32_Half e_shstrndx; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; }; // Section header @@ -138,7 +135,7 @@ struct Elf32_Shdr { Elf32_Word sh_type; Elf32_Word sh_flags; Elf32_Addr sh_addr; - Elf32_Off sh_offset; + Elf32_Off sh_offset; Elf32_Word sh_size; Elf32_Word sh_link; Elf32_Word sh_info; @@ -149,7 +146,7 @@ struct Elf32_Shdr { // Segment header struct Elf32_Phdr { Elf32_Word p_type; - Elf32_Off p_offset; + Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; @@ -160,12 +157,12 @@ struct Elf32_Phdr { // Symbol table entry struct Elf32_Sym { - Elf32_Word st_name; - Elf32_Addr st_value; - Elf32_Word st_size; + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; unsigned char st_info; unsigned char st_other; - Elf32_Half st_shndx; + Elf32_Half st_shndx; }; // Relocation entries @@ -181,35 +178,51 @@ typedef int SectionID; class ElfReader { private: - char *base; - u32 *base32; + char* base; + u32* base32; - Elf32_Ehdr *header; - Elf32_Phdr *segments; - Elf32_Shdr *sections; + Elf32_Ehdr* header; + Elf32_Phdr* segments; + Elf32_Shdr* sections; - u32 *sectionAddrs; + u32* sectionAddrs; bool relocate; u32 entryPoint; public: - ElfReader(void *ptr); + ElfReader(void* ptr); - u32 Read32(int off) const { return base32[off >> 2]; } + u32 Read32(int off) const { + return base32[off >> 2]; + } // Quick accessors - ElfType GetType() const { return (ElfType)(header->e_type); } - ElfMachine GetMachine() const { return (ElfMachine)(header->e_machine); } - u32 GetEntryPoint() const { return entryPoint; } - u32 GetFlags() const { return (u32)(header->e_flags); } + ElfType GetType() const { + return (ElfType)(header->e_type); + } + ElfMachine GetMachine() const { + return (ElfMachine)(header->e_machine); + } + u32 GetEntryPoint() const { + return entryPoint; + } + u32 GetFlags() const { + return (u32)(header->e_flags); + } SharedPtr<CodeSet> LoadInto(u32 vaddr); bool LoadSymbols(); - int GetNumSegments() const { return (int)(header->e_phnum); } - int GetNumSections() const { return (int)(header->e_shnum); } - const u8 *GetPtr(int offset) const { return (u8*)base + offset; } - const char *GetSectionName(int section) const; - const u8 *GetSectionDataPtr(int section) const { + int GetNumSegments() const { + return (int)(header->e_phnum); + } + int GetNumSections() const { + return (int)(header->e_shnum); + } + const u8* GetPtr(int offset) const { + return (u8*)base + offset; + } + const char* GetSectionName(int section) const; + const u8* GetSectionDataPtr(int section) const { if (section < 0 || section >= header->e_shnum) return nullptr; if (sections[section].sh_type != SHT_NOBITS) @@ -220,19 +233,23 @@ public: bool IsCodeSection(int section) const { return sections[section].sh_type == SHT_PROGBITS; } - const u8 *GetSegmentPtr(int segment) { + const u8* GetSegmentPtr(int segment) { return GetPtr(segments[segment].p_offset); } - u32 GetSectionAddr(SectionID section) const { return sectionAddrs[section]; } - unsigned int GetSectionSize(SectionID section) const { return sections[section].sh_size; } - SectionID GetSectionByName(const char *name, int firstSection = 0) const; //-1 for not found + u32 GetSectionAddr(SectionID section) const { + return sectionAddrs[section]; + } + unsigned int GetSectionSize(SectionID section) const { + return sections[section].sh_size; + } + SectionID GetSectionByName(const char* name, int firstSection = 0) const; //-1 for not found bool DidRelocate() const { return relocate; } }; -ElfReader::ElfReader(void *ptr) { +ElfReader::ElfReader(void* ptr) { base = (char*)ptr; base32 = (u32*)ptr; header = (Elf32_Ehdr*)ptr; @@ -245,7 +262,7 @@ ElfReader::ElfReader(void *ptr) { LoadSymbols(); } -const char *ElfReader::GetSectionName(int section) const { +const char* ElfReader::GetSectionName(int section) const { if (sections[section].sh_type == SHT_NULL) return nullptr; @@ -303,12 +320,15 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) { } else if (permission_flags == (PF_R | PF_W)) { codeset_segment = &codeset->data; } else { - LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id %u with flags %X", i, p->p_flags); + LOG_ERROR(Loader, "Unexpected ELF PT_LOAD segment id %u with flags %X", i, + p->p_flags); continue; } if (codeset_segment->size != 0) { - LOG_ERROR(Loader, "ELF has more than one segment of the same type. Skipping extra segment (id %i)", i); + LOG_ERROR(Loader, "ELF has more than one segment of the same type. Skipping extra " + "segment (id %i)", + i); continue; } @@ -332,9 +352,9 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) { return codeset; } -SectionID ElfReader::GetSectionByName(const char *name, int firstSection) const { +SectionID ElfReader::GetSectionByName(const char* name, int firstSection) const { for (int i = firstSection; i < header->e_shnum; i++) { - const char *secname = GetSectionName(i); + const char* secname = GetSectionName(i); if (secname != nullptr && strcmp(name, secname) == 0) return i; @@ -347,9 +367,9 @@ bool ElfReader::LoadSymbols() { SectionID sec = GetSectionByName(".symtab"); if (sec != -1) { int stringSection = sections[sec].sh_link; - const char *stringBase = reinterpret_cast<const char*>(GetSectionDataPtr(stringSection)); + const char* stringBase = reinterpret_cast<const char*>(GetSectionDataPtr(stringSection)); - //We have a symbol table! + // We have a symbol table! const Elf32_Sym* symtab = reinterpret_cast<const Elf32_Sym*>(GetSectionDataPtr(sec)); unsigned int numSymbols = sections[sec].sh_size / sizeof(Elf32_Sym); for (unsigned sym = 0; sym < numSymbols; sym++) { @@ -359,7 +379,7 @@ bool ElfReader::LoadSymbols() { int type = symtab[sym].st_info & 0xF; - const char *name = stringBase + symtab[sym].st_name; + const char* name = stringBase + symtab[sym].st_name; Symbols::Add(symtab[sym].st_value, name, size, type); @@ -411,7 +431,8 @@ ResultStatus AppLoader_ELF::Load() { Kernel::g_current_process->address_mappings = default_address_mappings; // Attach the default resource limit (APPLICATION) to the process - Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); + Kernel::g_current_process->resource_limit = + Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); Kernel::g_current_process->Run(48, Kernel::DEFAULT_STACK_SIZE); diff --git a/src/core/loader/elf.h b/src/core/loader/elf.h index cb3724f9d..584bf6e27 100644 --- a/src/core/loader/elf.h +++ b/src/core/loader/elf.h @@ -5,7 +5,6 @@ #pragma once #include <string> - #include "common/common_types.h" #include "core/loader/loader.h" @@ -18,7 +17,7 @@ namespace Loader { class AppLoader_ELF final : public AppLoader { public: AppLoader_ELF(FileUtil::IOFile&& file, std::string filename) - : AppLoader(std::move(file)), filename(std::move(filename)) { } + : AppLoader(std::move(file)), filename(std::move(filename)) {} /** * Returns the type of the file diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 9719d30d5..147bf8591 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -4,10 +4,8 @@ #include <memory> #include <string> - #include "common/logging/log.h" #include "common/string_util.h" - #include "core/hle/kernel/process.h" #include "core/loader/3dsx.h" #include "core/loader/elf.h" @@ -18,17 +16,17 @@ namespace Loader { const std::initializer_list<Kernel::AddressMapping> default_address_mappings = { - { 0x1FF50000, 0x8000, true }, // part of DSP RAM - { 0x1FF70000, 0x8000, true }, // part of DSP RAM - { 0x1F000000, 0x600000, false }, // entire VRAM + {0x1FF50000, 0x8000, true}, // part of DSP RAM + {0x1FF70000, 0x8000, true}, // part of DSP RAM + {0x1F000000, 0x600000, false}, // entire VRAM }; FileType IdentifyFile(FileUtil::IOFile& file) { FileType type; -#define CHECK_TYPE(loader) \ - type = AppLoader_##loader::IdentifyType(file); \ - if (FileType::Error != type) \ +#define CHECK_TYPE(loader) \ + type = AppLoader_##loader::IdentifyType(file); \ + if (FileType::Error != type) \ return type; CHECK_TYPE(THREEDSX) @@ -100,7 +98,8 @@ const char* GetFileTypeString(FileType type) { * @return std::unique_ptr<AppLoader> a pointer to a loader object; nullptr for unsupported type */ static std::unique_ptr<AppLoader> GetFileLoader(FileUtil::IOFile&& file, FileType type, - const std::string& filename, const std::string& filepath) { + const std::string& filename, + const std::string& filepath) { switch (type) { // 3DSX file format. diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index 77d87afe1..9652d7ac5 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -9,7 +9,6 @@ #include <memory> #include <string> #include <vector> - #include "common/common_types.h" #include "common/file_util.h" @@ -30,7 +29,7 @@ enum class FileType { CXI, CIA, ELF, - THREEDSX, //3DSX + THREEDSX, // 3DSX }; /** @@ -81,8 +80,8 @@ constexpr u32 MakeMagic(char a, char b, char c, char d) { /// Interface for loading an application class AppLoader : NonCopyable { public: - AppLoader(FileUtil::IOFile&& file) : file(std::move(file)) { } - virtual ~AppLoader() { } + AppLoader(FileUtil::IOFile&& file) : file(std::move(file)) {} + virtual ~AppLoader() {} /** * Returns the type of this file @@ -140,7 +139,8 @@ public: * @param size The size of the romfs * @return ResultStatus result of function */ - virtual ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) { + virtual ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, + u64& size) { return ResultStatus::ErrorNotImplemented; } diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index fca091ff9..2e4510857 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp @@ -5,11 +5,9 @@ #include <algorithm> #include <cstring> #include <memory> - #include "common/logging/log.h" #include "common/string_util.h" #include "common/swap.h" - #include "core/file_sys/archive_romfs.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/resource_limit.h" @@ -22,8 +20,8 @@ namespace Loader { -static const int kMaxSections = 8; ///< Maximum number of sections (files) in an ExeFs -static const int kBlockSize = 0x200; ///< Size of ExeFS blocks (in bytes) +static const int kMaxSections = 8; ///< Maximum number of sections (files) in an ExeFs +static const int kBlockSize = 0x200; ///< Size of ExeFS blocks (in bytes) /** * Get the decompressed size of an LZSS compressed ExeFS file @@ -44,7 +42,8 @@ static u32 LZSS_GetDecompressedSize(const u8* buffer, u32 size) { * @param decompressed_size Size of decompressed buffer * @return True on success, otherwise false */ -static bool LZSS_Decompress(const u8* compressed, u32 compressed_size, u8* decompressed, u32 decompressed_size) { +static bool LZSS_Decompress(const u8* compressed, u32 compressed_size, u8* decompressed, + u32 decompressed_size) { const u8* footer = compressed + compressed_size - 8; u32 buffer_top_and_bottom = *reinterpret_cast<const u32*>(footer); u32 out = decompressed_size; @@ -55,7 +54,7 @@ static bool LZSS_Decompress(const u8* compressed, u32 compressed_size, u8* decom memcpy(decompressed, compressed, compressed_size); while (index > stop_index) { - u8 control = compressed[--index]; + u8 control = compressed[--index]; for (unsigned i = 0; i < 8; i++) { if (index <= stop_index) @@ -128,7 +127,7 @@ ResultStatus AppLoader_NCCH::LoadExec() { std::vector<u8> code; if (ResultStatus::Success == ReadCode(code)) { std::string process_name = Common::StringFromFixedZeroTerminatedBuffer( - (const char*)exheader_header.codeset_info.name, 8); + (const char*)exheader_header.codeset_info.name, 8); SharedPtr<CodeSet> codeset = CodeSet::Create(process_name, ncch_header.program_id); @@ -147,7 +146,8 @@ ResultStatus AppLoader_NCCH::LoadExec() { codeset->data.offset = codeset->rodata.offset + codeset->rodata.size; codeset->data.addr = exheader_header.codeset_info.data.address; - codeset->data.size = exheader_header.codeset_info.data.num_max_pages * Memory::PAGE_SIZE + bss_page_size; + codeset->data.size = + exheader_header.codeset_info.data.num_max_pages * Memory::PAGE_SIZE + bss_page_size; codeset->entrypoint = codeset->code.addr; codeset->memory = std::make_shared<std::vector<u8>>(std::move(code)); @@ -155,15 +155,18 @@ ResultStatus AppLoader_NCCH::LoadExec() { Kernel::g_current_process = Kernel::Process::Create(std::move(codeset)); // Attach a resource limit to the process based on the resource limit category - Kernel::g_current_process->resource_limit = Kernel::ResourceLimit::GetForCategory( - static_cast<Kernel::ResourceLimitCategory>(exheader_header.arm11_system_local_caps.resource_limit_category)); + Kernel::g_current_process->resource_limit = + Kernel::ResourceLimit::GetForCategory(static_cast<Kernel::ResourceLimitCategory>( + exheader_header.arm11_system_local_caps.resource_limit_category)); // Set the default CPU core for this process - Kernel::g_current_process->ideal_processor = exheader_header.arm11_system_local_caps.ideal_processor; + Kernel::g_current_process->ideal_processor = + exheader_header.arm11_system_local_caps.ideal_processor; // Copy data while converting endianess std::array<u32, ARRAY_SIZE(exheader_header.arm11_kernel_caps.descriptors)> kernel_caps; - std::copy_n(exheader_header.arm11_kernel_caps.descriptors, kernel_caps.size(), begin(kernel_caps)); + std::copy_n(exheader_header.arm11_kernel_caps.descriptors, kernel_caps.size(), + begin(kernel_caps)); Kernel::g_current_process->ParseKernelCaps(kernel_caps.data(), kernel_caps.size()); s32 priority = exheader_header.arm11_system_local_caps.priority; @@ -192,7 +195,8 @@ ResultStatus AppLoader_NCCH::LoadSectionExeFS(const char* name, std::vector<u8>& LOG_DEBUG(Loader, "%d - offset: 0x%08X, size: 0x%08X, name: %s", section_number, section.offset, section.size, section.name); - s64 section_offset = (section.offset + exefs_offset + sizeof(ExeFs_Header) + ncch_offset); + s64 section_offset = + (section.offset + exefs_offset + sizeof(ExeFs_Header) + ncch_offset); file.Seek(section_offset, SEEK_SET); if (strcmp(section.name, ".code") == 0 && is_compressed) { @@ -254,25 +258,25 @@ ResultStatus AppLoader_NCCH::LoadExeFS() { if (file.ReadBytes(&exheader_header, sizeof(ExHeader_Header)) != sizeof(ExHeader_Header)) return ResultStatus::Error; - is_compressed = (exheader_header.codeset_info.flags.flag & 1) == 1; - entry_point = exheader_header.codeset_info.text.address; - code_size = exheader_header.codeset_info.text.code_size; - stack_size = exheader_header.codeset_info.stack_size; - bss_size = exheader_header.codeset_info.bss_size; - core_version = exheader_header.arm11_system_local_caps.core_version; - priority = exheader_header.arm11_system_local_caps.priority; + is_compressed = (exheader_header.codeset_info.flags.flag & 1) == 1; + entry_point = exheader_header.codeset_info.text.address; + code_size = exheader_header.codeset_info.text.code_size; + stack_size = exheader_header.codeset_info.stack_size; + bss_size = exheader_header.codeset_info.bss_size; + core_version = exheader_header.arm11_system_local_caps.core_version; + priority = exheader_header.arm11_system_local_caps.priority; resource_limit_category = exheader_header.arm11_system_local_caps.resource_limit_category; - LOG_INFO(Loader, "Name: %s" , exheader_header.codeset_info.name); - LOG_INFO(Loader, "Program ID: %016llX" , ncch_header.program_id); - LOG_DEBUG(Loader, "Code compressed: %s" , is_compressed ? "yes" : "no"); + LOG_INFO(Loader, "Name: %s", exheader_header.codeset_info.name); + LOG_INFO(Loader, "Program ID: %016llX", ncch_header.program_id); + LOG_DEBUG(Loader, "Code compressed: %s", is_compressed ? "yes" : "no"); LOG_DEBUG(Loader, "Entry point: 0x%08X", entry_point); LOG_DEBUG(Loader, "Code size: 0x%08X", code_size); LOG_DEBUG(Loader, "Stack size: 0x%08X", stack_size); LOG_DEBUG(Loader, "Bss size: 0x%08X", bss_size); - LOG_DEBUG(Loader, "Core version: %d" , core_version); - LOG_DEBUG(Loader, "Thread priority: 0x%X" , priority); - LOG_DEBUG(Loader, "Resource limit category: %d" , resource_limit_category); + LOG_DEBUG(Loader, "Core version: %d", core_version); + LOG_DEBUG(Loader, "Thread priority: 0x%X", priority); + LOG_DEBUG(Loader, "Resource limit category: %d", resource_limit_category); if (exheader_header.arm11_system_local_caps.program_id != ncch_header.program_id) { LOG_ERROR(Loader, "ExHeader Program ID mismatch: the ROM is probably encrypted."); @@ -309,7 +313,8 @@ ResultStatus AppLoader_NCCH::Load() { if (ResultStatus::Success != result) return result; - Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*this), Service::FS::ArchiveIdCode::RomFS); + Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*this), + Service::FS::ArchiveIdCode::RomFS); return ResultStatus::Success; } @@ -329,7 +334,8 @@ ResultStatus AppLoader_NCCH::ReadLogo(std::vector<u8>& buffer) { return LoadSectionExeFS("logo", buffer); } -ResultStatus AppLoader_NCCH::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) { +ResultStatus AppLoader_NCCH::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, + u64& size) { if (!file.IsOpen()) return ResultStatus::Error; @@ -341,7 +347,7 @@ ResultStatus AppLoader_NCCH::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_ LOG_DEBUG(Loader, "RomFS offset: 0x%08X", romfs_offset); LOG_DEBUG(Loader, "RomFS size: 0x%08X", romfs_size); - if (file.GetSize () < romfs_offset + romfs_size) + if (file.GetSize() < romfs_offset + romfs_size) return ResultStatus::Error; // We reopen the file, to allow its position to be independent from file's diff --git a/src/core/loader/ncch.h b/src/core/loader/ncch.h index 75609ee57..04350d006 100644 --- a/src/core/loader/ncch.h +++ b/src/core/loader/ncch.h @@ -5,11 +5,9 @@ #pragma once #include <memory> - #include "common/bit_field.h" #include "common/common_types.h" #include "common/swap.h" - #include "core/loader/loader.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -164,7 +162,7 @@ namespace Loader { class AppLoader_NCCH final : public AppLoader { public: AppLoader_NCCH(FileUtil::IOFile&& file, const std::string& filepath) - : AppLoader(std::move(file)), filepath(filepath) { } + : AppLoader(std::move(file)), filepath(filepath) {} /** * Returns the type of the file @@ -222,10 +220,10 @@ public: * @param size Size of the RomFS in bytes * @return ResultStatus result of function */ - ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, u64& size) override; + ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, + u64& size) override; private: - /** * Reads an application ExeFS section of an NCCH file into AppLoader (e.g. .code, .logo, etc.) * @param name Name of section to read out of NCCH file @@ -246,24 +244,24 @@ private: */ ResultStatus LoadExeFS(); - bool is_exefs_loaded = false; - bool is_compressed = false; - - u32 entry_point = 0; - u32 code_size = 0; - u32 stack_size = 0; - u32 bss_size = 0; - u32 core_version = 0; - u8 priority = 0; - u8 resource_limit_category = 0; - u32 ncch_offset = 0; // Offset to NCCH header, can be 0 or after NCSD header - u32 exefs_offset = 0; - - NCCH_Header ncch_header; - ExeFs_Header exefs_header; + bool is_exefs_loaded = false; + bool is_compressed = false; + + u32 entry_point = 0; + u32 code_size = 0; + u32 stack_size = 0; + u32 bss_size = 0; + u32 core_version = 0; + u8 priority = 0; + u8 resource_limit_category = 0; + u32 ncch_offset = 0; // Offset to NCCH header, can be 0 or after NCSD header + u32 exefs_offset = 0; + + NCCH_Header ncch_header; + ExeFs_Header exefs_header; ExHeader_Header exheader_header; - std::string filepath; + std::string filepath; }; } // namespace Loader diff --git a/src/core/loader/smdh.cpp b/src/core/loader/smdh.cpp index 2d014054a..ccbeb7961 100644 --- a/src/core/loader/smdh.cpp +++ b/src/core/loader/smdh.cpp @@ -4,12 +4,9 @@ #include <cstring> #include <vector> - #include "common/common_types.h" - #include "core/loader/loader.h" #include "core/loader/smdh.h" - #include "video_core/utils.h" namespace Loader { diff --git a/src/core/loader/smdh.h b/src/core/loader/smdh.h index 2011abda2..ac7726c8f 100644 --- a/src/core/loader/smdh.h +++ b/src/core/loader/smdh.h @@ -6,7 +6,6 @@ #include <array> #include <vector> - #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" @@ -56,7 +55,7 @@ struct SMDH { Italian = 4, Spanish = 5, SimplifiedChinese = 6, - Korean= 7, + Korean = 7, Dutch = 8, Portuguese = 9, Russian = 10, diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 9aa8c4e5a..df029d655 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -4,17 +4,14 @@ #include <array> #include <cstring> - #include "common/assert.h" #include "common/common_types.h" #include "common/logging/log.h" #include "common/swap.h" - #include "core/hle/kernel/process.h" #include "core/memory.h" #include "core/memory_setup.h" #include "core/mmio.h" - #include "video_core/renderer_base.h" #include "video_core/video_core.h" @@ -25,11 +22,13 @@ enum class PageType { Unmapped, /// Page is mapped to regular memory. This is the only type you can get pointers to. Memory, - /// Page is mapped to regular memory, but also needs to check for rasterizer cache flushing and invalidation + /// Page is mapped to regular memory, but also needs to check for rasterizer cache flushing and + /// invalidation RasterizerCachedMemory, /// Page is mapped to a I/O region. Writing and reading to this page is handled by functions. Special, - /// Page is mapped to a I/O region, but also needs to check for rasterizer cache flushing and invalidation + /// Page is mapped to a I/O region, but also needs to check for rasterizer cache flushing and + /// invalidation RasterizerCachedSpecial, }; @@ -55,7 +54,8 @@ struct PageTable { std::array<u8*, NUM_ENTRIES> pointers; /** - * Contains MMIO handlers that back memory regions whose entries in the `attribute` array is of type `Special`. + * Contains MMIO handlers that back memory regions whose entries in the `attribute` array is of + * type `Special`. */ std::vector<SpecialRegion> special_regions; @@ -78,17 +78,20 @@ static PageTable main_page_table; static PageTable* current_page_table = &main_page_table; static void MapPages(u32 base, u32 size, u8* memory, PageType type) { - LOG_DEBUG(HW_Memory, "Mapping %p onto %08X-%08X", memory, base * PAGE_SIZE, (base + size) * PAGE_SIZE); + LOG_DEBUG(HW_Memory, "Mapping %p onto %08X-%08X", memory, base * PAGE_SIZE, + (base + size) * PAGE_SIZE); u32 end = base + size; while (base != end) { ASSERT_MSG(base < PageTable::NUM_ENTRIES, "out of range mapping at %08X", base); - // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be null here + // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be + // null here if (current_page_table->attributes[base] == PageType::RasterizerCachedMemory || current_page_table->attributes[base] == PageType::RasterizerCachedSpecial) { - RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(base << PAGE_BITS), PAGE_SIZE); + RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(base << PAGE_BITS), + PAGE_SIZE); } current_page_table->attributes[base] = type; @@ -162,7 +165,7 @@ static MMIORegionPointer GetMMIOHandler(VAddr vaddr) { return nullptr; // Should never happen } -template<typename T> +template <typename T> T ReadMMIO(MMIORegionPointer mmio_handler, VAddr addr); template <typename T> @@ -183,8 +186,7 @@ T Read(const VAddr vaddr) { case PageType::Memory: ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); break; - case PageType::RasterizerCachedMemory: - { + case PageType::RasterizerCachedMemory: { RasterizerFlushRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); T value; @@ -193,8 +195,7 @@ T Read(const VAddr vaddr) { } case PageType::Special: return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr); - case PageType::RasterizerCachedSpecial: - { + case PageType::RasterizerCachedSpecial: { RasterizerFlushRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); return ReadMMIO<T>(GetMMIOHandler(vaddr), vaddr); @@ -204,7 +205,7 @@ T Read(const VAddr vaddr) { } } -template<typename T> +template <typename T> void WriteMMIO(MMIORegionPointer mmio_handler, VAddr addr, const T data); template <typename T> @@ -219,13 +220,13 @@ void Write(const VAddr vaddr, const T data) { PageType type = current_page_table->attributes[vaddr >> PAGE_BITS]; switch (type) { case PageType::Unmapped: - LOG_ERROR(HW_Memory, "unmapped Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32) data, vaddr); + LOG_ERROR(HW_Memory, "unmapped Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data, + vaddr); return; case PageType::Memory: ASSERT_MSG(false, "Mapped memory page without a pointer @ %08X", vaddr); break; - case PageType::RasterizerCachedMemory: - { + case PageType::RasterizerCachedMemory: { RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); std::memcpy(GetPointerFromVMA(vaddr), &data, sizeof(T)); @@ -234,8 +235,7 @@ void Write(const VAddr vaddr, const T data) { case PageType::Special: WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data); break; - case PageType::RasterizerCachedSpecial: - { + case PageType::RasterizerCachedSpecial: { RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(vaddr), sizeof(T)); WriteMMIO<T>(GetMMIOHandler(vaddr), vaddr, data); @@ -310,7 +310,8 @@ void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) { for (unsigned i = 0; i < num_pages; ++i) { VAddr vaddr = PhysicalToVirtualAddress(paddr); u8& res_count = current_page_table->cached_res_count[vaddr >> PAGE_BITS]; - ASSERT_MSG(count_delta <= UINT8_MAX - res_count, "Rasterizer resource cache counter overflow!"); + ASSERT_MSG(count_delta <= UINT8_MAX - res_count, + "Rasterizer resource cache counter overflow!"); ASSERT_MSG(count_delta >= -res_count, "Rasterizer resource cache counter underflow!"); // Switch page type to cached if now cached @@ -337,7 +338,8 @@ void RasterizerMarkRegionCached(PAddr start, u32 size, int count_delta) { switch (page_type) { case PageType::RasterizerCachedMemory: page_type = PageType::Memory; - current_page_table->pointers[vaddr >> PAGE_BITS] = GetPointerFromVMA(vaddr & ~PAGE_MASK); + current_page_table->pointers[vaddr >> PAGE_BITS] = + GetPointerFromVMA(vaddr & ~PAGE_MASK); break; case PageType::RasterizerCachedSpecial: page_type = PageType::Special; @@ -389,7 +391,8 @@ void ReadBlock(const VAddr src_addr, void* dest_buffer, const size_t size) { switch (current_page_table->attributes[page_index]) { case PageType::Unmapped: { - LOG_ERROR(HW_Memory, "unmapped ReadBlock @ 0x%08X (start address = 0x%08X, size = %zu)", current_vaddr, src_addr, size); + LOG_ERROR(HW_Memory, "unmapped ReadBlock @ 0x%08X (start address = 0x%08X, size = %zu)", + current_vaddr, src_addr, size); std::memset(dest_buffer, 0, copy_amount); break; } @@ -458,7 +461,9 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size switch (current_page_table->attributes[page_index]) { case PageType::Unmapped: { - LOG_ERROR(HW_Memory, "unmapped WriteBlock @ 0x%08X (start address = 0x%08X, size = %zu)", current_vaddr, dest_addr, size); + LOG_ERROR(HW_Memory, + "unmapped WriteBlock @ 0x%08X (start address = 0x%08X, size = %zu)", + current_vaddr, dest_addr, size); break; } case PageType::Memory: { @@ -475,7 +480,8 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size break; } case PageType::RasterizerCachedMemory: { - RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); + RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), + copy_amount); std::memcpy(GetPointerFromVMA(current_vaddr), src_buffer, copy_amount); break; @@ -483,7 +489,8 @@ void WriteBlock(const VAddr dest_addr, const void* src_buffer, const size_t size case PageType::RasterizerCachedSpecial: { DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); - RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); + RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), + copy_amount); GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, src_buffer, copy_amount); break; @@ -512,7 +519,8 @@ void ZeroBlock(const VAddr dest_addr, const size_t size) { switch (current_page_table->attributes[page_index]) { case PageType::Unmapped: { - LOG_ERROR(HW_Memory, "unmapped ZeroBlock @ 0x%08X (start address = 0x%08X, size = %zu)", current_vaddr, dest_addr, size); + LOG_ERROR(HW_Memory, "unmapped ZeroBlock @ 0x%08X (start address = 0x%08X, size = %zu)", + current_vaddr, dest_addr, size); break; } case PageType::Memory: { @@ -529,7 +537,8 @@ void ZeroBlock(const VAddr dest_addr, const size_t size) { break; } case PageType::RasterizerCachedMemory: { - RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); + RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), + copy_amount); std::memset(GetPointerFromVMA(current_vaddr), 0, copy_amount); break; @@ -537,7 +546,8 @@ void ZeroBlock(const VAddr dest_addr, const size_t size) { case PageType::RasterizerCachedSpecial: { DEBUG_ASSERT(GetMMIOHandler(current_vaddr)); - RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), copy_amount); + RasterizerFlushAndInvalidateRegion(VirtualToPhysicalAddress(current_vaddr), + copy_amount); GetMMIOHandler(current_vaddr)->WriteBlock(current_vaddr, zeros.data(), copy_amount); break; @@ -563,7 +573,8 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, const size_t size) { switch (current_page_table->attributes[page_index]) { case PageType::Unmapped: { - LOG_ERROR(HW_Memory, "unmapped CopyBlock @ 0x%08X (start address = 0x%08X, size = %zu)", current_vaddr, src_addr, size); + LOG_ERROR(HW_Memory, "unmapped CopyBlock @ 0x%08X (start address = 0x%08X, size = %zu)", + current_vaddr, src_addr, size); ZeroBlock(dest_addr, copy_amount); break; } @@ -609,42 +620,42 @@ void CopyBlock(VAddr dest_addr, VAddr src_addr, const size_t size) { } } -template<> +template <> u8 ReadMMIO<u8>(MMIORegionPointer mmio_handler, VAddr addr) { return mmio_handler->Read8(addr); } -template<> +template <> u16 ReadMMIO<u16>(MMIORegionPointer mmio_handler, VAddr addr) { return mmio_handler->Read16(addr); } -template<> +template <> u32 ReadMMIO<u32>(MMIORegionPointer mmio_handler, VAddr addr) { return mmio_handler->Read32(addr); } -template<> +template <> u64 ReadMMIO<u64>(MMIORegionPointer mmio_handler, VAddr addr) { return mmio_handler->Read64(addr); } -template<> +template <> void WriteMMIO<u8>(MMIORegionPointer mmio_handler, VAddr addr, const u8 data) { mmio_handler->Write8(addr, data); } -template<> +template <> void WriteMMIO<u16>(MMIORegionPointer mmio_handler, VAddr addr, const u16 data) { mmio_handler->Write16(addr, data); } -template<> +template <> void WriteMMIO<u32>(MMIORegionPointer mmio_handler, VAddr addr, const u32 data) { mmio_handler->Write32(addr, data); } -template<> +template <> void WriteMMIO<u64>(MMIORegionPointer mmio_handler, VAddr addr, const u64 data) { mmio_handler->Write64(addr, data); } diff --git a/src/core/memory.h b/src/core/memory.h index cad845385..8fd3080ff 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -6,7 +6,6 @@ #include <cstddef> #include <string> - #include "common/common_types.h" namespace Memory { @@ -22,92 +21,93 @@ const int PAGE_BITS = 12; /// Physical memory regions as seen from the ARM11 enum : PAddr { /// IO register area - IO_AREA_PADDR = 0x10100000, - IO_AREA_SIZE = 0x01000000, ///< IO area size (16MB) + IO_AREA_PADDR = 0x10100000, + IO_AREA_SIZE = 0x01000000, ///< IO area size (16MB) IO_AREA_PADDR_END = IO_AREA_PADDR + IO_AREA_SIZE, /// MPCore internal memory region - MPCORE_RAM_PADDR = 0x17E00000, - MPCORE_RAM_SIZE = 0x00002000, ///< MPCore internal memory size (8KB) + MPCORE_RAM_PADDR = 0x17E00000, + MPCORE_RAM_SIZE = 0x00002000, ///< MPCore internal memory size (8KB) MPCORE_RAM_PADDR_END = MPCORE_RAM_PADDR + MPCORE_RAM_SIZE, /// Video memory - VRAM_PADDR = 0x18000000, - VRAM_SIZE = 0x00600000, ///< VRAM size (6MB) + VRAM_PADDR = 0x18000000, + VRAM_SIZE = 0x00600000, ///< VRAM size (6MB) VRAM_PADDR_END = VRAM_PADDR + VRAM_SIZE, /// DSP memory - DSP_RAM_PADDR = 0x1FF00000, - DSP_RAM_SIZE = 0x00080000, ///< DSP memory size (512KB) + DSP_RAM_PADDR = 0x1FF00000, + DSP_RAM_SIZE = 0x00080000, ///< DSP memory size (512KB) DSP_RAM_PADDR_END = DSP_RAM_PADDR + DSP_RAM_SIZE, /// AXI WRAM - AXI_WRAM_PADDR = 0x1FF80000, - AXI_WRAM_SIZE = 0x00080000, ///< AXI WRAM size (512KB) + AXI_WRAM_PADDR = 0x1FF80000, + AXI_WRAM_SIZE = 0x00080000, ///< AXI WRAM size (512KB) AXI_WRAM_PADDR_END = AXI_WRAM_PADDR + AXI_WRAM_SIZE, /// Main FCRAM - FCRAM_PADDR = 0x20000000, - FCRAM_SIZE = 0x08000000, ///< FCRAM size (128MB) + FCRAM_PADDR = 0x20000000, + FCRAM_SIZE = 0x08000000, ///< FCRAM size (128MB) FCRAM_PADDR_END = FCRAM_PADDR + FCRAM_SIZE, }; /// Virtual user-space memory regions enum : VAddr { /// Where the application text, data and bss reside. - PROCESS_IMAGE_VADDR = 0x00100000, - PROCESS_IMAGE_MAX_SIZE = 0x03F00000, + PROCESS_IMAGE_VADDR = 0x00100000, + PROCESS_IMAGE_MAX_SIZE = 0x03F00000, PROCESS_IMAGE_VADDR_END = PROCESS_IMAGE_VADDR + PROCESS_IMAGE_MAX_SIZE, /// Area where IPC buffers are mapped onto. - IPC_MAPPING_VADDR = 0x04000000, - IPC_MAPPING_SIZE = 0x04000000, + IPC_MAPPING_VADDR = 0x04000000, + IPC_MAPPING_SIZE = 0x04000000, IPC_MAPPING_VADDR_END = IPC_MAPPING_VADDR + IPC_MAPPING_SIZE, /// Application heap (includes stack). - HEAP_VADDR = 0x08000000, - HEAP_SIZE = 0x08000000, + HEAP_VADDR = 0x08000000, + HEAP_SIZE = 0x08000000, HEAP_VADDR_END = HEAP_VADDR + HEAP_SIZE, /// Area where shared memory buffers are mapped onto. - SHARED_MEMORY_VADDR = 0x10000000, - SHARED_MEMORY_SIZE = 0x04000000, + SHARED_MEMORY_VADDR = 0x10000000, + SHARED_MEMORY_SIZE = 0x04000000, SHARED_MEMORY_VADDR_END = SHARED_MEMORY_VADDR + SHARED_MEMORY_SIZE, - /// Maps 1:1 to an offset in FCRAM. Used for HW allocations that need to be linear in physical memory. - LINEAR_HEAP_VADDR = 0x14000000, - LINEAR_HEAP_SIZE = 0x08000000, + /// Maps 1:1 to an offset in FCRAM. Used for HW allocations that need to be linear in physical + /// memory. + LINEAR_HEAP_VADDR = 0x14000000, + LINEAR_HEAP_SIZE = 0x08000000, LINEAR_HEAP_VADDR_END = LINEAR_HEAP_VADDR + LINEAR_HEAP_SIZE, /// Maps 1:1 to the IO register area. - IO_AREA_VADDR = 0x1EC00000, + IO_AREA_VADDR = 0x1EC00000, IO_AREA_VADDR_END = IO_AREA_VADDR + IO_AREA_SIZE, /// Maps 1:1 to VRAM. - VRAM_VADDR = 0x1F000000, + VRAM_VADDR = 0x1F000000, VRAM_VADDR_END = VRAM_VADDR + VRAM_SIZE, /// Maps 1:1 to DSP memory. - DSP_RAM_VADDR = 0x1FF00000, + DSP_RAM_VADDR = 0x1FF00000, DSP_RAM_VADDR_END = DSP_RAM_VADDR + DSP_RAM_SIZE, /// Read-only page containing kernel and system configuration values. - CONFIG_MEMORY_VADDR = 0x1FF80000, - CONFIG_MEMORY_SIZE = 0x00001000, + CONFIG_MEMORY_VADDR = 0x1FF80000, + CONFIG_MEMORY_SIZE = 0x00001000, CONFIG_MEMORY_VADDR_END = CONFIG_MEMORY_VADDR + CONFIG_MEMORY_SIZE, /// Usually read-only page containing mostly values read from hardware. - SHARED_PAGE_VADDR = 0x1FF81000, - SHARED_PAGE_SIZE = 0x00001000, + SHARED_PAGE_VADDR = 0x1FF81000, + SHARED_PAGE_SIZE = 0x00001000, SHARED_PAGE_VADDR_END = SHARED_PAGE_VADDR + SHARED_PAGE_SIZE, /// Area where TLS (Thread-Local Storage) buffers are allocated. - TLS_AREA_VADDR = 0x1FF82000, - TLS_ENTRY_SIZE = 0x200, + TLS_AREA_VADDR = 0x1FF82000, + TLS_ENTRY_SIZE = 0x200, /// Equivalent to LINEAR_HEAP_VADDR, but expanded to cover the extra memory in the New 3DS. - NEW_LINEAR_HEAP_VADDR = 0x30000000, - NEW_LINEAR_HEAP_SIZE = 0x10000000, + NEW_LINEAR_HEAP_VADDR = 0x30000000, + NEW_LINEAR_HEAP_SIZE = 0x10000000, NEW_LINEAR_HEAP_VADDR_END = NEW_LINEAR_HEAP_VADDR + NEW_LINEAR_HEAP_SIZE, }; @@ -166,5 +166,4 @@ void RasterizerFlushRegion(PAddr start, u32 size); * Flushes and invalidates any externally cached rasterizer resources touching the given region. */ void RasterizerFlushAndInvalidateRegion(PAddr start, u32 size); - } diff --git a/src/core/memory_setup.h b/src/core/memory_setup.h index ee8ea7857..3fdf3a87d 100644 --- a/src/core/memory_setup.h +++ b/src/core/memory_setup.h @@ -5,7 +5,6 @@ #pragma once #include "common/common_types.h" - #include "core/mmio.h" namespace Memory { @@ -30,5 +29,4 @@ void MapMemoryRegion(VAddr base, u32 size, u8* target); void MapIoRegion(VAddr base, u32 size, MMIORegionPointer mmio_handler); void UnmapRegion(VAddr base, u32 size); - } diff --git a/src/core/mmio.h b/src/core/mmio.h index d76f005d8..f45126da8 100644 --- a/src/core/mmio.h +++ b/src/core/mmio.h @@ -5,7 +5,6 @@ #pragma once #include <memory> - #include "common/common_types.h" namespace Memory { @@ -36,5 +35,4 @@ public: }; using MMIORegionPointer = std::shared_ptr<MMIORegion>; - }; diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 1b6733a79..4a0969b00 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -2,12 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "settings.h" - #include "audio_core/audio_core.h" - #include "core/gdbstub/gdbstub.h" - +#include "settings.h" #include "video_core/video_core.h" namespace Settings { @@ -25,7 +22,6 @@ void Apply() { AudioCore::SelectSink(values.sink_id); AudioCore::EnableStretching(values.enable_audio_stretching); - } } // namespace diff --git a/src/core/settings.h b/src/core/settings.h index fcd14c6f3..5a64f8018 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -4,9 +4,8 @@ #pragma once -#include <string> #include <array> - +#include <string> #include "common/common_types.h" namespace Settings { @@ -14,14 +13,31 @@ namespace Settings { namespace NativeInput { enum Values { // directly mapped keys - A, B, X, Y, - L, R, ZL, ZR, - START, SELECT, HOME, - DUP, DDOWN, DLEFT, DRIGHT, - CUP, CDOWN, CLEFT, CRIGHT, + A, + B, + X, + Y, + L, + R, + ZL, + ZR, + START, + SELECT, + HOME, + DUP, + DDOWN, + DLEFT, + DRIGHT, + CUP, + CDOWN, + CLEFT, + CRIGHT, // indirectly mapped keys - CIRCLE_UP, CIRCLE_DOWN, CIRCLE_LEFT, CIRCLE_RIGHT, + CIRCLE_UP, + CIRCLE_DOWN, + CIRCLE_LEFT, + CIRCLE_RIGHT, CIRCLE_MODIFIER, NUM_INPUTS @@ -29,28 +45,21 @@ enum Values { static const std::array<const char*, NUM_INPUTS> Mapping = {{ // directly mapped keys - "pad_a", "pad_b", "pad_x", "pad_y", - "pad_l", "pad_r", "pad_zl", "pad_zr", - "pad_start", "pad_select", "pad_home", - "pad_dup", "pad_ddown", "pad_dleft", "pad_dright", - "pad_cup", "pad_cdown", "pad_cleft", "pad_cright", + "pad_a", "pad_b", "pad_x", "pad_y", "pad_l", "pad_r", "pad_zl", "pad_zr", "pad_start", + "pad_select", "pad_home", "pad_dup", "pad_ddown", "pad_dleft", "pad_dright", "pad_cup", + "pad_cdown", "pad_cleft", "pad_cright", // indirectly mapped keys "pad_circle_up", "pad_circle_down", "pad_circle_left", "pad_circle_right", "pad_circle_modifier", }}; static const std::array<Values, NUM_INPUTS> All = {{ - A, B, X, Y, - L, R, ZL, ZR, - START, SELECT, HOME, - DUP, DDOWN, DLEFT, DRIGHT, - CUP, CDOWN, CLEFT, CRIGHT, - CIRCLE_UP, CIRCLE_DOWN, CIRCLE_LEFT, CIRCLE_RIGHT, - CIRCLE_MODIFIER, + A, B, X, Y, L, R, ZL, ZR, + START, SELECT, HOME, DUP, DDOWN, DLEFT, DRIGHT, CUP, + CDOWN, CLEFT, CRIGHT, CIRCLE_UP, CIRCLE_DOWN, CIRCLE_LEFT, CIRCLE_RIGHT, CIRCLE_MODIFIER, }}; } - struct Values { // CheckNew3DS bool is_new_3ds; @@ -91,5 +100,4 @@ struct Values { } extern values; void Apply(); - } diff --git a/src/core/system.cpp b/src/core/system.cpp index 4fc266cb0..7d54811a0 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -3,21 +3,19 @@ // Refer to the license.txt file included. #include "audio_core/audio_core.h" - #include "core/core.h" #include "core/core_timing.h" -#include "core/system.h" #include "core/gdbstub/gdbstub.h" -#include "core/hw/hw.h" #include "core/hle/hle.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/memory.h" - +#include "core/hw/hw.h" +#include "core/system.h" #include "video_core/video_core.h" namespace System { -static bool is_powered_on{ false }; +static bool is_powered_on{false}; Result Init(EmuWindow* emu_window) { Core::Init(); diff --git a/src/core/system.h b/src/core/system.h index fb0ca4e1b..6d672b1b5 100644 --- a/src/core/system.h +++ b/src/core/system.h @@ -9,14 +9,13 @@ class EmuWindow; namespace System { enum class Result { - Success, ///< Everything is fine - Error, ///< Something went wrong (no module specified) - ErrorInitCore, ///< Something went wrong during core init - ErrorInitVideoCore, ///< Something went wrong during video core init + Success, ///< Everything is fine + Error, ///< Something went wrong (no module specified) + ErrorInitCore, ///< Something went wrong during core init + ErrorInitVideoCore, ///< Something went wrong during video core init }; Result Init(EmuWindow* emu_window); bool IsPoweredOn(); void Shutdown(); - } diff --git a/src/core/tracer/citrace.h b/src/core/tracer/citrace.h index 709abdfb3..215f86359 100644 --- a/src/core/tracer/citrace.h +++ b/src/core/tracer/citrace.h @@ -61,8 +61,8 @@ struct CTHeader { }; enum CTStreamElementType : u32 { - FrameMarker = 0xE1, - MemoryLoad = 0xE2, + FrameMarker = 0xE1, + MemoryLoad = 0xE2, RegisterWrite = 0xE3, }; @@ -77,10 +77,10 @@ struct CTRegisterWrite { u32 physical_address; enum : u32 { - SIZE_8 = 0xD1, + SIZE_8 = 0xD1, SIZE_16 = 0xD2, SIZE_32 = 0xD3, - SIZE_64 = 0xD4 + SIZE_64 = 0xD4, } size; // TODO: Make it clearer which bits of this member are used for sizes other than 32 bits @@ -97,5 +97,4 @@ struct CTStreamElement { }; #pragma pack() - } diff --git a/src/core/tracer/recorder.cpp b/src/core/tracer/recorder.cpp index 7abaacf70..276a5b288 100644 --- a/src/core/tracer/recorder.cpp +++ b/src/core/tracer/recorder.cpp @@ -3,18 +3,14 @@ // Refer to the license.txt file included. #include <cstring> - #include "common/assert.h" #include "common/file_util.h" #include "common/logging/log.h" - #include "recorder.h" namespace CiTrace { -Recorder::Recorder(const InitialState& initial_state) : initial_state(initial_state) { - -} +Recorder::Recorder(const InitialState& initial_state) : initial_state(initial_state) {} void Recorder::Finish(const std::string& filename) { // Setup CiTrace header @@ -26,35 +22,41 @@ void Recorder::Finish(const std::string& filename) { // Calculate file offsets auto& initial = header.initial_state_offsets; - initial.gpu_registers_size = static_cast<u32>(initial_state.gpu_registers.size()); - initial.lcd_registers_size = static_cast<u32>(initial_state.lcd_registers.size()); - initial.pica_registers_size = static_cast<u32>(initial_state.pica_registers.size()); + initial.gpu_registers_size = static_cast<u32>(initial_state.gpu_registers.size()); + initial.lcd_registers_size = static_cast<u32>(initial_state.lcd_registers.size()); + initial.pica_registers_size = static_cast<u32>(initial_state.pica_registers.size()); initial.default_attributes_size = static_cast<u32>(initial_state.default_attributes.size()); - initial.vs_program_binary_size = static_cast<u32>(initial_state.vs_program_binary.size()); - initial.vs_swizzle_data_size = static_cast<u32>(initial_state.vs_swizzle_data.size()); - initial.vs_float_uniforms_size = static_cast<u32>(initial_state.vs_float_uniforms.size()); - initial.gs_program_binary_size = static_cast<u32>(initial_state.gs_program_binary.size()); - initial.gs_swizzle_data_size = static_cast<u32>(initial_state.gs_swizzle_data.size()); - initial.gs_float_uniforms_size = static_cast<u32>(initial_state.gs_float_uniforms.size()); - header.stream_size = static_cast<u32>(stream.size()); - - initial.gpu_registers = sizeof(header); - initial.lcd_registers = initial.gpu_registers + initial.gpu_registers_size * sizeof(u32); - initial.pica_registers = initial.lcd_registers + initial.lcd_registers_size * sizeof(u32);; - initial.default_attributes = initial.pica_registers + initial.pica_registers_size * sizeof(u32); - initial.vs_program_binary = initial.default_attributes + initial.default_attributes_size * sizeof(u32); - initial.vs_swizzle_data = initial.vs_program_binary + initial.vs_program_binary_size * sizeof(u32); - initial.vs_float_uniforms = initial.vs_swizzle_data + initial.vs_swizzle_data_size * sizeof(u32); - initial.gs_program_binary = initial.vs_float_uniforms + initial.vs_float_uniforms_size * sizeof(u32); - initial.gs_swizzle_data = initial.gs_program_binary + initial.gs_program_binary_size * sizeof(u32); - initial.gs_float_uniforms = initial.gs_swizzle_data + initial.gs_swizzle_data_size * sizeof(u32); - header.stream_offset = initial.gs_float_uniforms + initial.gs_float_uniforms_size * sizeof(u32); + initial.vs_program_binary_size = static_cast<u32>(initial_state.vs_program_binary.size()); + initial.vs_swizzle_data_size = static_cast<u32>(initial_state.vs_swizzle_data.size()); + initial.vs_float_uniforms_size = static_cast<u32>(initial_state.vs_float_uniforms.size()); + initial.gs_program_binary_size = static_cast<u32>(initial_state.gs_program_binary.size()); + initial.gs_swizzle_data_size = static_cast<u32>(initial_state.gs_swizzle_data.size()); + initial.gs_float_uniforms_size = static_cast<u32>(initial_state.gs_float_uniforms.size()); + header.stream_size = static_cast<u32>(stream.size()); + + initial.gpu_registers = sizeof(header); + initial.lcd_registers = initial.gpu_registers + initial.gpu_registers_size * sizeof(u32); + initial.pica_registers = initial.lcd_registers + initial.lcd_registers_size * sizeof(u32); + ; + initial.default_attributes = initial.pica_registers + initial.pica_registers_size * sizeof(u32); + initial.vs_program_binary = + initial.default_attributes + initial.default_attributes_size * sizeof(u32); + initial.vs_swizzle_data = + initial.vs_program_binary + initial.vs_program_binary_size * sizeof(u32); + initial.vs_float_uniforms = + initial.vs_swizzle_data + initial.vs_swizzle_data_size * sizeof(u32); + initial.gs_program_binary = + initial.vs_float_uniforms + initial.vs_float_uniforms_size * sizeof(u32); + initial.gs_swizzle_data = + initial.gs_program_binary + initial.gs_program_binary_size * sizeof(u32); + initial.gs_float_uniforms = + initial.gs_swizzle_data + initial.gs_swizzle_data_size * sizeof(u32); + header.stream_offset = initial.gs_float_uniforms + initial.gs_float_uniforms_size * sizeof(u32); // Iterate through stream elements, update relevant stream element data for (auto& stream_element : stream) { switch (stream_element.data.type) { - case MemoryLoad: - { + case MemoryLoad: { auto& file_offset = memory_regions[stream_element.hash]; if (!stream_element.uses_existing_data) { file_offset = header.stream_offset; @@ -79,44 +81,62 @@ void Recorder::Finish(const std::string& filename) { throw "Failed to write header"; // Write initial state - written = file.WriteArray(initial_state.gpu_registers.data(), initial_state.gpu_registers.size()); + written = + file.WriteArray(initial_state.gpu_registers.data(), initial_state.gpu_registers.size()); if (written != initial_state.gpu_registers.size() || file.Tell() != initial.lcd_registers) throw "Failed to write GPU registers"; - written = file.WriteArray(initial_state.lcd_registers.data(), initial_state.lcd_registers.size()); + written = + file.WriteArray(initial_state.lcd_registers.data(), initial_state.lcd_registers.size()); if (written != initial_state.lcd_registers.size() || file.Tell() != initial.pica_registers) throw "Failed to write LCD registers"; - written = file.WriteArray(initial_state.pica_registers.data(), initial_state.pica_registers.size()); - if (written != initial_state.pica_registers.size() || file.Tell() != initial.default_attributes) + written = file.WriteArray(initial_state.pica_registers.data(), + initial_state.pica_registers.size()); + if (written != initial_state.pica_registers.size() || + file.Tell() != initial.default_attributes) throw "Failed to write Pica registers"; - written = file.WriteArray(initial_state.default_attributes.data(), initial_state.default_attributes.size()); - if (written != initial_state.default_attributes.size() || file.Tell() != initial.vs_program_binary) + written = file.WriteArray(initial_state.default_attributes.data(), + initial_state.default_attributes.size()); + if (written != initial_state.default_attributes.size() || + file.Tell() != initial.vs_program_binary) throw "Failed to write default vertex attributes"; - written = file.WriteArray(initial_state.vs_program_binary.data(), initial_state.vs_program_binary.size()); - if (written != initial_state.vs_program_binary.size() || file.Tell() != initial.vs_swizzle_data) + written = file.WriteArray(initial_state.vs_program_binary.data(), + initial_state.vs_program_binary.size()); + if (written != initial_state.vs_program_binary.size() || + file.Tell() != initial.vs_swizzle_data) throw "Failed to write vertex shader program binary"; - written = file.WriteArray(initial_state.vs_swizzle_data.data(), initial_state.vs_swizzle_data.size()); - if (written != initial_state.vs_swizzle_data.size() || file.Tell() != initial.vs_float_uniforms) + written = file.WriteArray(initial_state.vs_swizzle_data.data(), + initial_state.vs_swizzle_data.size()); + if (written != initial_state.vs_swizzle_data.size() || + file.Tell() != initial.vs_float_uniforms) throw "Failed to write vertex shader swizzle data"; - written = file.WriteArray(initial_state.vs_float_uniforms.data(), initial_state.vs_float_uniforms.size()); - if (written != initial_state.vs_float_uniforms.size() || file.Tell() != initial.gs_program_binary) + written = file.WriteArray(initial_state.vs_float_uniforms.data(), + initial_state.vs_float_uniforms.size()); + if (written != initial_state.vs_float_uniforms.size() || + file.Tell() != initial.gs_program_binary) throw "Failed to write vertex shader float uniforms"; - written = file.WriteArray(initial_state.gs_program_binary.data(), initial_state.gs_program_binary.size()); - if (written != initial_state.gs_program_binary.size() || file.Tell() != initial.gs_swizzle_data) + written = file.WriteArray(initial_state.gs_program_binary.data(), + initial_state.gs_program_binary.size()); + if (written != initial_state.gs_program_binary.size() || + file.Tell() != initial.gs_swizzle_data) throw "Failed to write geomtry shader program binary"; - written = file.WriteArray(initial_state.gs_swizzle_data.data(), initial_state.gs_swizzle_data.size()); - if (written != initial_state.gs_swizzle_data.size() || file.Tell() != initial.gs_float_uniforms) + written = file.WriteArray(initial_state.gs_swizzle_data.data(), + initial_state.gs_swizzle_data.size()); + if (written != initial_state.gs_swizzle_data.size() || + file.Tell() != initial.gs_float_uniforms) throw "Failed to write geometry shader swizzle data"; - written = file.WriteArray(initial_state.gs_float_uniforms.data(), initial_state.gs_float_uniforms.size()); - if (written != initial_state.gs_float_uniforms.size() || file.Tell() != initial.gs_float_uniforms + sizeof(u32) * initial.gs_float_uniforms_size) + written = file.WriteArray(initial_state.gs_float_uniforms.data(), + initial_state.gs_float_uniforms.size()); + if (written != initial_state.gs_float_uniforms.size() || + file.Tell() != initial.gs_float_uniforms + sizeof(u32) * initial.gs_float_uniforms_size) throw "Failed to write geometry shader float uniforms"; // Iterate through stream elements, write "extra data" @@ -124,7 +144,8 @@ void Recorder::Finish(const std::string& filename) { if (stream_element.extra_data.size() == 0) continue; - written = file.WriteBytes(stream_element.extra_data.data(), stream_element.extra_data.size()); + written = + file.WriteBytes(stream_element.extra_data.data(), stream_element.extra_data.size()); if (written != stream_element.extra_data.size()) throw "Failed to write extra data"; } @@ -137,17 +158,17 @@ void Recorder::Finish(const std::string& filename) { if (1 != file.WriteObject(stream_element.data)) throw "Failed to write stream element"; } - } catch(const char* str) { + } catch (const char* str) { LOG_ERROR(HW_GPU, "Writing CiTrace file failed: %s", str); } } void Recorder::FrameFinished() { - stream.push_back( { { FrameMarker } } ); + stream.push_back({{FrameMarker}}); } void Recorder::MemoryAccessed(const u8* data, u32 size, u32 physical_address) { - StreamElement element = { { MemoryLoad } }; + StreamElement element = {{MemoryLoad}}; element.data.memory_load.size = size; element.data.memory_load.physical_address = physical_address; @@ -166,22 +187,22 @@ void Recorder::MemoryAccessed(const u8* data, u32 size, u32 physical_address) { stream.push_back(element); } -template<typename T> +template <typename T> void Recorder::RegisterWritten(u32 physical_address, T value) { - StreamElement element = { { RegisterWrite } }; - element.data.register_write.size = (sizeof(T) == 1) ? CTRegisterWrite::SIZE_8 - : (sizeof(T) == 2) ? CTRegisterWrite::SIZE_16 - : (sizeof(T) == 4) ? CTRegisterWrite::SIZE_32 - : CTRegisterWrite::SIZE_64; + StreamElement element = {{RegisterWrite}}; + element.data.register_write.size = + (sizeof(T) == 1) ? CTRegisterWrite::SIZE_8 + : (sizeof(T) == 2) ? CTRegisterWrite::SIZE_16 + : (sizeof(T) == 4) ? CTRegisterWrite::SIZE_32 + : CTRegisterWrite::SIZE_64; element.data.register_write.physical_address = physical_address; element.data.register_write.value = value; stream.push_back(element); } -template void Recorder::RegisterWritten(u32,u8); -template void Recorder::RegisterWritten(u32,u16); -template void Recorder::RegisterWritten(u32,u32); -template void Recorder::RegisterWritten(u32,u64); - +template void Recorder::RegisterWritten(u32, u8); +template void Recorder::RegisterWritten(u32, u16); +template void Recorder::RegisterWritten(u32, u32); +template void Recorder::RegisterWritten(u32, u64); } diff --git a/src/core/tracer/recorder.h b/src/core/tracer/recorder.h index febf883c8..aea363b95 100644 --- a/src/core/tracer/recorder.h +++ b/src/core/tracer/recorder.h @@ -7,12 +7,9 @@ #include <string> #include <unordered_map> #include <vector> - #include <boost/crc.hpp> - -#include "common/common_types.h" - #include "citrace.h" +#include "common/common_types.h" namespace CiTrace { @@ -54,7 +51,7 @@ public: * Record a register write. * @note Use this whenever a GPU-related MMIO register has been written to. */ - template<typename T> + template <typename T> void RegisterWritten(u32 physical_address, T value); private: diff --git a/src/video_core/clipper.cpp b/src/video_core/clipper.cpp index db99ce666..05b5cea73 100644 --- a/src/video_core/clipper.cpp +++ b/src/video_core/clipper.cpp @@ -5,15 +5,12 @@ #include <algorithm> #include <array> #include <cstddef> - #include <boost/container/static_vector.hpp> #include <boost/container/vector.hpp> - #include "common/bit_field.h" #include "common/common_types.h" #include "common/logging/log.h" #include "common/vector_math.h" - #include "video_core/clipper.h" #include "video_core/pica.h" #include "video_core/pica_state.h" @@ -27,15 +24,10 @@ namespace Clipper { struct ClippingEdge { public: - ClippingEdge(Math::Vec4<float24> coeffs, - Math::Vec4<float24> bias = Math::Vec4<float24>(float24::FromFloat32(0), - float24::FromFloat32(0), - float24::FromFloat32(0), - float24::FromFloat32(0))) - : coeffs(coeffs), - bias(bias) - { - } + ClippingEdge(Math::Vec4<float24> coeffs, Math::Vec4<float24> bias = Math::Vec4<float24>( + float24::FromFloat32(0), float24::FromFloat32(0), + float24::FromFloat32(0), float24::FromFloat32(0))) + : coeffs(coeffs), bias(bias) {} bool IsInside(const OutputVertex& vertex) const { return Math::Dot(vertex.pos + bias, coeffs) <= float24::FromFloat32(0); @@ -59,8 +51,7 @@ private: Math::Vec4<float24> bias; }; -static void InitScreenCoordinates(OutputVertex& vtx) -{ +static void InitScreenCoordinates(OutputVertex& vtx) { struct { float24 halfsize_x; float24 offset_x; @@ -73,8 +64,8 @@ static void InitScreenCoordinates(OutputVertex& vtx) const auto& regs = g_state.regs; viewport.halfsize_x = float24::FromRaw(regs.viewport_size_x); viewport.halfsize_y = float24::FromRaw(regs.viewport_size_y); - viewport.offset_x = float24::FromFloat32(static_cast<float>(regs.viewport_corner.x)); - viewport.offset_y = float24::FromFloat32(static_cast<float>(regs.viewport_corner.y)); + viewport.offset_x = float24::FromFloat32(static_cast<float>(regs.viewport_corner.x)); + viewport.offset_y = float24::FromFloat32(static_cast<float>(regs.viewport_corner.y)); float24 inv_w = float24::FromFloat32(1.f) / vtx.pos.w; vtx.color *= inv_w; @@ -85,12 +76,14 @@ static void InitScreenCoordinates(OutputVertex& vtx) vtx.tc2 *= inv_w; vtx.pos.w = inv_w; - vtx.screenpos[0] = (vtx.pos.x * inv_w + float24::FromFloat32(1.0)) * viewport.halfsize_x + viewport.offset_x; - vtx.screenpos[1] = (vtx.pos.y * inv_w + float24::FromFloat32(1.0)) * viewport.halfsize_y + viewport.offset_y; + vtx.screenpos[0] = + (vtx.pos.x * inv_w + float24::FromFloat32(1.0)) * viewport.halfsize_x + viewport.offset_x; + vtx.screenpos[1] = + (vtx.pos.y * inv_w + float24::FromFloat32(1.0)) * viewport.halfsize_y + viewport.offset_y; vtx.screenpos[2] = vtx.pos.z * inv_w; } -void ProcessTriangle(const OutputVertex &v0, const OutputVertex &v1, const OutputVertex &v2) { +void ProcessTriangle(const OutputVertex& v0, const OutputVertex& v1, const OutputVertex& v2) { using boost::container::static_vector; // Clipping a planar n-gon against a plane will remove at least 1 vertex and introduces 2 at @@ -98,10 +91,10 @@ void ProcessTriangle(const OutputVertex &v0, const OutputVertex &v1, const Outpu // introduces at most 1 new vertex to the polygon. Since we start with a triangle and have a // fixed 6 clipping planes, the maximum number of vertices of the clipped polygon is 3 + 6 = 9. static const size_t MAX_VERTICES = 9; - static_vector<OutputVertex, MAX_VERTICES> buffer_a = { v0, v1, v2 }; + static_vector<OutputVertex, MAX_VERTICES> buffer_a = {v0, v1, v2}; static_vector<OutputVertex, MAX_VERTICES> buffer_b; auto* output_list = &buffer_a; - auto* input_list = &buffer_b; + auto* input_list = &buffer_b; // NOTE: We clip against a w=epsilon plane to guarantee that the output has a positive w value. // TODO: Not sure if this is a valid approach. Also should probably instead use the smallest @@ -110,13 +103,13 @@ void ProcessTriangle(const OutputVertex &v0, const OutputVertex &v1, const Outpu static const float24 f0 = float24::FromFloat32(0.0); static const float24 f1 = float24::FromFloat32(1.0); static const std::array<ClippingEdge, 7> clipping_edges = {{ - { Math::MakeVec( f1, f0, f0, -f1) }, // x = +w - { Math::MakeVec(-f1, f0, f0, -f1) }, // x = -w - { Math::MakeVec( f0, f1, f0, -f1) }, // y = +w - { Math::MakeVec( f0, -f1, f0, -f1) }, // y = -w - { Math::MakeVec( f0, f0, f1, f0) }, // z = 0 - { Math::MakeVec( f0, f0, -f1, -f1) }, // z = -w - { Math::MakeVec( f0, f0, f0, -f1), Math::Vec4<float24>(f0, f0, f0, EPSILON) }, // w = EPSILON + {Math::MakeVec(f1, f0, f0, -f1)}, // x = +w + {Math::MakeVec(-f1, f0, f0, -f1)}, // x = -w + {Math::MakeVec(f0, f1, f0, -f1)}, // y = +w + {Math::MakeVec(f0, -f1, f0, -f1)}, // y = -w + {Math::MakeVec(f0, f0, f1, f0)}, // z = 0 + {Math::MakeVec(f0, f0, -f1, -f1)}, // z = -w + {Math::MakeVec(f0, f0, f0, -f1), Math::Vec4<float24>(f0, f0, f0, EPSILON)}, // w = EPSILON }}; // TODO: If one vertex lies outside one of the depth clipping planes, some platforms (e.g. Wii) @@ -154,10 +147,10 @@ void ProcessTriangle(const OutputVertex &v0, const OutputVertex &v1, const Outpu InitScreenCoordinates((*output_list)[0]); InitScreenCoordinates((*output_list)[1]); - for (size_t i = 0; i < output_list->size() - 2; i ++) { + for (size_t i = 0; i < output_list->size() - 2; i++) { OutputVertex& vtx0 = (*output_list)[0]; - OutputVertex& vtx1 = (*output_list)[i+1]; - OutputVertex& vtx2 = (*output_list)[i+2]; + OutputVertex& vtx1 = (*output_list)[i + 1]; + OutputVertex& vtx2 = (*output_list)[i + 2]; InitScreenCoordinates(vtx2); @@ -165,19 +158,20 @@ void ProcessTriangle(const OutputVertex &v0, const OutputVertex &v1, const Outpu "Triangle %lu/%lu at position (%.3f, %.3f, %.3f, %.3f), " "(%.3f, %.3f, %.3f, %.3f), (%.3f, %.3f, %.3f, %.3f) and " "screen position (%.2f, %.2f, %.2f), (%.2f, %.2f, %.2f), (%.2f, %.2f, %.2f)", - i + 1, output_list->size() - 2, - vtx0.pos.x.ToFloat32(), vtx0.pos.y.ToFloat32(), vtx0.pos.z.ToFloat32(), vtx0.pos.w.ToFloat32(), - vtx1.pos.x.ToFloat32(), vtx1.pos.y.ToFloat32(), vtx1.pos.z.ToFloat32(), vtx1.pos.w.ToFloat32(), - vtx2.pos.x.ToFloat32(), vtx2.pos.y.ToFloat32(), vtx2.pos.z.ToFloat32(), vtx2.pos.w.ToFloat32(), - vtx0.screenpos.x.ToFloat32(), vtx0.screenpos.y.ToFloat32(), vtx0.screenpos.z.ToFloat32(), - vtx1.screenpos.x.ToFloat32(), vtx1.screenpos.y.ToFloat32(), vtx1.screenpos.z.ToFloat32(), - vtx2.screenpos.x.ToFloat32(), vtx2.screenpos.y.ToFloat32(), vtx2.screenpos.z.ToFloat32()); + i + 1, output_list->size() - 2, vtx0.pos.x.ToFloat32(), vtx0.pos.y.ToFloat32(), + vtx0.pos.z.ToFloat32(), vtx0.pos.w.ToFloat32(), vtx1.pos.x.ToFloat32(), + vtx1.pos.y.ToFloat32(), vtx1.pos.z.ToFloat32(), vtx1.pos.w.ToFloat32(), + vtx2.pos.x.ToFloat32(), vtx2.pos.y.ToFloat32(), vtx2.pos.z.ToFloat32(), + vtx2.pos.w.ToFloat32(), vtx0.screenpos.x.ToFloat32(), + vtx0.screenpos.y.ToFloat32(), vtx0.screenpos.z.ToFloat32(), + vtx1.screenpos.x.ToFloat32(), vtx1.screenpos.y.ToFloat32(), + vtx1.screenpos.z.ToFloat32(), vtx2.screenpos.x.ToFloat32(), + vtx2.screenpos.y.ToFloat32(), vtx2.screenpos.z.ToFloat32()); Rasterizer::ProcessTriangle(vtx0, vtx1, vtx2); } } - } // namespace } // namespace diff --git a/src/video_core/clipper.h b/src/video_core/clipper.h index f85d8d4c9..b51af0af9 100644 --- a/src/video_core/clipper.h +++ b/src/video_core/clipper.h @@ -7,7 +7,7 @@ namespace Pica { namespace Shader { - struct OutputVertex; +struct OutputVertex; } namespace Clipper { diff --git a/src/video_core/command_processor.cpp b/src/video_core/command_processor.cpp index 689859049..bb618cacd 100644 --- a/src/video_core/command_processor.cpp +++ b/src/video_core/command_processor.cpp @@ -6,17 +6,14 @@ #include <cstddef> #include <memory> #include <utility> - #include "common/assert.h" #include "common/logging/log.h" #include "common/microprofile.h" #include "common/vector_math.h" - #include "core/hle/service/gsp_gpu.h" #include "core/hw/gpu.h" #include "core/memory.h" #include "core/tracer/recorder.h" - #include "video_core/command_processor.h" #include "video_core/debug_utils/debug_utils.h" #include "video_core/pica.h" @@ -43,10 +40,8 @@ static u32 default_attr_write_buffer[3]; // Expand a 4-bit mask to 4-byte mask, e.g. 0b0101 -> 0x00FF00FF static const u32 expand_bits_to_bytes[] = { - 0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff, - 0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff, - 0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff, - 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff + 0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff, 0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff, + 0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff, 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff, }; MICROPROFILE_DEFINE(GPU_Drawing, "GPU", "Drawing", MP_RGB(50, 50, 240)); @@ -68,383 +63,393 @@ static void WritePicaReg(u32 id, u32 value, u32 mask) { regs[id] = (old_value & ~write_mask) | (value & write_mask); - DebugUtils::OnPicaRegWrite({ (u16)id, (u16)mask, regs[id] }); + DebugUtils::OnPicaRegWrite({(u16)id, (u16)mask, regs[id]}); if (g_debug_context) - g_debug_context->OnEvent(DebugContext::Event::PicaCommandLoaded, reinterpret_cast<void*>(&id)); - - switch(id) { - // Trigger IRQ - case PICA_REG_INDEX(trigger_irq): - GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::P3D); - break; - - case PICA_REG_INDEX_WORKAROUND(triangle_topology, 0x25E): - g_state.primitive_assembler.Reconfigure(regs.triangle_topology); - break; - - case PICA_REG_INDEX_WORKAROUND(restart_primitive, 0x25F): - g_state.primitive_assembler.Reset(); - break; - - case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.index, 0x232): - g_state.immediate.current_attribute = 0; + g_debug_context->OnEvent(DebugContext::Event::PicaCommandLoaded, + reinterpret_cast<void*>(&id)); + + switch (id) { + // Trigger IRQ + case PICA_REG_INDEX(trigger_irq): + GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::P3D); + break; + + case PICA_REG_INDEX_WORKAROUND(triangle_topology, 0x25E): + g_state.primitive_assembler.Reconfigure(regs.triangle_topology); + break; + + case PICA_REG_INDEX_WORKAROUND(restart_primitive, 0x25F): + g_state.primitive_assembler.Reset(); + break; + + case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.index, 0x232): + g_state.immediate.current_attribute = 0; + default_attr_counter = 0; + break; + + // Load default vertex input attributes + case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[0], 0x233): + case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[1], 0x234): + case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[2], 0x235): { + // TODO: Does actual hardware indeed keep an intermediate buffer or does + // it directly write the values? + default_attr_write_buffer[default_attr_counter++] = value; + + // Default attributes are written in a packed format such that four float24 values are + // encoded in + // three 32-bit numbers. We write to internal memory once a full such vector is + // written. + if (default_attr_counter >= 3) { default_attr_counter = 0; - break; - - // Load default vertex input attributes - case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[0], 0x233): - case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[1], 0x234): - case PICA_REG_INDEX_WORKAROUND(vs_default_attributes_setup.set_value[2], 0x235): - { - // TODO: Does actual hardware indeed keep an intermediate buffer or does - // it directly write the values? - default_attr_write_buffer[default_attr_counter++] = value; - - // Default attributes are written in a packed format such that four float24 values are encoded in - // three 32-bit numbers. We write to internal memory once a full such vector is - // written. - if (default_attr_counter >= 3) { - default_attr_counter = 0; - - auto& setup = regs.vs_default_attributes_setup; - - if (setup.index >= 16) { - LOG_ERROR(HW_GPU, "Invalid VS default attribute index %d", (int)setup.index); - break; - } - Math::Vec4<float24> attribute; + auto& setup = regs.vs_default_attributes_setup; - // NOTE: The destination component order indeed is "backwards" - attribute.w = float24::FromRaw(default_attr_write_buffer[0] >> 8); - attribute.z = float24::FromRaw(((default_attr_write_buffer[0] & 0xFF) << 16) | ((default_attr_write_buffer[1] >> 16) & 0xFFFF)); - attribute.y = float24::FromRaw(((default_attr_write_buffer[1] & 0xFFFF) << 8) | ((default_attr_write_buffer[2] >> 24) & 0xFF)); - attribute.x = float24::FromRaw(default_attr_write_buffer[2] & 0xFFFFFF); + if (setup.index >= 16) { + LOG_ERROR(HW_GPU, "Invalid VS default attribute index %d", (int)setup.index); + break; + } - LOG_TRACE(HW_GPU, "Set default VS attribute %x to (%f %f %f %f)", (int)setup.index, - attribute.x.ToFloat32(), attribute.y.ToFloat32(), attribute.z.ToFloat32(), - attribute.w.ToFloat32()); + Math::Vec4<float24> attribute; - // TODO: Verify that this actually modifies the register! - if (setup.index < 15) { - g_state.vs_default_attributes[setup.index] = attribute; - setup.index++; - } else { - // Put each attribute into an immediate input buffer. - // When all specified immediate attributes are present, the Vertex Shader is invoked and everything is - // sent to the primitive assembler. + // NOTE: The destination component order indeed is "backwards" + attribute.w = float24::FromRaw(default_attr_write_buffer[0] >> 8); + attribute.z = float24::FromRaw(((default_attr_write_buffer[0] & 0xFF) << 16) | + ((default_attr_write_buffer[1] >> 16) & 0xFFFF)); + attribute.y = float24::FromRaw(((default_attr_write_buffer[1] & 0xFFFF) << 8) | + ((default_attr_write_buffer[2] >> 24) & 0xFF)); + attribute.x = float24::FromRaw(default_attr_write_buffer[2] & 0xFFFFFF); - auto& immediate_input = g_state.immediate.input_vertex; - auto& immediate_attribute_id = g_state.immediate.current_attribute; + LOG_TRACE(HW_GPU, "Set default VS attribute %x to (%f %f %f %f)", (int)setup.index, + attribute.x.ToFloat32(), attribute.y.ToFloat32(), attribute.z.ToFloat32(), + attribute.w.ToFloat32()); - immediate_input.attr[immediate_attribute_id++] = attribute; + // TODO: Verify that this actually modifies the register! + if (setup.index < 15) { + g_state.vs_default_attributes[setup.index] = attribute; + setup.index++; + } else { + // Put each attribute into an immediate input buffer. + // When all specified immediate attributes are present, the Vertex Shader is invoked + // and everything is + // sent to the primitive assembler. - if (immediate_attribute_id >= regs.vs.num_input_attributes+1) { - immediate_attribute_id = 0; + auto& immediate_input = g_state.immediate.input_vertex; + auto& immediate_attribute_id = g_state.immediate.current_attribute; - Shader::UnitState<false> shader_unit; - g_state.vs.Setup(); + immediate_input.attr[immediate_attribute_id++] = attribute; - // Send to vertex shader - if (g_debug_context) - g_debug_context->OnEvent(DebugContext::Event::VertexShaderInvocation, static_cast<void*>(&immediate_input)); - g_state.vs.Run(shader_unit, immediate_input, regs.vs.num_input_attributes+1); - Shader::OutputVertex output_vertex = shader_unit.output_registers.ToVertex(regs.vs); + if (immediate_attribute_id >= regs.vs.num_input_attributes + 1) { + immediate_attribute_id = 0; - // Send to renderer - using Pica::Shader::OutputVertex; - auto AddTriangle = [](const OutputVertex& v0, const OutputVertex& v1, const OutputVertex& v2) { - VideoCore::g_renderer->Rasterizer()->AddTriangle(v0, v1, v2); - }; + Shader::UnitState<false> shader_unit; + g_state.vs.Setup(); - g_state.primitive_assembler.SubmitVertex(output_vertex, AddTriangle); - } + // Send to vertex shader + if (g_debug_context) + g_debug_context->OnEvent(DebugContext::Event::VertexShaderInvocation, + static_cast<void*>(&immediate_input)); + g_state.vs.Run(shader_unit, immediate_input, regs.vs.num_input_attributes + 1); + Shader::OutputVertex output_vertex = + shader_unit.output_registers.ToVertex(regs.vs); + + // Send to renderer + using Pica::Shader::OutputVertex; + auto AddTriangle = [](const OutputVertex& v0, const OutputVertex& v1, + const OutputVertex& v2) { + VideoCore::g_renderer->Rasterizer()->AddTriangle(v0, v1, v2); + }; + + g_state.primitive_assembler.SubmitVertex(output_vertex, AddTriangle); } } - break; } + break; + } - case PICA_REG_INDEX(gpu_mode): - if (regs.gpu_mode == Regs::GPUMode::Configuring) { - // Draw immediate mode triangles when GPU Mode is set to GPUMode::Configuring - VideoCore::g_renderer->Rasterizer()->DrawTriangles(); + case PICA_REG_INDEX(gpu_mode): + if (regs.gpu_mode == Regs::GPUMode::Configuring) { + // Draw immediate mode triangles when GPU Mode is set to GPUMode::Configuring + VideoCore::g_renderer->Rasterizer()->DrawTriangles(); - if (g_debug_context) { - g_debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr); - } + if (g_debug_context) { + g_debug_context->OnEvent(DebugContext::Event::FinishedPrimitiveBatch, nullptr); } - break; - - case PICA_REG_INDEX_WORKAROUND(command_buffer.trigger[0], 0x23c): - case PICA_REG_INDEX_WORKAROUND(command_buffer.trigger[1], 0x23d): - { - unsigned index = static_cast<unsigned>(id - PICA_REG_INDEX(command_buffer.trigger[0])); - u32* head_ptr = (u32*)Memory::GetPhysicalPointer(regs.command_buffer.GetPhysicalAddress(index)); - g_state.cmd_list.head_ptr = g_state.cmd_list.current_ptr = head_ptr; - g_state.cmd_list.length = regs.command_buffer.GetSize(index) / sizeof(u32); - break; } + break; + + case PICA_REG_INDEX_WORKAROUND(command_buffer.trigger[0], 0x23c): + case PICA_REG_INDEX_WORKAROUND(command_buffer.trigger[1], 0x23d): { + unsigned index = static_cast<unsigned>(id - PICA_REG_INDEX(command_buffer.trigger[0])); + u32* head_ptr = + (u32*)Memory::GetPhysicalPointer(regs.command_buffer.GetPhysicalAddress(index)); + g_state.cmd_list.head_ptr = g_state.cmd_list.current_ptr = head_ptr; + g_state.cmd_list.length = regs.command_buffer.GetSize(index) / sizeof(u32); + break; + } - // It seems like these trigger vertex rendering - case PICA_REG_INDEX(trigger_draw): - case PICA_REG_INDEX(trigger_draw_indexed): - { - MICROPROFILE_SCOPE(GPU_Drawing); + // It seems like these trigger vertex rendering + case PICA_REG_INDEX(trigger_draw): + case PICA_REG_INDEX(trigger_draw_indexed): { + MICROPROFILE_SCOPE(GPU_Drawing); #if PICA_LOG_TEV - DebugUtils::DumpTevStageConfig(regs.GetTevStages()); + DebugUtils::DumpTevStageConfig(regs.GetTevStages()); #endif - if (g_debug_context) - g_debug_context->OnEvent(DebugContext::Event::IncomingPrimitiveBatch, nullptr); - - // Processes information about internal vertex attributes to figure out how a vertex is loaded. - // Later, these can be compiled and cached. - const u32 base_address = regs.vertex_attributes.GetPhysicalBaseAddress(); - VertexLoader loader(regs); - - // Load vertices - bool is_indexed = (id == PICA_REG_INDEX(trigger_draw_indexed)); - - const auto& index_info = regs.index_array; - const u8* index_address_8 = Memory::GetPhysicalPointer(base_address + index_info.offset); - const u16* index_address_16 = reinterpret_cast<const u16*>(index_address_8); - bool index_u16 = index_info.format != 0; - - PrimitiveAssembler<Shader::OutputVertex>& primitive_assembler = g_state.primitive_assembler; - - if (g_debug_context) { - for (int i = 0; i < 3; ++i) { - const auto texture = regs.GetTextures()[i]; - if (!texture.enabled) - continue; - - u8* texture_data = Memory::GetPhysicalPointer(texture.config.GetPhysicalAddress()); - if (g_debug_context && Pica::g_debug_context->recorder) - g_debug_context->recorder->MemoryAccessed(texture_data, Pica::Regs::NibblesPerPixel(texture.format) * texture.config.width / 2 * texture.config.height, texture.config.GetPhysicalAddress()); - } + if (g_debug_context) + g_debug_context->OnEvent(DebugContext::Event::IncomingPrimitiveBatch, nullptr); + + // Processes information about internal vertex attributes to figure out how a vertex is + // loaded. + // Later, these can be compiled and cached. + const u32 base_address = regs.vertex_attributes.GetPhysicalBaseAddress(); + VertexLoader loader(regs); + + // Load vertices + bool is_indexed = (id == PICA_REG_INDEX(trigger_draw_indexed)); + + const auto& index_info = regs.index_array; + const u8* index_address_8 = Memory::GetPhysicalPointer(base_address + index_info.offset); + const u16* index_address_16 = reinterpret_cast<const u16*>(index_address_8); + bool index_u16 = index_info.format != 0; + + PrimitiveAssembler<Shader::OutputVertex>& primitive_assembler = g_state.primitive_assembler; + + if (g_debug_context) { + for (int i = 0; i < 3; ++i) { + const auto texture = regs.GetTextures()[i]; + if (!texture.enabled) + continue; + + u8* texture_data = Memory::GetPhysicalPointer(texture.config.GetPhysicalAddress()); + if (g_debug_context && Pica::g_debug_context->recorder) + g_debug_context->recorder->MemoryAccessed( + texture_data, Pica::Regs::NibblesPerPixel(texture.format) * + texture.config.width / 2 * texture.config.height, + texture.config.GetPhysicalAddress()); } + } - DebugUtils::MemoryAccessTracker memory_accesses; - - // Simple circular-replacement vertex cache - // The size has been tuned for optimal balance between hit-rate and the cost of lookup - const size_t VERTEX_CACHE_SIZE = 32; - std::array<u16, VERTEX_CACHE_SIZE> vertex_cache_ids; - std::array<Shader::OutputRegisters, VERTEX_CACHE_SIZE> vertex_cache; + DebugUtils::MemoryAccessTracker memory_accesses; - unsigned int vertex_cache_pos = 0; - vertex_cache_ids.fill(-1); + // Simple circular-replacement vertex cache + // The size has been tuned for optimal balance between hit-rate and the cost of lookup + const size_t VERTEX_CACHE_SIZE = 32; + std::array<u16, VERTEX_CACHE_SIZE> vertex_cache_ids; + std::array<Shader::OutputRegisters, VERTEX_CACHE_SIZE> vertex_cache; - Shader::UnitState<false> shader_unit; - g_state.vs.Setup(); + unsigned int vertex_cache_pos = 0; + vertex_cache_ids.fill(-1); - for (unsigned int index = 0; index < regs.num_vertices; ++index) - { - // Indexed rendering doesn't use the start offset - unsigned int vertex = is_indexed ? (index_u16 ? index_address_16[index] : index_address_8[index]) : (index + regs.vertex_offset); + Shader::UnitState<false> shader_unit; + g_state.vs.Setup(); - // -1 is a common special value used for primitive restart. Since it's unknown if - // the PICA supports it, and it would mess up the caching, guard against it here. - ASSERT(vertex != -1); + for (unsigned int index = 0; index < regs.num_vertices; ++index) { + // Indexed rendering doesn't use the start offset + unsigned int vertex = + is_indexed ? (index_u16 ? index_address_16[index] : index_address_8[index]) + : (index + regs.vertex_offset); - bool vertex_cache_hit = false; - Shader::OutputRegisters output_registers; + // -1 is a common special value used for primitive restart. Since it's unknown if + // the PICA supports it, and it would mess up the caching, guard against it here. + ASSERT(vertex != -1); - if (is_indexed) { - if (g_debug_context && Pica::g_debug_context->recorder) { - int size = index_u16 ? 2 : 1; - memory_accesses.AddAccess(base_address + index_info.offset + size * index, size); - } + bool vertex_cache_hit = false; + Shader::OutputRegisters output_registers; - for (unsigned int i = 0; i < VERTEX_CACHE_SIZE; ++i) { - if (vertex == vertex_cache_ids[i]) { - output_registers = vertex_cache[i]; - vertex_cache_hit = true; - break; - } - } + if (is_indexed) { + if (g_debug_context && Pica::g_debug_context->recorder) { + int size = index_u16 ? 2 : 1; + memory_accesses.AddAccess(base_address + index_info.offset + size * index, + size); } - if (!vertex_cache_hit) { - // Initialize data for the current vertex - Shader::InputVertex input; - loader.LoadVertex(base_address, index, vertex, input, memory_accesses); - - // Send to vertex shader - if (g_debug_context) - g_debug_context->OnEvent(DebugContext::Event::VertexShaderInvocation, (void*)&input); - g_state.vs.Run(shader_unit, input, loader.GetNumTotalAttributes()); - output_registers = shader_unit.output_registers; - - if (is_indexed) { - vertex_cache[vertex_cache_pos] = output_registers; - vertex_cache_ids[vertex_cache_pos] = vertex; - vertex_cache_pos = (vertex_cache_pos + 1) % VERTEX_CACHE_SIZE; + for (unsigned int i = 0; i < VERTEX_CACHE_SIZE; ++i) { + if (vertex == vertex_cache_ids[i]) { + output_registers = vertex_cache[i]; + vertex_cache_hit = true; + break; } } + } - // Retreive vertex from register data - Shader::OutputVertex output_vertex = output_registers.ToVertex(regs.vs); + if (!vertex_cache_hit) { + // Initialize data for the current vertex + Shader::InputVertex input; + loader.LoadVertex(base_address, index, vertex, input, memory_accesses); - // Send to renderer - using Pica::Shader::OutputVertex; - auto AddTriangle = []( - const OutputVertex& v0, const OutputVertex& v1, const OutputVertex& v2) { - VideoCore::g_renderer->Rasterizer()->AddTriangle(v0, v1, v2); - }; + // Send to vertex shader + if (g_debug_context) + g_debug_context->OnEvent(DebugContext::Event::VertexShaderInvocation, + (void*)&input); + g_state.vs.Run(shader_unit, input, loader.GetNumTotalAttributes()); + output_registers = shader_unit.output_registers; - primitive_assembler.SubmitVertex(output_vertex, AddTriangle); + if (is_indexed) { + vertex_cache[vertex_cache_pos] = output_registers; + vertex_cache_ids[vertex_cache_pos] = vertex; + vertex_cache_pos = (vertex_cache_pos + 1) % VERTEX_CACHE_SIZE; + } } - for (auto& range : memory_accesses.ranges) { - g_debug_context->recorder->MemoryAccessed(Memory::GetPhysicalPointer(range.first), - range.second, range.first); - } + // Retreive vertex from register data + Shader::OutputVertex output_vertex = output_registers.ToVertex(regs.vs); + + // Send to renderer + using Pica::Shader::OutputVertex; + auto AddTriangle = [](const OutputVertex& v0, const OutputVertex& v1, + const OutputVertex& v2) { + VideoCore::g_renderer->Rasterizer()->AddTriangle(v0, v1, v2); + }; - break; + primitive_assembler.SubmitVertex(output_vertex, AddTriangle); } - case PICA_REG_INDEX(vs.bool_uniforms): - for (unsigned i = 0; i < 16; ++i) - g_state.vs.uniforms.b[i] = (regs.vs.bool_uniforms.Value() & (1 << i)) != 0; - - break; - - case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[0], 0x2b1): - case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[1], 0x2b2): - case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[2], 0x2b3): - case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[3], 0x2b4): - { - int index = (id - PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[0], 0x2b1)); - auto values = regs.vs.int_uniforms[index]; - g_state.vs.uniforms.i[index] = Math::Vec4<u8>(values.x, values.y, values.z, values.w); - LOG_TRACE(HW_GPU, "Set integer uniform %d to %02x %02x %02x %02x", - index, values.x.Value(), values.y.Value(), values.z.Value(), values.w.Value()); - break; + for (auto& range : memory_accesses.ranges) { + g_debug_context->recorder->MemoryAccessed(Memory::GetPhysicalPointer(range.first), + range.second, range.first); } - case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[0], 0x2c1): - case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[1], 0x2c2): - case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[2], 0x2c3): - case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[3], 0x2c4): - case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[4], 0x2c5): - case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[5], 0x2c6): - case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[6], 0x2c7): - case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[7], 0x2c8): - { - auto& uniform_setup = regs.vs.uniform_setup; - - // TODO: Does actual hardware indeed keep an intermediate buffer or does - // it directly write the values? - uniform_write_buffer[float_regs_counter++] = value; - - // Uniforms are written in a packed format such that four float24 values are encoded in - // three 32-bit numbers. We write to internal memory once a full such vector is - // written. - if ((float_regs_counter >= 4 && uniform_setup.IsFloat32()) || - (float_regs_counter >= 3 && !uniform_setup.IsFloat32())) { - float_regs_counter = 0; - - auto& uniform = g_state.vs.uniforms.f[uniform_setup.index]; - - if (uniform_setup.index > 95) { - LOG_ERROR(HW_GPU, "Invalid VS uniform index %d", (int)uniform_setup.index); - break; - } + break; + } - // NOTE: The destination component order indeed is "backwards" - if (uniform_setup.IsFloat32()) { - for (auto i : {0,1,2,3}) - uniform[3 - i] = float24::FromFloat32(*(float*)(&uniform_write_buffer[i])); - } else { - // TODO: Untested - uniform.w = float24::FromRaw(uniform_write_buffer[0] >> 8); - uniform.z = float24::FromRaw(((uniform_write_buffer[0] & 0xFF) << 16) | ((uniform_write_buffer[1] >> 16) & 0xFFFF)); - uniform.y = float24::FromRaw(((uniform_write_buffer[1] & 0xFFFF) << 8) | ((uniform_write_buffer[2] >> 24) & 0xFF)); - uniform.x = float24::FromRaw(uniform_write_buffer[2] & 0xFFFFFF); - } + case PICA_REG_INDEX(vs.bool_uniforms): + for (unsigned i = 0; i < 16; ++i) + g_state.vs.uniforms.b[i] = (regs.vs.bool_uniforms.Value() & (1 << i)) != 0; + + break; + + case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[0], 0x2b1): + case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[1], 0x2b2): + case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[2], 0x2b3): + case PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[3], 0x2b4): { + int index = (id - PICA_REG_INDEX_WORKAROUND(vs.int_uniforms[0], 0x2b1)); + auto values = regs.vs.int_uniforms[index]; + g_state.vs.uniforms.i[index] = Math::Vec4<u8>(values.x, values.y, values.z, values.w); + LOG_TRACE(HW_GPU, "Set integer uniform %d to %02x %02x %02x %02x", index, values.x.Value(), + values.y.Value(), values.z.Value(), values.w.Value()); + break; + } - LOG_TRACE(HW_GPU, "Set uniform %x to (%f %f %f %f)", (int)uniform_setup.index, - uniform.x.ToFloat32(), uniform.y.ToFloat32(), uniform.z.ToFloat32(), - uniform.w.ToFloat32()); + case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[0], 0x2c1): + case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[1], 0x2c2): + case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[2], 0x2c3): + case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[3], 0x2c4): + case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[4], 0x2c5): + case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[5], 0x2c6): + case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[6], 0x2c7): + case PICA_REG_INDEX_WORKAROUND(vs.uniform_setup.set_value[7], 0x2c8): { + auto& uniform_setup = regs.vs.uniform_setup; + + // TODO: Does actual hardware indeed keep an intermediate buffer or does + // it directly write the values? + uniform_write_buffer[float_regs_counter++] = value; + + // Uniforms are written in a packed format such that four float24 values are encoded in + // three 32-bit numbers. We write to internal memory once a full such vector is + // written. + if ((float_regs_counter >= 4 && uniform_setup.IsFloat32()) || + (float_regs_counter >= 3 && !uniform_setup.IsFloat32())) { + float_regs_counter = 0; + + auto& uniform = g_state.vs.uniforms.f[uniform_setup.index]; + + if (uniform_setup.index > 95) { + LOG_ERROR(HW_GPU, "Invalid VS uniform index %d", (int)uniform_setup.index); + break; + } - // TODO: Verify that this actually modifies the register! - uniform_setup.index.Assign(uniform_setup.index + 1); + // NOTE: The destination component order indeed is "backwards" + if (uniform_setup.IsFloat32()) { + for (auto i : {0, 1, 2, 3}) + uniform[3 - i] = float24::FromFloat32(*(float*)(&uniform_write_buffer[i])); + } else { + // TODO: Untested + uniform.w = float24::FromRaw(uniform_write_buffer[0] >> 8); + uniform.z = float24::FromRaw(((uniform_write_buffer[0] & 0xFF) << 16) | + ((uniform_write_buffer[1] >> 16) & 0xFFFF)); + uniform.y = float24::FromRaw(((uniform_write_buffer[1] & 0xFFFF) << 8) | + ((uniform_write_buffer[2] >> 24) & 0xFF)); + uniform.x = float24::FromRaw(uniform_write_buffer[2] & 0xFFFFFF); } - break; - } - // Load shader program code - case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[0], 0x2cc): - case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[1], 0x2cd): - case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[2], 0x2ce): - case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[3], 0x2cf): - case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[4], 0x2d0): - case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[5], 0x2d1): - case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[6], 0x2d2): - case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[7], 0x2d3): - { - g_state.vs.program_code[regs.vs.program.offset] = value; - regs.vs.program.offset++; - break; - } + LOG_TRACE(HW_GPU, "Set uniform %x to (%f %f %f %f)", (int)uniform_setup.index, + uniform.x.ToFloat32(), uniform.y.ToFloat32(), uniform.z.ToFloat32(), + uniform.w.ToFloat32()); - // Load swizzle pattern data - case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[0], 0x2d6): - case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[1], 0x2d7): - case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[2], 0x2d8): - case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[3], 0x2d9): - case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[4], 0x2da): - case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[5], 0x2db): - case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[6], 0x2dc): - case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[7], 0x2dd): - { - g_state.vs.swizzle_data[regs.vs.swizzle_patterns.offset] = value; - regs.vs.swizzle_patterns.offset++; - break; + // TODO: Verify that this actually modifies the register! + uniform_setup.index.Assign(uniform_setup.index + 1); } + break; + } - case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[0], 0x1c8): - case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[1], 0x1c9): - case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[2], 0x1ca): - case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[3], 0x1cb): - case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[4], 0x1cc): - case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[5], 0x1cd): - case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[6], 0x1ce): - case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[7], 0x1cf): - { - auto& lut_config = regs.lighting.lut_config; - - ASSERT_MSG(lut_config.index < 256, "lut_config.index exceeded maximum value of 255!"); - - g_state.lighting.luts[lut_config.type][lut_config.index].raw = value; - lut_config.index.Assign(lut_config.index + 1); - break; - } + // Load shader program code + case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[0], 0x2cc): + case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[1], 0x2cd): + case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[2], 0x2ce): + case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[3], 0x2cf): + case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[4], 0x2d0): + case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[5], 0x2d1): + case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[6], 0x2d2): + case PICA_REG_INDEX_WORKAROUND(vs.program.set_word[7], 0x2d3): { + g_state.vs.program_code[regs.vs.program.offset] = value; + regs.vs.program.offset++; + break; + } - case PICA_REG_INDEX_WORKAROUND(fog_lut_data[0], 0xe8): - case PICA_REG_INDEX_WORKAROUND(fog_lut_data[1], 0xe9): - case PICA_REG_INDEX_WORKAROUND(fog_lut_data[2], 0xea): - case PICA_REG_INDEX_WORKAROUND(fog_lut_data[3], 0xeb): - case PICA_REG_INDEX_WORKAROUND(fog_lut_data[4], 0xec): - case PICA_REG_INDEX_WORKAROUND(fog_lut_data[5], 0xed): - case PICA_REG_INDEX_WORKAROUND(fog_lut_data[6], 0xee): - case PICA_REG_INDEX_WORKAROUND(fog_lut_data[7], 0xef): - { - g_state.fog.lut[regs.fog_lut_offset % 128].raw = value; - regs.fog_lut_offset.Assign(regs.fog_lut_offset + 1); - break; - } + // Load swizzle pattern data + case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[0], 0x2d6): + case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[1], 0x2d7): + case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[2], 0x2d8): + case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[3], 0x2d9): + case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[4], 0x2da): + case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[5], 0x2db): + case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[6], 0x2dc): + case PICA_REG_INDEX_WORKAROUND(vs.swizzle_patterns.set_word[7], 0x2dd): { + g_state.vs.swizzle_data[regs.vs.swizzle_patterns.offset] = value; + regs.vs.swizzle_patterns.offset++; + break; + } + + case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[0], 0x1c8): + case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[1], 0x1c9): + case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[2], 0x1ca): + case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[3], 0x1cb): + case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[4], 0x1cc): + case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[5], 0x1cd): + case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[6], 0x1ce): + case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[7], 0x1cf): { + auto& lut_config = regs.lighting.lut_config; + + ASSERT_MSG(lut_config.index < 256, "lut_config.index exceeded maximum value of 255!"); + + g_state.lighting.luts[lut_config.type][lut_config.index].raw = value; + lut_config.index.Assign(lut_config.index + 1); + break; + } - default: - break; + case PICA_REG_INDEX_WORKAROUND(fog_lut_data[0], 0xe8): + case PICA_REG_INDEX_WORKAROUND(fog_lut_data[1], 0xe9): + case PICA_REG_INDEX_WORKAROUND(fog_lut_data[2], 0xea): + case PICA_REG_INDEX_WORKAROUND(fog_lut_data[3], 0xeb): + case PICA_REG_INDEX_WORKAROUND(fog_lut_data[4], 0xec): + case PICA_REG_INDEX_WORKAROUND(fog_lut_data[5], 0xed): + case PICA_REG_INDEX_WORKAROUND(fog_lut_data[6], 0xee): + case PICA_REG_INDEX_WORKAROUND(fog_lut_data[7], 0xef): { + g_state.fog.lut[regs.fog_lut_offset % 128].raw = value; + regs.fog_lut_offset.Assign(regs.fog_lut_offset + 1); + break; + } + + default: + break; } VideoCore::g_renderer->Rasterizer()->NotifyPicaRegisterChanged(id); if (g_debug_context) - g_debug_context->OnEvent(DebugContext::Event::PicaCommandProcessed, reinterpret_cast<void*>(&id)); + g_debug_context->OnEvent(DebugContext::Event::PicaCommandProcessed, + reinterpret_cast<void*>(&id)); } void ProcessCommandList(const u32* list, u32 size) { @@ -458,14 +463,14 @@ void ProcessCommandList(const u32* list, u32 size) { ++g_state.cmd_list.current_ptr; u32 value = *g_state.cmd_list.current_ptr++; - const CommandHeader header = { *g_state.cmd_list.current_ptr++ }; + const CommandHeader header = {*g_state.cmd_list.current_ptr++}; WritePicaReg(header.cmd_id, value, header.parameter_mask); for (unsigned i = 0; i < header.extra_data_length; ++i) { u32 cmd = header.cmd_id + (header.group_commands ? i + 1 : 0); WritePicaReg(cmd, *g_state.cmd_list.current_ptr++, header.parameter_mask); - } + } } } diff --git a/src/video_core/command_processor.h b/src/video_core/command_processor.h index 022a71f5e..62ad2d3f3 100644 --- a/src/video_core/command_processor.h +++ b/src/video_core/command_processor.h @@ -5,7 +5,6 @@ #pragma once #include <type_traits> - #include "common/bit_field.h" #include "common/common_types.h" @@ -16,7 +15,7 @@ namespace CommandProcessor { union CommandHeader { u32 hex; - BitField< 0, 16, u32> cmd_id; + BitField<0, 16, u32> cmd_id; // parameter_mask: // Mask applied to the input value to make it possible to update @@ -25,11 +24,11 @@ union CommandHeader { // second bit: 0x0000FF00 // third bit: 0x00FF0000 // fourth bit: 0xFF000000 - BitField<16, 4, u32> parameter_mask; + BitField<16, 4, u32> parameter_mask; BitField<20, 11, u32> extra_data_length; - BitField<31, 1, u32> group_commands; + BitField<31, 1, u32> group_commands; }; static_assert(std::is_standard_layout<CommandHeader>::value == true, "CommandHeader does not use standard layout"); diff --git a/src/video_core/debug_utils/debug_utils.cpp b/src/video_core/debug_utils/debug_utils.cpp index bfa686380..8806464d9 100644 --- a/src/video_core/debug_utils/debug_utils.cpp +++ b/src/video_core/debug_utils/debug_utils.cpp @@ -20,7 +20,6 @@ #include <nihstro/bit_field.h> #include <nihstro/float24.h> #include <nihstro/shader_binary.h> - #include "common/assert.h" #include "common/bit_field.h" #include "common/color.h" @@ -29,7 +28,6 @@ #include "common/logging/log.h" #include "common/math_util.h" #include "common/vector_math.h" - #include "video_core/debug_utils/debug_utils.h" #include "video_core/pica.h" #include "video_core/pica_state.h" @@ -50,7 +48,8 @@ void DebugContext::DoOnEvent(Event event, void* data) { { std::unique_lock<std::mutex> lock(breakpoint_mutex); - // Commit the rasterizer's caches so framebuffers, render targets, etc. will show on debug widgets + // Commit the rasterizer's caches so framebuffers, render targets, etc. will show on debug + // widgets VideoCore::g_renderer->Rasterizer()->FlushAll(); // TODO: Should stop the CPU thread here once we multithread emulation. @@ -64,7 +63,7 @@ void DebugContext::DoOnEvent(Event event, void* data) { } // Wait until another thread tells us to Resume() - resume_from_breakpoint.wait(lock, [&]{ return !at_breakpoint; }); + resume_from_breakpoint.wait(lock, [&] { return !at_breakpoint; }); } } @@ -88,8 +87,9 @@ std::shared_ptr<DebugContext> g_debug_context; // TODO: Get rid of this global namespace DebugUtils { -void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, const Shader::ShaderSetup& setup, const Regs::VSOutputAttributes* output_attributes) -{ +void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, + const Shader::ShaderSetup& setup, + const Regs::VSOutputAttributes* output_attributes) { struct StuffToWrite { const u8* pointer; u32 size; @@ -97,7 +97,7 @@ void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, c std::vector<StuffToWrite> writing_queue; u32 write_offset = 0; - auto QueueForWriting = [&writing_queue,&write_offset](const u8* pointer, u32 size) { + auto QueueForWriting = [&writing_queue, &write_offset](const u8* pointer, u32 size) { writing_queue.push_back({pointer, size}); u32 old_write_offset = write_offset; write_offset += size; @@ -108,99 +108,95 @@ void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, c // into shbin format (separate type and component mask). union OutputRegisterInfo { enum Type : u64 { - POSITION = 0, + POSITION = 0, QUATERNION = 1, - COLOR = 2, - TEXCOORD0 = 3, - TEXCOORD1 = 5, - TEXCOORD2 = 6, + COLOR = 2, + TEXCOORD0 = 3, + TEXCOORD1 = 5, + TEXCOORD2 = 6, - VIEW = 8, + VIEW = 8, }; - BitField< 0, 64, u64> hex; + BitField<0, 64, u64> hex; - BitField< 0, 16, Type> type; + BitField<0, 16, Type> type; BitField<16, 16, u64> id; - BitField<32, 4, u64> component_mask; + BitField<32, 4, u64> component_mask; }; // This is put into a try-catch block to make sure we notice unknown configurations. std::vector<OutputRegisterInfo> output_info_table; - for (unsigned i = 0; i < 7; ++i) { - using OutputAttributes = Pica::Regs::VSOutputAttributes; - - // TODO: It's still unclear how the attribute components map to the register! - // Once we know that, this code probably will not make much sense anymore. - std::map<OutputAttributes::Semantic, std::pair<OutputRegisterInfo::Type, u32> > map = { - { OutputAttributes::POSITION_X, { OutputRegisterInfo::POSITION, 1} }, - { OutputAttributes::POSITION_Y, { OutputRegisterInfo::POSITION, 2} }, - { OutputAttributes::POSITION_Z, { OutputRegisterInfo::POSITION, 4} }, - { OutputAttributes::POSITION_W, { OutputRegisterInfo::POSITION, 8} }, - { OutputAttributes::QUATERNION_X, { OutputRegisterInfo::QUATERNION, 1} }, - { OutputAttributes::QUATERNION_Y, { OutputRegisterInfo::QUATERNION, 2} }, - { OutputAttributes::QUATERNION_Z, { OutputRegisterInfo::QUATERNION, 4} }, - { OutputAttributes::QUATERNION_W, { OutputRegisterInfo::QUATERNION, 8} }, - { OutputAttributes::COLOR_R, { OutputRegisterInfo::COLOR, 1} }, - { OutputAttributes::COLOR_G, { OutputRegisterInfo::COLOR, 2} }, - { OutputAttributes::COLOR_B, { OutputRegisterInfo::COLOR, 4} }, - { OutputAttributes::COLOR_A, { OutputRegisterInfo::COLOR, 8} }, - { OutputAttributes::TEXCOORD0_U, { OutputRegisterInfo::TEXCOORD0, 1} }, - { OutputAttributes::TEXCOORD0_V, { OutputRegisterInfo::TEXCOORD0, 2} }, - { OutputAttributes::TEXCOORD1_U, { OutputRegisterInfo::TEXCOORD1, 1} }, - { OutputAttributes::TEXCOORD1_V, { OutputRegisterInfo::TEXCOORD1, 2} }, - { OutputAttributes::TEXCOORD2_U, { OutputRegisterInfo::TEXCOORD2, 1} }, - { OutputAttributes::TEXCOORD2_V, { OutputRegisterInfo::TEXCOORD2, 2} }, - { OutputAttributes::VIEW_X, { OutputRegisterInfo::VIEW, 1} }, - { OutputAttributes::VIEW_Y, { OutputRegisterInfo::VIEW, 2} }, - { OutputAttributes::VIEW_Z, { OutputRegisterInfo::VIEW, 4} } - }; - - for (const auto& semantic : std::vector<OutputAttributes::Semantic>{ - output_attributes[i].map_x, - output_attributes[i].map_y, - output_attributes[i].map_z, - output_attributes[i].map_w }) { - if (semantic == OutputAttributes::INVALID) - continue; - - try { - OutputRegisterInfo::Type type = map.at(semantic).first; - u32 component_mask = map.at(semantic).second; - - auto it = std::find_if(output_info_table.begin(), output_info_table.end(), - [&i, &type](const OutputRegisterInfo& info) { - return info.id == i && info.type == type; - } - ); - - if (it == output_info_table.end()) { - output_info_table.emplace_back(); - output_info_table.back().type.Assign(type); - output_info_table.back().component_mask.Assign(component_mask); - output_info_table.back().id.Assign(i); - } else { - it->component_mask.Assign(it->component_mask | component_mask); - } - } catch (const std::out_of_range& ) { - DEBUG_ASSERT_MSG(false, "Unknown output attribute mapping"); - LOG_ERROR(HW_GPU, "Unknown output attribute mapping: %03x, %03x, %03x, %03x", - (int)output_attributes[i].map_x.Value(), - (int)output_attributes[i].map_y.Value(), - (int)output_attributes[i].map_z.Value(), - (int)output_attributes[i].map_w.Value()); + for (unsigned i = 0; i < 7; ++i) { + using OutputAttributes = Pica::Regs::VSOutputAttributes; + + // TODO: It's still unclear how the attribute components map to the register! + // Once we know that, this code probably will not make much sense anymore. + std::map<OutputAttributes::Semantic, std::pair<OutputRegisterInfo::Type, u32>> map = { + {OutputAttributes::POSITION_X, {OutputRegisterInfo::POSITION, 1}}, + {OutputAttributes::POSITION_Y, {OutputRegisterInfo::POSITION, 2}}, + {OutputAttributes::POSITION_Z, {OutputRegisterInfo::POSITION, 4}}, + {OutputAttributes::POSITION_W, {OutputRegisterInfo::POSITION, 8}}, + {OutputAttributes::QUATERNION_X, {OutputRegisterInfo::QUATERNION, 1}}, + {OutputAttributes::QUATERNION_Y, {OutputRegisterInfo::QUATERNION, 2}}, + {OutputAttributes::QUATERNION_Z, {OutputRegisterInfo::QUATERNION, 4}}, + {OutputAttributes::QUATERNION_W, {OutputRegisterInfo::QUATERNION, 8}}, + {OutputAttributes::COLOR_R, {OutputRegisterInfo::COLOR, 1}}, + {OutputAttributes::COLOR_G, {OutputRegisterInfo::COLOR, 2}}, + {OutputAttributes::COLOR_B, {OutputRegisterInfo::COLOR, 4}}, + {OutputAttributes::COLOR_A, {OutputRegisterInfo::COLOR, 8}}, + {OutputAttributes::TEXCOORD0_U, {OutputRegisterInfo::TEXCOORD0, 1}}, + {OutputAttributes::TEXCOORD0_V, {OutputRegisterInfo::TEXCOORD0, 2}}, + {OutputAttributes::TEXCOORD1_U, {OutputRegisterInfo::TEXCOORD1, 1}}, + {OutputAttributes::TEXCOORD1_V, {OutputRegisterInfo::TEXCOORD1, 2}}, + {OutputAttributes::TEXCOORD2_U, {OutputRegisterInfo::TEXCOORD2, 1}}, + {OutputAttributes::TEXCOORD2_V, {OutputRegisterInfo::TEXCOORD2, 2}}, + {OutputAttributes::VIEW_X, {OutputRegisterInfo::VIEW, 1}}, + {OutputAttributes::VIEW_Y, {OutputRegisterInfo::VIEW, 2}}, + {OutputAttributes::VIEW_Z, {OutputRegisterInfo::VIEW, 4}}, + }; + + for (const auto& semantic : std::vector<OutputAttributes::Semantic>{ + output_attributes[i].map_x, output_attributes[i].map_y, output_attributes[i].map_z, + output_attributes[i].map_w}) { + if (semantic == OutputAttributes::INVALID) + continue; + + try { + OutputRegisterInfo::Type type = map.at(semantic).first; + u32 component_mask = map.at(semantic).second; + + auto it = std::find_if(output_info_table.begin(), output_info_table.end(), + [&i, &type](const OutputRegisterInfo& info) { + return info.id == i && info.type == type; + }); + + if (it == output_info_table.end()) { + output_info_table.emplace_back(); + output_info_table.back().type.Assign(type); + output_info_table.back().component_mask.Assign(component_mask); + output_info_table.back().id.Assign(i); + } else { + it->component_mask.Assign(it->component_mask | component_mask); } + } catch (const std::out_of_range&) { + DEBUG_ASSERT_MSG(false, "Unknown output attribute mapping"); + LOG_ERROR(HW_GPU, "Unknown output attribute mapping: %03x, %03x, %03x, %03x", + (int)output_attributes[i].map_x.Value(), + (int)output_attributes[i].map_y.Value(), + (int)output_attributes[i].map_z.Value(), + (int)output_attributes[i].map_w.Value()); } } - + } struct { DVLBHeader header; u32 dvle_offset; - } dvlb{ {DVLBHeader::MAGIC_WORD, 1 } }; // 1 DVLE + } dvlb{{DVLBHeader::MAGIC_WORD, 1}}; // 1 DVLE - DVLPHeader dvlp{ DVLPHeader::MAGIC_WORD }; - DVLEHeader dvle{ DVLEHeader::MAGIC_WORD }; + DVLPHeader dvlp{DVLPHeader::MAGIC_WORD}; + DVLEHeader dvle{DVLEHeader::MAGIC_WORD}; QueueForWriting(reinterpret_cast<const u8*>(&dvlb), sizeof(dvlb)); u32 dvlp_offset = QueueForWriting(reinterpret_cast<const u8*>(&dvlp), sizeof(dvlp)); @@ -216,14 +212,16 @@ void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, c dvlp.swizzle_info_num_entries = static_cast<uint32_t>(setup.swizzle_data.size()); u32 dummy = 0; for (unsigned int i = 0; i < setup.swizzle_data.size(); ++i) { - QueueForWriting(reinterpret_cast<const u8*>(&setup.swizzle_data[i]), sizeof(setup.swizzle_data[i])); + QueueForWriting(reinterpret_cast<const u8*>(&setup.swizzle_data[i]), + sizeof(setup.swizzle_data[i])); QueueForWriting(reinterpret_cast<const u8*>(&dummy), sizeof(dummy)); } dvle.main_offset_words = config.main_offset; dvle.output_register_table_offset = write_offset - dvlb.dvle_offset; dvle.output_register_table_size = static_cast<u32>(output_info_table.size()); - QueueForWriting(reinterpret_cast<const u8*>(output_info_table.data()), static_cast<u32>(output_info_table.size() * sizeof(OutputRegisterInfo))); + QueueForWriting(reinterpret_cast<const u8*>(output_info_table.data()), + static_cast<u32>(output_info_table.size() * sizeof(OutputRegisterInfo))); // TODO: Create a label table for "main" @@ -258,10 +256,8 @@ void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, c constant.f.w = nihstro::to_float24(setup.uniforms.f[i].w.ToFloat32()); // Store constant if it's different from zero.. - if (setup.uniforms.f[i].x.ToFloat32() != 0.0 || - setup.uniforms.f[i].y.ToFloat32() != 0.0 || - setup.uniforms.f[i].z.ToFloat32() != 0.0 || - setup.uniforms.f[i].w.ToFloat32() != 0.0) + if (setup.uniforms.f[i].x.ToFloat32() != 0.0 || setup.uniforms.f[i].y.ToFloat32() != 0.0 || + setup.uniforms.f[i].z.ToFloat32() != 0.0 || setup.uniforms.f[i].w.ToFloat32() != 0.0) constant_table.emplace_back(constant); } dvle.constant_table_offset = write_offset - dvlb.dvle_offset; @@ -282,8 +278,7 @@ static std::unique_ptr<PicaTrace> pica_trace; static std::mutex pica_trace_mutex; static int is_pica_tracing = false; -void StartPicaTracing() -{ +void StartPicaTracing() { if (is_pica_tracing) { LOG_WARNING(HW_GPU, "StartPicaTracing called even though tracing already running!"); return; @@ -295,13 +290,11 @@ void StartPicaTracing() is_pica_tracing = true; } -bool IsPicaTracing() -{ +bool IsPicaTracing() { return is_pica_tracing != 0; } -void OnPicaRegWrite(PicaTrace::Write write) -{ +void OnPicaRegWrite(PicaTrace::Write write) { // Double check for is_pica_tracing to avoid pointless locking overhead if (!is_pica_tracing) return; @@ -314,8 +307,7 @@ void OnPicaRegWrite(PicaTrace::Write write) pica_trace->writes.push_back(write); } -std::unique_ptr<PicaTrace> FinishPicaTracing() -{ +std::unique_ptr<PicaTrace> FinishPicaTracing() { if (!is_pica_tracing) { LOG_WARNING(HW_GPU, "FinishPicaTracing called even though tracing isn't running!"); return {}; @@ -331,12 +323,12 @@ std::unique_ptr<PicaTrace> FinishPicaTracing() return ret; } -const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const TextureInfo& info, bool disable_alpha) { +const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const TextureInfo& info, + bool disable_alpha) { const unsigned int coarse_x = x & ~7; const unsigned int coarse_y = y & ~7; - if (info.format != Regs::TextureFormat::ETC1 && - info.format != Regs::TextureFormat::ETC1A4) { + if (info.format != Regs::TextureFormat::ETC1 && info.format != Regs::TextureFormat::ETC1A4) { // TODO(neobrain): Fix code design to unify vertical block offsets! source += coarse_y * info.stride; } @@ -344,73 +336,63 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture // TODO: Assert that width/height are multiples of block dimensions switch (info.format) { - case Regs::TextureFormat::RGBA8: - { + case Regs::TextureFormat::RGBA8: { auto res = Color::DecodeRGBA8(source + VideoCore::GetMortonOffset(x, y, 4)); - return { res.r(), res.g(), res.b(), static_cast<u8>(disable_alpha ? 255 : res.a()) }; + return {res.r(), res.g(), res.b(), static_cast<u8>(disable_alpha ? 255 : res.a())}; } - case Regs::TextureFormat::RGB8: - { + case Regs::TextureFormat::RGB8: { auto res = Color::DecodeRGB8(source + VideoCore::GetMortonOffset(x, y, 3)); - return { res.r(), res.g(), res.b(), 255 }; + return {res.r(), res.g(), res.b(), 255}; } - case Regs::TextureFormat::RGB5A1: - { + case Regs::TextureFormat::RGB5A1: { auto res = Color::DecodeRGB5A1(source + VideoCore::GetMortonOffset(x, y, 2)); - return { res.r(), res.g(), res.b(), static_cast<u8>(disable_alpha ? 255 : res.a()) }; + return {res.r(), res.g(), res.b(), static_cast<u8>(disable_alpha ? 255 : res.a())}; } - case Regs::TextureFormat::RGB565: - { + case Regs::TextureFormat::RGB565: { auto res = Color::DecodeRGB565(source + VideoCore::GetMortonOffset(x, y, 2)); - return { res.r(), res.g(), res.b(), 255 }; + return {res.r(), res.g(), res.b(), 255}; } - case Regs::TextureFormat::RGBA4: - { + case Regs::TextureFormat::RGBA4: { auto res = Color::DecodeRGBA4(source + VideoCore::GetMortonOffset(x, y, 2)); - return { res.r(), res.g(), res.b(), static_cast<u8>(disable_alpha ? 255 : res.a()) }; + return {res.r(), res.g(), res.b(), static_cast<u8>(disable_alpha ? 255 : res.a())}; } - case Regs::TextureFormat::IA8: - { + case Regs::TextureFormat::IA8: { const u8* source_ptr = source + VideoCore::GetMortonOffset(x, y, 2); if (disable_alpha) { // Show intensity as red, alpha as green - return { source_ptr[1], source_ptr[0], 0, 255 }; + return {source_ptr[1], source_ptr[0], 0, 255}; } else { - return { source_ptr[1], source_ptr[1], source_ptr[1], source_ptr[0] }; + return {source_ptr[1], source_ptr[1], source_ptr[1], source_ptr[0]}; } } - case Regs::TextureFormat::RG8: - { + case Regs::TextureFormat::RG8: { auto res = Color::DecodeRG8(source + VideoCore::GetMortonOffset(x, y, 2)); - return { res.r(), res.g(), 0, 255 }; + return {res.r(), res.g(), 0, 255}; } - case Regs::TextureFormat::I8: - { + case Regs::TextureFormat::I8: { const u8* source_ptr = source + VideoCore::GetMortonOffset(x, y, 1); - return { *source_ptr, *source_ptr, *source_ptr, 255 }; + return {*source_ptr, *source_ptr, *source_ptr, 255}; } - case Regs::TextureFormat::A8: - { + case Regs::TextureFormat::A8: { const u8* source_ptr = source + VideoCore::GetMortonOffset(x, y, 1); if (disable_alpha) { - return { *source_ptr, *source_ptr, *source_ptr, 255 }; + return {*source_ptr, *source_ptr, *source_ptr, 255}; } else { - return { 0, 0, 0, *source_ptr }; + return {0, 0, 0, *source_ptr}; } } - case Regs::TextureFormat::IA4: - { + case Regs::TextureFormat::IA4: { const u8* source_ptr = source + VideoCore::GetMortonOffset(x, y, 1); u8 i = Color::Convert4To8(((*source_ptr) & 0xF0) >> 4); @@ -418,25 +400,23 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture if (disable_alpha) { // Show intensity as red, alpha as green - return { i, a, 0, 255 }; + return {i, a, 0, 255}; } else { - return { i, i, i, a }; + return {i, i, i, a}; } } - case Regs::TextureFormat::I4: - { + case Regs::TextureFormat::I4: { u32 morton_offset = VideoCore::GetMortonOffset(x, y, 1); const u8* source_ptr = source + morton_offset / 2; u8 i = (morton_offset % 2) ? ((*source_ptr & 0xF0) >> 4) : (*source_ptr & 0xF); i = Color::Convert4To8(i); - return { i, i, i, 255 }; + return {i, i, i, 255}; } - case Regs::TextureFormat::A4: - { + case Regs::TextureFormat::A4: { u32 morton_offset = VideoCore::GetMortonOffset(x, y, 1); const u8* source_ptr = source + morton_offset / 2; @@ -444,15 +424,14 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture a = Color::Convert4To8(a); if (disable_alpha) { - return { a, a, a, 255 }; + return {a, a, a, 255}; } else { - return { 0, 0, 0, a }; + return {0, 0, 0, a}; } } case Regs::TextureFormat::ETC1: - case Regs::TextureFormat::ETC1A4: - { + case Regs::TextureFormat::ETC1A4: { bool has_alpha = (info.format == Regs::TextureFormat::ETC1A4); // ETC1 further subdivides each 8x8 tile into four 4x4 subtiles @@ -462,10 +441,9 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture int subtile_index = ((x / subtile_width) & 1) + 2 * ((y / subtile_height) & 1); unsigned subtile_bytes = has_alpha ? 2 : 1; // TODO: Name... - const u64* source_ptr = (const u64*)(source - + coarse_x * subtile_bytes * 4 - + coarse_y * subtile_bytes * 4 * (info.width / 8) - + subtile_index * subtile_bytes * 8); + const u64* source_ptr = (const u64*)(source + coarse_x * subtile_bytes * 4 + + coarse_y * subtile_bytes * 4 * (info.width / 8) + + subtile_index * subtile_bytes * 8); u64 alpha = 0xFFFFFFFFFFFFFFFF; if (has_alpha) { alpha = *source_ptr; @@ -474,7 +452,7 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture union ETC1Tile { // Each of these two is a collection of 16 bits (one per lookup value) - BitField< 0, 16, u64> table_subindexes; + BitField<0, 16, u64> table_subindexes; BitField<16, 16, u64> negation_flags; unsigned GetTableSubIndex(unsigned index) const { @@ -547,11 +525,18 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture } // Add modifier - unsigned table_index = static_cast<int>((x < 2) ? table_index_1.Value() : table_index_2.Value()); + unsigned table_index = + static_cast<int>((x < 2) ? table_index_1.Value() : table_index_2.Value()); static const std::array<std::array<u8, 2>, 8> etc1_modifier_table = {{ - {{ 2, 8 }}, {{ 5, 17 }}, {{ 9, 29 }}, {{ 13, 42 }}, - {{ 18, 60 }}, {{ 24, 80 }}, {{ 33, 106 }}, {{ 47, 183 }} + {{2, 8}}, + {{5, 17}}, + {{9, 29}}, + {{13, 42}}, + {{18, 60}}, + {{24, 80}}, + {{33, 106}}, + {{47, 183}}, }}; int modifier = etc1_modifier_table.at(table_index).at(GetTableSubIndex(texel)); @@ -564,7 +549,7 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture return ret.Cast<u8>(); } - } const *etc1_tile = reinterpret_cast<const ETC1Tile*>(source_ptr); + } const* etc1_tile = reinterpret_cast<const ETC1Tile*>(source_ptr); alpha >>= 4 * ((x & 3) * 4 + (y & 3)); return Math::MakeVec(etc1_tile->GetRGB(x & 3, y & 3), @@ -579,8 +564,7 @@ const Math::Vec4<u8> LookupTexture(const u8* source, int x, int y, const Texture } TextureInfo TextureInfo::FromPicaRegister(const Regs::TextureConfig& config, - const Regs::TextureFormat& format) -{ + const Regs::TextureFormat& format) { TextureInfo info; info.physical_address = config.GetPhysicalAddress(); info.width = config.width; @@ -595,13 +579,13 @@ TextureInfo TextureInfo::FromPicaRegister(const Regs::TextureConfig& config, static void WriteIOFile(png_structp png_ptr, png_bytep data, png_size_t length) { auto* fp = static_cast<FileUtil::IOFile*>(png_get_io_ptr(png_ptr)); if (!fp->WriteBytes(data, length)) - png_error(png_ptr, "Failed to write to output PNG file."); + png_error(png_ptr, "Failed to write to output PNG file."); } static void FlushIOFile(png_structp png_ptr) { auto* fp = static_cast<FileUtil::IOFile*>(png_get_io_ptr(png_ptr)); if (!fp->Flush()) - png_error(png_ptr, "Failed to flush to output PNG file."); + png_error(png_ptr, "Failed to flush to output PNG file."); } #endif @@ -614,7 +598,8 @@ void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data) { // Write data to file static int dump_index = 0; - std::string filename = std::string("texture_dump") + std::to_string(++dump_index) + std::string(".png"); + std::string filename = + std::string("texture_dump") + std::to_string(++dump_index) + std::string(".png"); u32 row_stride = texture_config.width * 3; u8* buf; @@ -632,7 +617,6 @@ void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data) { if (png_ptr == nullptr) { LOG_ERROR(Debug_GPU, "Could not allocate write struct"); goto finalise; - } // Initialize info structure @@ -651,9 +635,9 @@ void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data) { png_set_write_fn(png_ptr, static_cast<void*>(&fp), WriteIOFile, FlushIOFile); // Write header (8 bit color depth) - png_set_IHDR(png_ptr, info_ptr, texture_config.width, texture_config.height, - 8, PNG_COLOR_TYPE_RGB /*_ALPHA*/, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + png_set_IHDR(png_ptr, info_ptr, texture_config.width, texture_config.height, 8, + PNG_COLOR_TYPE_RGB /*_ALPHA*/, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, + PNG_FILTER_TYPE_BASE); png_text title_text; title_text.compression = PNG_TEXT_COMPRESSION_NONE; @@ -672,15 +656,14 @@ void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data) { info.stride = row_stride; info.format = g_state.regs.texture0_format; Math::Vec4<u8> texture_color = LookupTexture(data, x, y, info); - buf[3 * x + y * row_stride ] = texture_color.r(); + buf[3 * x + y * row_stride] = texture_color.r(); buf[3 * x + y * row_stride + 1] = texture_color.g(); buf[3 * x + y * row_stride + 2] = texture_color.b(); } } // Write image data - for (unsigned y = 0; y < texture_config.height; ++y) - { + for (unsigned y = 0; y < texture_config.height; ++y) { u8* row_ptr = (u8*)buf + y * row_stride; png_write_row(png_ptr, row_ptr); } @@ -691,12 +674,15 @@ void DumpTexture(const Pica::Regs::TextureConfig& texture_config, u8* data) { png_write_end(png_ptr, nullptr); finalise: - if (info_ptr != nullptr) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); - if (png_ptr != nullptr) png_destroy_write_struct(&png_ptr, (png_infopp)nullptr); + if (info_ptr != nullptr) + png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); + if (png_ptr != nullptr) + png_destroy_write_struct(&png_ptr, (png_infopp) nullptr); #endif } -static std::string ReplacePattern(const std::string& input, const std::string& pattern, const std::string& replacement) { +static std::string ReplacePattern(const std::string& input, const std::string& pattern, + const std::string& replacement) { size_t start = input.find(pattern); if (start == std::string::npos) return input; @@ -709,16 +695,16 @@ static std::string ReplacePattern(const std::string& input, const std::string& p static std::string GetTevStageConfigSourceString(const Pica::Regs::TevStageConfig::Source& source) { using Source = Pica::Regs::TevStageConfig::Source; static const std::map<Source, std::string> source_map = { - { Source::PrimaryColor, "PrimaryColor" }, - { Source::PrimaryFragmentColor, "PrimaryFragmentColor" }, - { Source::SecondaryFragmentColor, "SecondaryFragmentColor" }, - { Source::Texture0, "Texture0" }, - { Source::Texture1, "Texture1" }, - { Source::Texture2, "Texture2" }, - { Source::Texture3, "Texture3" }, - { Source::PreviousBuffer, "PreviousBuffer" }, - { Source::Constant, "Constant" }, - { Source::Previous, "Previous" }, + {Source::PrimaryColor, "PrimaryColor"}, + {Source::PrimaryFragmentColor, "PrimaryFragmentColor"}, + {Source::SecondaryFragmentColor, "SecondaryFragmentColor"}, + {Source::Texture0, "Texture0"}, + {Source::Texture1, "Texture1"}, + {Source::Texture2, "Texture2"}, + {Source::Texture3, "Texture3"}, + {Source::PreviousBuffer, "PreviousBuffer"}, + {Source::Constant, "Constant"}, + {Source::Previous, "Previous"}, }; const auto src_it = source_map.find(source); @@ -728,19 +714,21 @@ static std::string GetTevStageConfigSourceString(const Pica::Regs::TevStageConfi return src_it->second; } -static std::string GetTevStageConfigColorSourceString(const Pica::Regs::TevStageConfig::Source& source, const Pica::Regs::TevStageConfig::ColorModifier modifier) { +static std::string GetTevStageConfigColorSourceString( + const Pica::Regs::TevStageConfig::Source& source, + const Pica::Regs::TevStageConfig::ColorModifier modifier) { using ColorModifier = Pica::Regs::TevStageConfig::ColorModifier; static const std::map<ColorModifier, std::string> color_modifier_map = { - { ColorModifier::SourceColor, "%source.rgb" }, - { ColorModifier::OneMinusSourceColor, "(1.0 - %source.rgb)" }, - { ColorModifier::SourceAlpha, "%source.aaa" }, - { ColorModifier::OneMinusSourceAlpha, "(1.0 - %source.aaa)" }, - { ColorModifier::SourceRed, "%source.rrr" }, - { ColorModifier::OneMinusSourceRed, "(1.0 - %source.rrr)" }, - { ColorModifier::SourceGreen, "%source.ggg" }, - { ColorModifier::OneMinusSourceGreen, "(1.0 - %source.ggg)" }, - { ColorModifier::SourceBlue, "%source.bbb" }, - { ColorModifier::OneMinusSourceBlue, "(1.0 - %source.bbb)" }, + {ColorModifier::SourceColor, "%source.rgb"}, + {ColorModifier::OneMinusSourceColor, "(1.0 - %source.rgb)"}, + {ColorModifier::SourceAlpha, "%source.aaa"}, + {ColorModifier::OneMinusSourceAlpha, "(1.0 - %source.aaa)"}, + {ColorModifier::SourceRed, "%source.rrr"}, + {ColorModifier::OneMinusSourceRed, "(1.0 - %source.rrr)"}, + {ColorModifier::SourceGreen, "%source.ggg"}, + {ColorModifier::OneMinusSourceGreen, "(1.0 - %source.ggg)"}, + {ColorModifier::SourceBlue, "%source.bbb"}, + {ColorModifier::OneMinusSourceBlue, "(1.0 - %source.bbb)"}, }; auto src_str = GetTevStageConfigSourceString(source); @@ -752,17 +740,19 @@ static std::string GetTevStageConfigColorSourceString(const Pica::Regs::TevStage return ReplacePattern(modifier_str, "%source", src_str); } -static std::string GetTevStageConfigAlphaSourceString(const Pica::Regs::TevStageConfig::Source& source, const Pica::Regs::TevStageConfig::AlphaModifier modifier) { +static std::string GetTevStageConfigAlphaSourceString( + const Pica::Regs::TevStageConfig::Source& source, + const Pica::Regs::TevStageConfig::AlphaModifier modifier) { using AlphaModifier = Pica::Regs::TevStageConfig::AlphaModifier; static const std::map<AlphaModifier, std::string> alpha_modifier_map = { - { AlphaModifier::SourceAlpha, "%source.a" }, - { AlphaModifier::OneMinusSourceAlpha, "(1.0 - %source.a)" }, - { AlphaModifier::SourceRed, "%source.r" }, - { AlphaModifier::OneMinusSourceRed, "(1.0 - %source.r)" }, - { AlphaModifier::SourceGreen, "%source.g" }, - { AlphaModifier::OneMinusSourceGreen, "(1.0 - %source.g)" }, - { AlphaModifier::SourceBlue, "%source.b" }, - { AlphaModifier::OneMinusSourceBlue, "(1.0 - %source.b)" }, + {AlphaModifier::SourceAlpha, "%source.a"}, + {AlphaModifier::OneMinusSourceAlpha, "(1.0 - %source.a)"}, + {AlphaModifier::SourceRed, "%source.r"}, + {AlphaModifier::OneMinusSourceRed, "(1.0 - %source.r)"}, + {AlphaModifier::SourceGreen, "%source.g"}, + {AlphaModifier::OneMinusSourceGreen, "(1.0 - %source.g)"}, + {AlphaModifier::SourceBlue, "%source.b"}, + {AlphaModifier::OneMinusSourceBlue, "(1.0 - %source.b)"}, }; auto src_str = GetTevStageConfigSourceString(source); @@ -774,18 +764,19 @@ static std::string GetTevStageConfigAlphaSourceString(const Pica::Regs::TevStage return ReplacePattern(modifier_str, "%source", src_str); } -static std::string GetTevStageConfigOperationString(const Pica::Regs::TevStageConfig::Operation& operation) { +static std::string GetTevStageConfigOperationString( + const Pica::Regs::TevStageConfig::Operation& operation) { using Operation = Pica::Regs::TevStageConfig::Operation; static const std::map<Operation, std::string> combiner_map = { - { Operation::Replace, "%source1" }, - { Operation::Modulate, "(%source1 * %source2)" }, - { Operation::Add, "(%source1 + %source2)" }, - { Operation::AddSigned, "(%source1 + %source2) - 0.5" }, - { Operation::Lerp, "lerp(%source1, %source2, %source3)" }, - { Operation::Subtract, "(%source1 - %source2)" }, - { Operation::Dot3_RGB, "dot(%source1, %source2)" }, - { Operation::MultiplyThenAdd, "((%source1 * %source2) + %source3)" }, - { Operation::AddThenMultiply, "((%source1 + %source2) * %source3)" }, + {Operation::Replace, "%source1"}, + {Operation::Modulate, "(%source1 * %source2)"}, + {Operation::Add, "(%source1 + %source2)"}, + {Operation::AddSigned, "(%source1 + %source2) - 0.5"}, + {Operation::Lerp, "lerp(%source1, %source2, %source3)"}, + {Operation::Subtract, "(%source1 - %source2)"}, + {Operation::Dot3_RGB, "dot(%source1, %source2)"}, + {Operation::MultiplyThenAdd, "((%source1 * %source2) + %source3)"}, + {Operation::AddThenMultiply, "((%source1 + %source2) * %source3)"}, }; const auto op_it = combiner_map.find(operation); @@ -797,23 +788,37 @@ static std::string GetTevStageConfigOperationString(const Pica::Regs::TevStageCo std::string GetTevStageConfigColorCombinerString(const Pica::Regs::TevStageConfig& tev_stage) { auto op_str = GetTevStageConfigOperationString(tev_stage.color_op); - op_str = ReplacePattern(op_str, "%source1", GetTevStageConfigColorSourceString(tev_stage.color_source1, tev_stage.color_modifier1)); - op_str = ReplacePattern(op_str, "%source2", GetTevStageConfigColorSourceString(tev_stage.color_source2, tev_stage.color_modifier2)); - return ReplacePattern(op_str, "%source3", GetTevStageConfigColorSourceString(tev_stage.color_source3, tev_stage.color_modifier3)); + op_str = ReplacePattern( + op_str, "%source1", + GetTevStageConfigColorSourceString(tev_stage.color_source1, tev_stage.color_modifier1)); + op_str = ReplacePattern( + op_str, "%source2", + GetTevStageConfigColorSourceString(tev_stage.color_source2, tev_stage.color_modifier2)); + return ReplacePattern( + op_str, "%source3", + GetTevStageConfigColorSourceString(tev_stage.color_source3, tev_stage.color_modifier3)); } std::string GetTevStageConfigAlphaCombinerString(const Pica::Regs::TevStageConfig& tev_stage) { auto op_str = GetTevStageConfigOperationString(tev_stage.alpha_op); - op_str = ReplacePattern(op_str, "%source1", GetTevStageConfigAlphaSourceString(tev_stage.alpha_source1, tev_stage.alpha_modifier1)); - op_str = ReplacePattern(op_str, "%source2", GetTevStageConfigAlphaSourceString(tev_stage.alpha_source2, tev_stage.alpha_modifier2)); - return ReplacePattern(op_str, "%source3", GetTevStageConfigAlphaSourceString(tev_stage.alpha_source3, tev_stage.alpha_modifier3)); + op_str = ReplacePattern( + op_str, "%source1", + GetTevStageConfigAlphaSourceString(tev_stage.alpha_source1, tev_stage.alpha_modifier1)); + op_str = ReplacePattern( + op_str, "%source2", + GetTevStageConfigAlphaSourceString(tev_stage.alpha_source2, tev_stage.alpha_modifier2)); + return ReplacePattern( + op_str, "%source3", + GetTevStageConfigAlphaSourceString(tev_stage.alpha_source3, tev_stage.alpha_modifier3)); } void DumpTevStageConfig(const std::array<Pica::Regs::TevStageConfig, 6>& stages) { std::string stage_info = "Tev setup:\n"; for (size_t index = 0; index < stages.size(); ++index) { const auto& tev_stage = stages[index]; - stage_info += "Stage " + std::to_string(index) + ": " + GetTevStageConfigColorCombinerString(tev_stage) + " " + GetTevStageConfigAlphaCombinerString(tev_stage) + "\n"; + stage_info += "Stage " + std::to_string(index) + ": " + + GetTevStageConfigColorCombinerString(tev_stage) + " " + + GetTevStageConfigAlphaCombinerString(tev_stage) + "\n"; } LOG_TRACE(HW_GPU, "%s", stage_info.c_str()); } diff --git a/src/video_core/debug_utils/debug_utils.h b/src/video_core/debug_utils/debug_utils.h index 92e9734ae..189c93abb 100644 --- a/src/video_core/debug_utils/debug_utils.h +++ b/src/video_core/debug_utils/debug_utils.h @@ -15,10 +15,8 @@ #include <string> #include <utility> #include <vector> - #include "common/common_types.h" #include "common/vector_math.h" - #include "video_core/pica.h" namespace CiTrace { @@ -53,13 +51,16 @@ public: * Most importantly this is used for our debugger GUI. * * To implement event handling, override the OnPicaBreakPointHit and OnPicaResume methods. - * @warning All BreakPointObservers need to be on the same thread to guarantee thread-safe state access - * @todo Evaluate an alternative interface, in which there is only one managing observer and multiple child observers running (by design) on the same thread. + * @warning All BreakPointObservers need to be on the same thread to guarantee thread-safe state + * access + * @todo Evaluate an alternative interface, in which there is only one managing observer and + * multiple child observers running (by design) on the same thread. */ class BreakPointObserver { public: /// Constructs the object such that it observes events of the given DebugContext. - BreakPointObserver(std::shared_ptr<DebugContext> debug_context) : context_weak(debug_context) { + BreakPointObserver(std::shared_ptr<DebugContext> debug_context) + : context_weak(debug_context) { std::unique_lock<std::mutex> lock(debug_context->breakpoint_mutex); debug_context->breakpoint_observers.push_back(this); } @@ -84,15 +85,13 @@ public: * @param data Optional data pointer (if unused, this is a nullptr) * @note This function will perform nothing unless it is overridden in the child class. */ - virtual void OnPicaBreakPointHit(Event, void*) { - } + virtual void OnPicaBreakPointHit(Event, void*) {} /** * Action to perform when emulation is resumed from a breakpoint. * @note This function will perform nothing unless it is overridden in the child class. */ - virtual void OnPicaResume() { - } + virtual void OnPicaResume() {} protected: /** @@ -122,7 +121,8 @@ public: * The current thread then is halted until Resume() is called from another thread (or until * emulation is stopped). * @param event Event which has happened - * @param data Optional data pointer (pass nullptr if unused). Needs to remain valid until Resume() is called. + * @param data Optional data pointer (pass nullptr if unused). Needs to remain valid until + * Resume() is called. */ void OnEvent(Event event, void* data) { // This check is left in the header to allow the compiler to inline it. @@ -132,11 +132,12 @@ public: DoOnEvent(event, data); } - void DoOnEvent(Event event, void *data); + void DoOnEvent(Event event, void* data); /** * Resume from the current breakpoint. - * @warning Calling this from the same thread that OnEvent was called in will cause a deadlock. Calling from any other thread is safe. + * @warning Calling this from the same thread that OnEvent was called in will cause a deadlock. + * Calling from any other thread is safe. */ void Resume(); @@ -144,7 +145,7 @@ public: * Delete all set breakpoints and resume emulation. */ void ClearBreakpoints() { - for (auto &bp : breakpoints) { + for (auto& bp : breakpoints) { bp.enabled = false; } Resume(); @@ -182,8 +183,8 @@ namespace DebugUtils { #define PICA_LOG_TEV 0 void DumpShader(const std::string& filename, const Regs::ShaderConfig& config, - const Shader::ShaderSetup& setup, const Regs::VSOutputAttributes* output_attributes); - + const Shader::ShaderSetup& setup, + const Regs::VSOutputAttributes* output_attributes); // Utility class to log Pica commands. struct PicaTrace { @@ -216,7 +217,10 @@ struct TextureInfo { * @param source Source pointer to read data from * @param s,t Texture coordinates to read from * @param info TextureInfo object describing the texture setup - * @param disable_alpha This is used for debug widgets which use this method to display textures without providing a good way to visualize alpha by themselves. If true, this will return 255 for the alpha component, and either drop the information entirely or store it in an "unused" color channel. + * @param disable_alpha This is used for debug widgets which use this method to display textures + * without providing a good way to visualize alpha by themselves. If true, this will return 255 for + * the alpha component, and either drop the information entirely or store it in an "unused" color + * channel. * @todo Eventually we should get rid of the disable_alpha parameter. */ const Math::Vec4<u8> LookupTexture(const u8* source, int s, int t, const TextureInfo& info, @@ -237,7 +241,8 @@ class MemoryAccessTracker { /// Combine overlapping and close ranges void SimplifyRanges() { for (auto it = ranges.begin(); it != ranges.end(); ++it) { - // NOTE: We add 32 to the range end address to make sure "close" ranges are combined, too + // NOTE: We add 32 to the range end address to make sure "close" ranges are combined, + // too auto it2 = std::next(it); while (it2 != ranges.end() && it->first + it->second + 32 >= it2->first) { it->second = std::max(it->second, it2->first + it2->second - it->first); diff --git a/src/video_core/gpu_debugger.h b/src/video_core/gpu_debugger.h index a3aab216c..3c6636d66 100644 --- a/src/video_core/gpu_debugger.h +++ b/src/video_core/gpu_debugger.h @@ -7,20 +7,16 @@ #include <algorithm> #include <functional> #include <vector> - #include "core/hle/service/gsp_gpu.h" -class GraphicsDebugger -{ +class GraphicsDebugger { public: // Base class for all objects which need to be notified about GPU events - class DebuggerObserver - { + class DebuggerObserver { public: - DebuggerObserver() : observed(nullptr) { } + DebuggerObserver() : observed(nullptr) {} - virtual ~DebuggerObserver() - { + virtual ~DebuggerObserver() { if (observed) observed->UnregisterObserver(this); } @@ -31,15 +27,13 @@ public: * @param total_command_count Total number of commands in the GX history * @note All methods in this class are called from the GSP thread */ - virtual void GXCommandProcessed(int total_command_count) - { - const GSP_GPU::Command& cmd = observed->ReadGXCommandHistory(total_command_count-1); + virtual void GXCommandProcessed(int total_command_count) { + const GSP_GPU::Command& cmd = observed->ReadGXCommandHistory(total_command_count - 1); LOG_TRACE(Debug_GPU, "Received command: id=%x", (int)cmd.id.Value()); } protected: - const GraphicsDebugger* GetDebugger() const - { + const GraphicsDebugger* GetDebugger() const { return observed; } @@ -49,8 +43,7 @@ public: friend class GraphicsDebugger; }; - void GXCommandProcessed(u8* command_data) - { + void GXCommandProcessed(u8* command_data) { if (observers.empty()) return; @@ -60,33 +53,29 @@ public: memcpy(&cmd, command_data, sizeof(GSP_GPU::Command)); ForEachObserver([this](DebuggerObserver* observer) { - observer->GXCommandProcessed(static_cast<int>(this->gx_command_history.size())); - } ); + observer->GXCommandProcessed(static_cast<int>(this->gx_command_history.size())); + }); } - const GSP_GPU::Command& ReadGXCommandHistory(int index) const - { + const GSP_GPU::Command& ReadGXCommandHistory(int index) const { // TODO: Is this thread-safe? return gx_command_history[index]; } - void RegisterObserver(DebuggerObserver* observer) - { + void RegisterObserver(DebuggerObserver* observer) { // TODO: Check for duplicates observers.push_back(observer); observer->observed = this; } - void UnregisterObserver(DebuggerObserver* observer) - { + void UnregisterObserver(DebuggerObserver* observer) { observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end()); observer->observed = nullptr; } private: - void ForEachObserver(std::function<void (DebuggerObserver*)> func) - { - std::for_each(observers.begin(),observers.end(), func); + void ForEachObserver(std::function<void(DebuggerObserver*)> func) { + std::for_each(observers.begin(), observers.end(), func); } std::vector<DebuggerObserver*> observers; diff --git a/src/video_core/pica.cpp b/src/video_core/pica.cpp index ec78f9593..ce2bd455e 100644 --- a/src/video_core/pica.cpp +++ b/src/video_core/pica.cpp @@ -6,7 +6,6 @@ #include <iterator> #include <unordered_map> #include <utility> - #include "video_core/pica.h" #include "video_core/pica_state.h" #include "video_core/primitive_assembly.h" @@ -17,466 +16,466 @@ namespace Pica { State g_state; static const std::pair<u16, const char*> register_names[] = { - { 0x010, "GPUREG_FINALIZE" }, - - { 0x040, "GPUREG_FACECULLING_CONFIG" }, - { 0x041, "GPUREG_VIEWPORT_WIDTH" }, - { 0x042, "GPUREG_VIEWPORT_INVW" }, - { 0x043, "GPUREG_VIEWPORT_HEIGHT" }, - { 0x044, "GPUREG_VIEWPORT_INVH" }, - - { 0x047, "GPUREG_FRAGOP_CLIP" }, - { 0x048, "GPUREG_FRAGOP_CLIP_DATA0" }, - { 0x049, "GPUREG_FRAGOP_CLIP_DATA1" }, - { 0x04A, "GPUREG_FRAGOP_CLIP_DATA2" }, - { 0x04B, "GPUREG_FRAGOP_CLIP_DATA3" }, - - { 0x04D, "GPUREG_DEPTHMAP_SCALE" }, - { 0x04E, "GPUREG_DEPTHMAP_OFFSET" }, - { 0x04F, "GPUREG_SH_OUTMAP_TOTAL" }, - { 0x050, "GPUREG_SH_OUTMAP_O0" }, - { 0x051, "GPUREG_SH_OUTMAP_O1" }, - { 0x052, "GPUREG_SH_OUTMAP_O2" }, - { 0x053, "GPUREG_SH_OUTMAP_O3" }, - { 0x054, "GPUREG_SH_OUTMAP_O4" }, - { 0x055, "GPUREG_SH_OUTMAP_O5" }, - { 0x056, "GPUREG_SH_OUTMAP_O6" }, - - { 0x061, "GPUREG_EARLYDEPTH_FUNC" }, - { 0x062, "GPUREG_EARLYDEPTH_TEST1" }, - { 0x063, "GPUREG_EARLYDEPTH_CLEAR" }, - { 0x064, "GPUREG_SH_OUTATTR_MODE" }, - { 0x065, "GPUREG_SCISSORTEST_MODE" }, - { 0x066, "GPUREG_SCISSORTEST_POS" }, - { 0x067, "GPUREG_SCISSORTEST_DIM" }, - { 0x068, "GPUREG_VIEWPORT_XY" }, - - { 0x06A, "GPUREG_EARLYDEPTH_DATA" }, - - { 0x06D, "GPUREG_DEPTHMAP_ENABLE" }, - { 0x06E, "GPUREG_RENDERBUF_DIM" }, - { 0x06F, "GPUREG_SH_OUTATTR_CLOCK" }, - - { 0x080, "GPUREG_TEXUNIT_CONFIG" }, - { 0x081, "GPUREG_TEXUNIT0_BORDER_COLOR" }, - { 0x082, "GPUREG_TEXUNIT0_DIM" }, - { 0x083, "GPUREG_TEXUNIT0_PARAM" }, - { 0x084, "GPUREG_TEXUNIT0_LOD" }, - { 0x085, "GPUREG_TEXUNIT0_ADDR1" }, - { 0x086, "GPUREG_TEXUNIT0_ADDR2" }, - { 0x087, "GPUREG_TEXUNIT0_ADDR3" }, - { 0x088, "GPUREG_TEXUNIT0_ADDR4" }, - { 0x089, "GPUREG_TEXUNIT0_ADDR5" }, - { 0x08A, "GPUREG_TEXUNIT0_ADDR6" }, - { 0x08B, "GPUREG_TEXUNIT0_SHADOW" }, - - { 0x08E, "GPUREG_TEXUNIT0_TYPE" }, - { 0x08F, "GPUREG_LIGHTING_ENABLE0" }, - - { 0x091, "GPUREG_TEXUNIT1_BORDER_COLOR" }, - { 0x092, "GPUREG_TEXUNIT1_DIM" }, - { 0x093, "GPUREG_TEXUNIT1_PARAM" }, - { 0x094, "GPUREG_TEXUNIT1_LOD" }, - { 0x095, "GPUREG_TEXUNIT1_ADDR" }, - { 0x096, "GPUREG_TEXUNIT1_TYPE" }, - - { 0x099, "GPUREG_TEXUNIT2_BORDER_COLOR" }, - { 0x09A, "GPUREG_TEXUNIT2_DIM" }, - { 0x09B, "GPUREG_TEXUNIT2_PARAM" }, - { 0x09C, "GPUREG_TEXUNIT2_LOD" }, - { 0x09D, "GPUREG_TEXUNIT2_ADDR" }, - { 0x09E, "GPUREG_TEXUNIT2_TYPE" }, - - { 0x0A8, "GPUREG_TEXUNIT3_PROCTEX0" }, - { 0x0A9, "GPUREG_TEXUNIT3_PROCTEX1" }, - { 0x0AA, "GPUREG_TEXUNIT3_PROCTEX2" }, - { 0x0AB, "GPUREG_TEXUNIT3_PROCTEX3" }, - { 0x0AC, "GPUREG_TEXUNIT3_PROCTEX4" }, - { 0x0AD, "GPUREG_TEXUNIT3_PROCTEX5" }, - - { 0x0AF, "GPUREG_PROCTEX_LUT" }, - { 0x0B0, "GPUREG_PROCTEX_LUT_DATA0" }, - { 0x0B1, "GPUREG_PROCTEX_LUT_DATA1" }, - { 0x0B2, "GPUREG_PROCTEX_LUT_DATA2" }, - { 0x0B3, "GPUREG_PROCTEX_LUT_DATA3" }, - { 0x0B4, "GPUREG_PROCTEX_LUT_DATA4" }, - { 0x0B5, "GPUREG_PROCTEX_LUT_DATA5" }, - { 0x0B6, "GPUREG_PROCTEX_LUT_DATA6" }, - { 0x0B7, "GPUREG_PROCTEX_LUT_DATA7" }, - - { 0x0C0, "GPUREG_TEXENV0_SOURCE" }, - { 0x0C1, "GPUREG_TEXENV0_OPERAND" }, - { 0x0C2, "GPUREG_TEXENV0_COMBINER" }, - { 0x0C3, "GPUREG_TEXENV0_COLOR" }, - { 0x0C4, "GPUREG_TEXENV0_SCALE" }, - - { 0x0C8, "GPUREG_TEXENV1_SOURCE" }, - { 0x0C9, "GPUREG_TEXENV1_OPERAND" }, - { 0x0CA, "GPUREG_TEXENV1_COMBINER" }, - { 0x0CB, "GPUREG_TEXENV1_COLOR" }, - { 0x0CC, "GPUREG_TEXENV1_SCALE" }, - - { 0x0D0, "GPUREG_TEXENV2_SOURCE" }, - { 0x0D1, "GPUREG_TEXENV2_OPERAND" }, - { 0x0D2, "GPUREG_TEXENV2_COMBINER" }, - { 0x0D3, "GPUREG_TEXENV2_COLOR" }, - { 0x0D4, "GPUREG_TEXENV2_SCALE" }, - - { 0x0D8, "GPUREG_TEXENV3_SOURCE" }, - { 0x0D9, "GPUREG_TEXENV3_OPERAND" }, - { 0x0DA, "GPUREG_TEXENV3_COMBINER" }, - { 0x0DB, "GPUREG_TEXENV3_COLOR" }, - { 0x0DC, "GPUREG_TEXENV3_SCALE" }, - - { 0x0E0, "GPUREG_TEXENV_UPDATE_BUFFER" }, - { 0x0E1, "GPUREG_FOG_COLOR" }, - - { 0x0E4, "GPUREG_GAS_ATTENUATION" }, - { 0x0E5, "GPUREG_GAS_ACCMAX" }, - { 0x0E6, "GPUREG_FOG_LUT_INDEX" }, - - { 0x0E8, "GPUREG_FOG_LUT_DATA0" }, - { 0x0E9, "GPUREG_FOG_LUT_DATA1" }, - { 0x0EA, "GPUREG_FOG_LUT_DATA2" }, - { 0x0EB, "GPUREG_FOG_LUT_DATA3" }, - { 0x0EC, "GPUREG_FOG_LUT_DATA4" }, - { 0x0ED, "GPUREG_FOG_LUT_DATA5" }, - { 0x0EE, "GPUREG_FOG_LUT_DATA6" }, - { 0x0EF, "GPUREG_FOG_LUT_DATA7" }, - { 0x0F0, "GPUREG_TEXENV4_SOURCE" }, - { 0x0F1, "GPUREG_TEXENV4_OPERAND" }, - { 0x0F2, "GPUREG_TEXENV4_COMBINER" }, - { 0x0F3, "GPUREG_TEXENV4_COLOR" }, - { 0x0F4, "GPUREG_TEXENV4_SCALE" }, - - { 0x0F8, "GPUREG_TEXENV5_SOURCE" }, - { 0x0F9, "GPUREG_TEXENV5_OPERAND" }, - { 0x0FA, "GPUREG_TEXENV5_COMBINER" }, - { 0x0FB, "GPUREG_TEXENV5_COLOR" }, - { 0x0FC, "GPUREG_TEXENV5_SCALE" }, - { 0x0FD, "GPUREG_TEXENV_BUFFER_COLOR" }, - - { 0x100, "GPUREG_COLOR_OPERATION" }, - { 0x101, "GPUREG_BLEND_FUNC" }, - { 0x102, "GPUREG_LOGIC_OP" }, - { 0x103, "GPUREG_BLEND_COLOR" }, - { 0x104, "GPUREG_FRAGOP_ALPHA_TEST" }, - { 0x105, "GPUREG_STENCIL_TEST" }, - { 0x106, "GPUREG_STENCIL_OP" }, - { 0x107, "GPUREG_DEPTH_COLOR_MASK" }, - - { 0x110, "GPUREG_FRAMEBUFFER_INVALIDATE" }, - { 0x111, "GPUREG_FRAMEBUFFER_FLUSH" }, - { 0x112, "GPUREG_COLORBUFFER_READ" }, - { 0x113, "GPUREG_COLORBUFFER_WRITE" }, - { 0x114, "GPUREG_DEPTHBUFFER_READ" }, - { 0x115, "GPUREG_DEPTHBUFFER_WRITE" }, - { 0x116, "GPUREG_DEPTHBUFFER_FORMAT" }, - { 0x117, "GPUREG_COLORBUFFER_FORMAT" }, - { 0x118, "GPUREG_EARLYDEPTH_TEST2" }, - - { 0x11B, "GPUREG_FRAMEBUFFER_BLOCK32" }, - { 0x11C, "GPUREG_DEPTHBUFFER_LOC" }, - { 0x11D, "GPUREG_COLORBUFFER_LOC" }, - { 0x11E, "GPUREG_FRAMEBUFFER_DIM" }, - - { 0x120, "GPUREG_GAS_LIGHT_XY" }, - { 0x121, "GPUREG_GAS_LIGHT_Z" }, - { 0x122, "GPUREG_GAS_LIGHT_Z_COLOR" }, - { 0x123, "GPUREG_GAS_LUT_INDEX" }, - { 0x124, "GPUREG_GAS_LUT_DATA" }, - - { 0x126, "GPUREG_GAS_DELTAZ_DEPTH" }, - - { 0x130, "GPUREG_FRAGOP_SHADOW" }, - - { 0x140, "GPUREG_LIGHT0_SPECULAR0" }, - { 0x141, "GPUREG_LIGHT0_SPECULAR1" }, - { 0x142, "GPUREG_LIGHT0_DIFFUSE" }, - { 0x143, "GPUREG_LIGHT0_AMBIENT" }, - { 0x144, "GPUREG_LIGHT0_XY" }, - { 0x145, "GPUREG_LIGHT0_Z" }, - { 0x146, "GPUREG_LIGHT0_SPOTDIR_XY" }, - { 0x147, "GPUREG_LIGHT0_SPOTDIR_Z" }, - - { 0x149, "GPUREG_LIGHT0_CONFIG" }, - { 0x14A, "GPUREG_LIGHT0_ATTENUATION_BIAS" }, - { 0x14B, "GPUREG_LIGHT0_ATTENUATION_SCALE" }, - - { 0x150, "GPUREG_LIGHT1_SPECULAR0" }, - { 0x151, "GPUREG_LIGHT1_SPECULAR1" }, - { 0x152, "GPUREG_LIGHT1_DIFFUSE" }, - { 0x153, "GPUREG_LIGHT1_AMBIENT" }, - { 0x154, "GPUREG_LIGHT1_XY" }, - { 0x155, "GPUREG_LIGHT1_Z" }, - { 0x156, "GPUREG_LIGHT1_SPOTDIR_XY" }, - { 0x157, "GPUREG_LIGHT1_SPOTDIR_Z" }, - - { 0x159, "GPUREG_LIGHT1_CONFIG" }, - { 0x15A, "GPUREG_LIGHT1_ATTENUATION_BIAS" }, - { 0x15B, "GPUREG_LIGHT1_ATTENUATION_SCALE" }, - - { 0x160, "GPUREG_LIGHT2_SPECULAR0" }, - { 0x161, "GPUREG_LIGHT2_SPECULAR1" }, - { 0x162, "GPUREG_LIGHT2_DIFFUSE" }, - { 0x163, "GPUREG_LIGHT2_AMBIENT" }, - { 0x164, "GPUREG_LIGHT2_XY" }, - { 0x165, "GPUREG_LIGHT2_Z" }, - { 0x166, "GPUREG_LIGHT2_SPOTDIR_XY" }, - { 0x167, "GPUREG_LIGHT2_SPOTDIR_Z" }, - - { 0x169, "GPUREG_LIGHT2_CONFIG" }, - { 0x16A, "GPUREG_LIGHT2_ATTENUATION_BIAS" }, - { 0x16B, "GPUREG_LIGHT2_ATTENUATION_SCALE" }, - - { 0x170, "GPUREG_LIGHT3_SPECULAR0" }, - { 0x171, "GPUREG_LIGHT3_SPECULAR1" }, - { 0x172, "GPUREG_LIGHT3_DIFFUSE" }, - { 0x173, "GPUREG_LIGHT3_AMBIENT" }, - { 0x174, "GPUREG_LIGHT3_XY" }, - { 0x175, "GPUREG_LIGHT3_Z" }, - { 0x176, "GPUREG_LIGHT3_SPOTDIR_XY" }, - { 0x177, "GPUREG_LIGHT3_SPOTDIR_Z" }, - - { 0x179, "GPUREG_LIGHT3_CONFIG" }, - { 0x17A, "GPUREG_LIGHT3_ATTENUATION_BIAS" }, - { 0x17B, "GPUREG_LIGHT3_ATTENUATION_SCALE" }, - - { 0x180, "GPUREG_LIGHT4_SPECULAR0" }, - { 0x181, "GPUREG_LIGHT4_SPECULAR1" }, - { 0x182, "GPUREG_LIGHT4_DIFFUSE" }, - { 0x183, "GPUREG_LIGHT4_AMBIENT" }, - { 0x184, "GPUREG_LIGHT4_XY" }, - { 0x185, "GPUREG_LIGHT4_Z" }, - { 0x186, "GPUREG_LIGHT4_SPOTDIR_XY" }, - { 0x187, "GPUREG_LIGHT4_SPOTDIR_Z" }, - - { 0x189, "GPUREG_LIGHT4_CONFIG" }, - { 0x18A, "GPUREG_LIGHT4_ATTENUATION_BIAS" }, - { 0x18B, "GPUREG_LIGHT4_ATTENUATION_SCALE" }, - - { 0x190, "GPUREG_LIGHT5_SPECULAR0" }, - { 0x191, "GPUREG_LIGHT5_SPECULAR1" }, - { 0x192, "GPUREG_LIGHT5_DIFFUSE" }, - { 0x193, "GPUREG_LIGHT5_AMBIENT" }, - { 0x194, "GPUREG_LIGHT5_XY" }, - { 0x195, "GPUREG_LIGHT5_Z" }, - { 0x196, "GPUREG_LIGHT5_SPOTDIR_XY" }, - { 0x197, "GPUREG_LIGHT5_SPOTDIR_Z" }, - - { 0x199, "GPUREG_LIGHT5_CONFIG" }, - { 0x19A, "GPUREG_LIGHT5_ATTENUATION_BIAS" }, - { 0x19B, "GPUREG_LIGHT5_ATTENUATION_SCALE" }, - - { 0x1A0, "GPUREG_LIGHT6_SPECULAR0" }, - { 0x1A1, "GPUREG_LIGHT6_SPECULAR1" }, - { 0x1A2, "GPUREG_LIGHT6_DIFFUSE" }, - { 0x1A3, "GPUREG_LIGHT6_AMBIENT" }, - { 0x1A4, "GPUREG_LIGHT6_XY" }, - { 0x1A5, "GPUREG_LIGHT6_Z" }, - { 0x1A6, "GPUREG_LIGHT6_SPOTDIR_XY" }, - { 0x1A7, "GPUREG_LIGHT6_SPOTDIR_Z" }, - - { 0x1A9, "GPUREG_LIGHT6_CONFIG" }, - { 0x1AA, "GPUREG_LIGHT6_ATTENUATION_BIAS" }, - { 0x1AB, "GPUREG_LIGHT6_ATTENUATION_SCALE" }, - - { 0x1B0, "GPUREG_LIGHT7_SPECULAR0" }, - { 0x1B1, "GPUREG_LIGHT7_SPECULAR1" }, - { 0x1B2, "GPUREG_LIGHT7_DIFFUSE" }, - { 0x1B3, "GPUREG_LIGHT7_AMBIENT" }, - { 0x1B4, "GPUREG_LIGHT7_XY" }, - { 0x1B5, "GPUREG_LIGHT7_Z" }, - { 0x1B6, "GPUREG_LIGHT7_SPOTDIR_XY" }, - { 0x1B7, "GPUREG_LIGHT7_SPOTDIR_Z" }, - - { 0x1B9, "GPUREG_LIGHT7_CONFIG" }, - { 0x1BA, "GPUREG_LIGHT7_ATTENUATION_BIAS" }, - { 0x1BB, "GPUREG_LIGHT7_ATTENUATION_SCALE" }, - - { 0x1C0, "GPUREG_LIGHTING_AMBIENT" }, - - { 0x1C2, "GPUREG_LIGHTING_NUM_LIGHTS" }, - { 0x1C3, "GPUREG_LIGHTING_CONFIG0" }, - { 0x1C4, "GPUREG_LIGHTING_CONFIG1" }, - { 0x1C5, "GPUREG_LIGHTING_LUT_INDEX" }, - { 0x1C6, "GPUREG_LIGHTING_ENABLE1" }, - - { 0x1C8, "GPUREG_LIGHTING_LUT_DATA0" }, - { 0x1C9, "GPUREG_LIGHTING_LUT_DATA1" }, - { 0x1CA, "GPUREG_LIGHTING_LUT_DATA2" }, - { 0x1CB, "GPUREG_LIGHTING_LUT_DATA3" }, - { 0x1CC, "GPUREG_LIGHTING_LUT_DATA4" }, - { 0x1CD, "GPUREG_LIGHTING_LUT_DATA5" }, - { 0x1CE, "GPUREG_LIGHTING_LUT_DATA6" }, - { 0x1CF, "GPUREG_LIGHTING_LUT_DATA7" }, - { 0x1D0, "GPUREG_LIGHTING_LUTINPUT_ABS" }, - { 0x1D1, "GPUREG_LIGHTING_LUTINPUT_SELECT" }, - { 0x1D2, "GPUREG_LIGHTING_LUTINPUT_SCALE" }, - - { 0x1D9, "GPUREG_LIGHTING_LIGHT_PERMUTATION" }, - - { 0x200, "GPUREG_ATTRIBBUFFERS_LOC" }, - { 0x201, "GPUREG_ATTRIBBUFFERS_FORMAT_LOW" }, - { 0x202, "GPUREG_ATTRIBBUFFERS_FORMAT_HIGH" }, - { 0x203, "GPUREG_ATTRIBBUFFER0_OFFSET" }, - { 0x204, "GPUREG_ATTRIBBUFFER0_CONFIG1" }, - { 0x205, "GPUREG_ATTRIBBUFFER0_CONFIG2" }, - { 0x206, "GPUREG_ATTRIBBUFFER1_OFFSET" }, - { 0x207, "GPUREG_ATTRIBBUFFER1_CONFIG1" }, - { 0x208, "GPUREG_ATTRIBBUFFER1_CONFIG2" }, - { 0x209, "GPUREG_ATTRIBBUFFER2_OFFSET" }, - { 0x20A, "GPUREG_ATTRIBBUFFER2_CONFIG1" }, - { 0x20B, "GPUREG_ATTRIBBUFFER2_CONFIG2" }, - { 0x20C, "GPUREG_ATTRIBBUFFER3_OFFSET" }, - { 0x20D, "GPUREG_ATTRIBBUFFER3_CONFIG1" }, - { 0x20E, "GPUREG_ATTRIBBUFFER3_CONFIG2" }, - { 0x20F, "GPUREG_ATTRIBBUFFER4_OFFSET" }, - { 0x210, "GPUREG_ATTRIBBUFFER4_CONFIG1" }, - { 0x211, "GPUREG_ATTRIBBUFFER4_CONFIG2" }, - { 0x212, "GPUREG_ATTRIBBUFFER5_OFFSET" }, - { 0x213, "GPUREG_ATTRIBBUFFER5_CONFIG1" }, - { 0x214, "GPUREG_ATTRIBBUFFER5_CONFIG2" }, - { 0x215, "GPUREG_ATTRIBBUFFER6_OFFSET" }, - { 0x216, "GPUREG_ATTRIBBUFFER6_CONFIG1" }, - { 0x217, "GPUREG_ATTRIBBUFFER6_CONFIG2" }, - { 0x218, "GPUREG_ATTRIBBUFFER7_OFFSET" }, - { 0x219, "GPUREG_ATTRIBBUFFER7_CONFIG1" }, - { 0x21A, "GPUREG_ATTRIBBUFFER7_CONFIG2" }, - { 0x21B, "GPUREG_ATTRIBBUFFER8_OFFSET" }, - { 0x21C, "GPUREG_ATTRIBBUFFER8_CONFIG1" }, - { 0x21D, "GPUREG_ATTRIBBUFFER8_CONFIG2" }, - { 0x21E, "GPUREG_ATTRIBBUFFER9_OFFSET" }, - { 0x21F, "GPUREG_ATTRIBBUFFER9_CONFIG1" }, - { 0x220, "GPUREG_ATTRIBBUFFER9_CONFIG2" }, - { 0x221, "GPUREG_ATTRIBBUFFER10_OFFSET" }, - { 0x222, "GPUREG_ATTRIBBUFFER10_CONFIG1" }, - { 0x223, "GPUREG_ATTRIBBUFFER10_CONFIG2" }, - { 0x224, "GPUREG_ATTRIBBUFFER11_OFFSET" }, - { 0x225, "GPUREG_ATTRIBBUFFER11_CONFIG1" }, - { 0x226, "GPUREG_ATTRIBBUFFER11_CONFIG2" }, - { 0x227, "GPUREG_INDEXBUFFER_CONFIG" }, - { 0x228, "GPUREG_NUMVERTICES" }, - { 0x229, "GPUREG_GEOSTAGE_CONFIG" }, - { 0x22A, "GPUREG_VERTEX_OFFSET" }, - - { 0x22D, "GPUREG_POST_VERTEX_CACHE_NUM" }, - { 0x22E, "GPUREG_DRAWARRAYS" }, - { 0x22F, "GPUREG_DRAWELEMENTS" }, - - { 0x231, "GPUREG_VTX_FUNC" }, - { 0x232, "GPUREG_FIXEDATTRIB_INDEX" }, - { 0x233, "GPUREG_FIXEDATTRIB_DATA0" }, - { 0x234, "GPUREG_FIXEDATTRIB_DATA1" }, - { 0x235, "GPUREG_FIXEDATTRIB_DATA2" }, - - { 0x238, "GPUREG_CMDBUF_SIZE0" }, - { 0x239, "GPUREG_CMDBUF_SIZE1" }, - { 0x23A, "GPUREG_CMDBUF_ADDR0" }, - { 0x23B, "GPUREG_CMDBUF_ADDR1" }, - { 0x23C, "GPUREG_CMDBUF_JUMP0" }, - { 0x23D, "GPUREG_CMDBUF_JUMP1" }, - - { 0x242, "GPUREG_VSH_NUM_ATTR" }, - - { 0x244, "GPUREG_VSH_COM_MODE" }, - { 0x245, "GPUREG_START_DRAW_FUNC0" }, - - { 0x24A, "GPUREG_VSH_OUTMAP_TOTAL1" }, - - { 0x251, "GPUREG_VSH_OUTMAP_TOTAL2" }, - { 0x252, "GPUREG_GSH_MISC0" }, - { 0x253, "GPUREG_GEOSTAGE_CONFIG2" }, - { 0x254, "GPUREG_GSH_MISC1" }, - - { 0x25E, "GPUREG_PRIMITIVE_CONFIG" }, - { 0x25F, "GPUREG_RESTART_PRIMITIVE" }, - - { 0x280, "GPUREG_GSH_BOOLUNIFORM" }, - { 0x281, "GPUREG_GSH_INTUNIFORM_I0" }, - { 0x282, "GPUREG_GSH_INTUNIFORM_I1" }, - { 0x283, "GPUREG_GSH_INTUNIFORM_I2" }, - { 0x284, "GPUREG_GSH_INTUNIFORM_I3" }, - - { 0x289, "GPUREG_GSH_INPUTBUFFER_CONFIG" }, - { 0x28A, "GPUREG_GSH_ENTRYPOINT" }, - { 0x28B, "GPUREG_GSH_ATTRIBUTES_PERMUTATION_LOW" }, - { 0x28C, "GPUREG_GSH_ATTRIBUTES_PERMUTATION_HIGH" }, - { 0x28D, "GPUREG_GSH_OUTMAP_MASK" }, - - { 0x28F, "GPUREG_GSH_CODETRANSFER_END" }, - { 0x290, "GPUREG_GSH_FLOATUNIFORM_INDEX" }, - { 0x291, "GPUREG_GSH_FLOATUNIFORM_DATA0" }, - { 0x292, "GPUREG_GSH_FLOATUNIFORM_DATA1" }, - { 0x293, "GPUREG_GSH_FLOATUNIFORM_DATA2" }, - { 0x294, "GPUREG_GSH_FLOATUNIFORM_DATA3" }, - { 0x295, "GPUREG_GSH_FLOATUNIFORM_DATA4" }, - { 0x296, "GPUREG_GSH_FLOATUNIFORM_DATA5" }, - { 0x297, "GPUREG_GSH_FLOATUNIFORM_DATA6" }, - { 0x298, "GPUREG_GSH_FLOATUNIFORM_DATA7" }, - - { 0x29B, "GPUREG_GSH_CODETRANSFER_INDEX" }, - { 0x29C, "GPUREG_GSH_CODETRANSFER_DATA0" }, - { 0x29D, "GPUREG_GSH_CODETRANSFER_DATA1" }, - { 0x29E, "GPUREG_GSH_CODETRANSFER_DATA2" }, - { 0x29F, "GPUREG_GSH_CODETRANSFER_DATA3" }, - { 0x2A0, "GPUREG_GSH_CODETRANSFER_DATA4" }, - { 0x2A1, "GPUREG_GSH_CODETRANSFER_DATA5" }, - { 0x2A2, "GPUREG_GSH_CODETRANSFER_DATA6" }, - { 0x2A3, "GPUREG_GSH_CODETRANSFER_DATA7" }, - - { 0x2A5, "GPUREG_GSH_OPDESCS_INDEX" }, - { 0x2A6, "GPUREG_GSH_OPDESCS_DATA0" }, - { 0x2A7, "GPUREG_GSH_OPDESCS_DATA1" }, - { 0x2A8, "GPUREG_GSH_OPDESCS_DATA2" }, - { 0x2A9, "GPUREG_GSH_OPDESCS_DATA3" }, - { 0x2AA, "GPUREG_GSH_OPDESCS_DATA4" }, - { 0x2AB, "GPUREG_GSH_OPDESCS_DATA5" }, - { 0x2AC, "GPUREG_GSH_OPDESCS_DATA6" }, - { 0x2AD, "GPUREG_GSH_OPDESCS_DATA7" }, - - { 0x2B0, "GPUREG_VSH_BOOLUNIFORM" }, - { 0x2B1, "GPUREG_VSH_INTUNIFORM_I0" }, - { 0x2B2, "GPUREG_VSH_INTUNIFORM_I1" }, - { 0x2B3, "GPUREG_VSH_INTUNIFORM_I2" }, - { 0x2B4, "GPUREG_VSH_INTUNIFORM_I3" }, - - { 0x2B9, "GPUREG_VSH_INPUTBUFFER_CONFIG" }, - { 0x2BA, "GPUREG_VSH_ENTRYPOINT" }, - { 0x2BB, "GPUREG_VSH_ATTRIBUTES_PERMUTATION_LOW" }, - { 0x2BC, "GPUREG_VSH_ATTRIBUTES_PERMUTATION_HIGH" }, - { 0x2BD, "GPUREG_VSH_OUTMAP_MASK" }, - - { 0x2BF, "GPUREG_VSH_CODETRANSFER_END" }, - { 0x2C0, "GPUREG_VSH_FLOATUNIFORM_INDEX" }, - { 0x2C1, "GPUREG_VSH_FLOATUNIFORM_DATA0" }, - { 0x2C2, "GPUREG_VSH_FLOATUNIFORM_DATA1" }, - { 0x2C3, "GPUREG_VSH_FLOATUNIFORM_DATA2" }, - { 0x2C4, "GPUREG_VSH_FLOATUNIFORM_DATA3" }, - { 0x2C5, "GPUREG_VSH_FLOATUNIFORM_DATA4" }, - { 0x2C6, "GPUREG_VSH_FLOATUNIFORM_DATA5" }, - { 0x2C7, "GPUREG_VSH_FLOATUNIFORM_DATA6" }, - { 0x2C8, "GPUREG_VSH_FLOATUNIFORM_DATA7" }, - - { 0x2CB, "GPUREG_VSH_CODETRANSFER_INDEX" }, - { 0x2CC, "GPUREG_VSH_CODETRANSFER_DATA0" }, - { 0x2CD, "GPUREG_VSH_CODETRANSFER_DATA1" }, - { 0x2CE, "GPUREG_VSH_CODETRANSFER_DATA2" }, - { 0x2CF, "GPUREG_VSH_CODETRANSFER_DATA3" }, - { 0x2D0, "GPUREG_VSH_CODETRANSFER_DATA4" }, - { 0x2D1, "GPUREG_VSH_CODETRANSFER_DATA5" }, - { 0x2D2, "GPUREG_VSH_CODETRANSFER_DATA6" }, - { 0x2D3, "GPUREG_VSH_CODETRANSFER_DATA7" }, - - { 0x2D5, "GPUREG_VSH_OPDESCS_INDEX" }, - { 0x2D6, "GPUREG_VSH_OPDESCS_DATA0" }, - { 0x2D7, "GPUREG_VSH_OPDESCS_DATA1" }, - { 0x2D8, "GPUREG_VSH_OPDESCS_DATA2" }, - { 0x2D9, "GPUREG_VSH_OPDESCS_DATA3" }, - { 0x2DA, "GPUREG_VSH_OPDESCS_DATA4" }, - { 0x2DB, "GPUREG_VSH_OPDESCS_DATA5" }, - { 0x2DC, "GPUREG_VSH_OPDESCS_DATA6" }, - { 0x2DD, "GPUREG_VSH_OPDESCS_DATA7" }, + {0x010, "GPUREG_FINALIZE"}, + + {0x040, "GPUREG_FACECULLING_CONFIG"}, + {0x041, "GPUREG_VIEWPORT_WIDTH"}, + {0x042, "GPUREG_VIEWPORT_INVW"}, + {0x043, "GPUREG_VIEWPORT_HEIGHT"}, + {0x044, "GPUREG_VIEWPORT_INVH"}, + + {0x047, "GPUREG_FRAGOP_CLIP"}, + {0x048, "GPUREG_FRAGOP_CLIP_DATA0"}, + {0x049, "GPUREG_FRAGOP_CLIP_DATA1"}, + {0x04A, "GPUREG_FRAGOP_CLIP_DATA2"}, + {0x04B, "GPUREG_FRAGOP_CLIP_DATA3"}, + + {0x04D, "GPUREG_DEPTHMAP_SCALE"}, + {0x04E, "GPUREG_DEPTHMAP_OFFSET"}, + {0x04F, "GPUREG_SH_OUTMAP_TOTAL"}, + {0x050, "GPUREG_SH_OUTMAP_O0"}, + {0x051, "GPUREG_SH_OUTMAP_O1"}, + {0x052, "GPUREG_SH_OUTMAP_O2"}, + {0x053, "GPUREG_SH_OUTMAP_O3"}, + {0x054, "GPUREG_SH_OUTMAP_O4"}, + {0x055, "GPUREG_SH_OUTMAP_O5"}, + {0x056, "GPUREG_SH_OUTMAP_O6"}, + + {0x061, "GPUREG_EARLYDEPTH_FUNC"}, + {0x062, "GPUREG_EARLYDEPTH_TEST1"}, + {0x063, "GPUREG_EARLYDEPTH_CLEAR"}, + {0x064, "GPUREG_SH_OUTATTR_MODE"}, + {0x065, "GPUREG_SCISSORTEST_MODE"}, + {0x066, "GPUREG_SCISSORTEST_POS"}, + {0x067, "GPUREG_SCISSORTEST_DIM"}, + {0x068, "GPUREG_VIEWPORT_XY"}, + + {0x06A, "GPUREG_EARLYDEPTH_DATA"}, + + {0x06D, "GPUREG_DEPTHMAP_ENABLE"}, + {0x06E, "GPUREG_RENDERBUF_DIM"}, + {0x06F, "GPUREG_SH_OUTATTR_CLOCK"}, + + {0x080, "GPUREG_TEXUNIT_CONFIG"}, + {0x081, "GPUREG_TEXUNIT0_BORDER_COLOR"}, + {0x082, "GPUREG_TEXUNIT0_DIM"}, + {0x083, "GPUREG_TEXUNIT0_PARAM"}, + {0x084, "GPUREG_TEXUNIT0_LOD"}, + {0x085, "GPUREG_TEXUNIT0_ADDR1"}, + {0x086, "GPUREG_TEXUNIT0_ADDR2"}, + {0x087, "GPUREG_TEXUNIT0_ADDR3"}, + {0x088, "GPUREG_TEXUNIT0_ADDR4"}, + {0x089, "GPUREG_TEXUNIT0_ADDR5"}, + {0x08A, "GPUREG_TEXUNIT0_ADDR6"}, + {0x08B, "GPUREG_TEXUNIT0_SHADOW"}, + + {0x08E, "GPUREG_TEXUNIT0_TYPE"}, + {0x08F, "GPUREG_LIGHTING_ENABLE0"}, + + {0x091, "GPUREG_TEXUNIT1_BORDER_COLOR"}, + {0x092, "GPUREG_TEXUNIT1_DIM"}, + {0x093, "GPUREG_TEXUNIT1_PARAM"}, + {0x094, "GPUREG_TEXUNIT1_LOD"}, + {0x095, "GPUREG_TEXUNIT1_ADDR"}, + {0x096, "GPUREG_TEXUNIT1_TYPE"}, + + {0x099, "GPUREG_TEXUNIT2_BORDER_COLOR"}, + {0x09A, "GPUREG_TEXUNIT2_DIM"}, + {0x09B, "GPUREG_TEXUNIT2_PARAM"}, + {0x09C, "GPUREG_TEXUNIT2_LOD"}, + {0x09D, "GPUREG_TEXUNIT2_ADDR"}, + {0x09E, "GPUREG_TEXUNIT2_TYPE"}, + + {0x0A8, "GPUREG_TEXUNIT3_PROCTEX0"}, + {0x0A9, "GPUREG_TEXUNIT3_PROCTEX1"}, + {0x0AA, "GPUREG_TEXUNIT3_PROCTEX2"}, + {0x0AB, "GPUREG_TEXUNIT3_PROCTEX3"}, + {0x0AC, "GPUREG_TEXUNIT3_PROCTEX4"}, + {0x0AD, "GPUREG_TEXUNIT3_PROCTEX5"}, + + {0x0AF, "GPUREG_PROCTEX_LUT"}, + {0x0B0, "GPUREG_PROCTEX_LUT_DATA0"}, + {0x0B1, "GPUREG_PROCTEX_LUT_DATA1"}, + {0x0B2, "GPUREG_PROCTEX_LUT_DATA2"}, + {0x0B3, "GPUREG_PROCTEX_LUT_DATA3"}, + {0x0B4, "GPUREG_PROCTEX_LUT_DATA4"}, + {0x0B5, "GPUREG_PROCTEX_LUT_DATA5"}, + {0x0B6, "GPUREG_PROCTEX_LUT_DATA6"}, + {0x0B7, "GPUREG_PROCTEX_LUT_DATA7"}, + + {0x0C0, "GPUREG_TEXENV0_SOURCE"}, + {0x0C1, "GPUREG_TEXENV0_OPERAND"}, + {0x0C2, "GPUREG_TEXENV0_COMBINER"}, + {0x0C3, "GPUREG_TEXENV0_COLOR"}, + {0x0C4, "GPUREG_TEXENV0_SCALE"}, + + {0x0C8, "GPUREG_TEXENV1_SOURCE"}, + {0x0C9, "GPUREG_TEXENV1_OPERAND"}, + {0x0CA, "GPUREG_TEXENV1_COMBINER"}, + {0x0CB, "GPUREG_TEXENV1_COLOR"}, + {0x0CC, "GPUREG_TEXENV1_SCALE"}, + + {0x0D0, "GPUREG_TEXENV2_SOURCE"}, + {0x0D1, "GPUREG_TEXENV2_OPERAND"}, + {0x0D2, "GPUREG_TEXENV2_COMBINER"}, + {0x0D3, "GPUREG_TEXENV2_COLOR"}, + {0x0D4, "GPUREG_TEXENV2_SCALE"}, + + {0x0D8, "GPUREG_TEXENV3_SOURCE"}, + {0x0D9, "GPUREG_TEXENV3_OPERAND"}, + {0x0DA, "GPUREG_TEXENV3_COMBINER"}, + {0x0DB, "GPUREG_TEXENV3_COLOR"}, + {0x0DC, "GPUREG_TEXENV3_SCALE"}, + + {0x0E0, "GPUREG_TEXENV_UPDATE_BUFFER"}, + {0x0E1, "GPUREG_FOG_COLOR"}, + + {0x0E4, "GPUREG_GAS_ATTENUATION"}, + {0x0E5, "GPUREG_GAS_ACCMAX"}, + {0x0E6, "GPUREG_FOG_LUT_INDEX"}, + + {0x0E8, "GPUREG_FOG_LUT_DATA0"}, + {0x0E9, "GPUREG_FOG_LUT_DATA1"}, + {0x0EA, "GPUREG_FOG_LUT_DATA2"}, + {0x0EB, "GPUREG_FOG_LUT_DATA3"}, + {0x0EC, "GPUREG_FOG_LUT_DATA4"}, + {0x0ED, "GPUREG_FOG_LUT_DATA5"}, + {0x0EE, "GPUREG_FOG_LUT_DATA6"}, + {0x0EF, "GPUREG_FOG_LUT_DATA7"}, + {0x0F0, "GPUREG_TEXENV4_SOURCE"}, + {0x0F1, "GPUREG_TEXENV4_OPERAND"}, + {0x0F2, "GPUREG_TEXENV4_COMBINER"}, + {0x0F3, "GPUREG_TEXENV4_COLOR"}, + {0x0F4, "GPUREG_TEXENV4_SCALE"}, + + {0x0F8, "GPUREG_TEXENV5_SOURCE"}, + {0x0F9, "GPUREG_TEXENV5_OPERAND"}, + {0x0FA, "GPUREG_TEXENV5_COMBINER"}, + {0x0FB, "GPUREG_TEXENV5_COLOR"}, + {0x0FC, "GPUREG_TEXENV5_SCALE"}, + {0x0FD, "GPUREG_TEXENV_BUFFER_COLOR"}, + + {0x100, "GPUREG_COLOR_OPERATION"}, + {0x101, "GPUREG_BLEND_FUNC"}, + {0x102, "GPUREG_LOGIC_OP"}, + {0x103, "GPUREG_BLEND_COLOR"}, + {0x104, "GPUREG_FRAGOP_ALPHA_TEST"}, + {0x105, "GPUREG_STENCIL_TEST"}, + {0x106, "GPUREG_STENCIL_OP"}, + {0x107, "GPUREG_DEPTH_COLOR_MASK"}, + + {0x110, "GPUREG_FRAMEBUFFER_INVALIDATE"}, + {0x111, "GPUREG_FRAMEBUFFER_FLUSH"}, + {0x112, "GPUREG_COLORBUFFER_READ"}, + {0x113, "GPUREG_COLORBUFFER_WRITE"}, + {0x114, "GPUREG_DEPTHBUFFER_READ"}, + {0x115, "GPUREG_DEPTHBUFFER_WRITE"}, + {0x116, "GPUREG_DEPTHBUFFER_FORMAT"}, + {0x117, "GPUREG_COLORBUFFER_FORMAT"}, + {0x118, "GPUREG_EARLYDEPTH_TEST2"}, + + {0x11B, "GPUREG_FRAMEBUFFER_BLOCK32"}, + {0x11C, "GPUREG_DEPTHBUFFER_LOC"}, + {0x11D, "GPUREG_COLORBUFFER_LOC"}, + {0x11E, "GPUREG_FRAMEBUFFER_DIM"}, + + {0x120, "GPUREG_GAS_LIGHT_XY"}, + {0x121, "GPUREG_GAS_LIGHT_Z"}, + {0x122, "GPUREG_GAS_LIGHT_Z_COLOR"}, + {0x123, "GPUREG_GAS_LUT_INDEX"}, + {0x124, "GPUREG_GAS_LUT_DATA"}, + + {0x126, "GPUREG_GAS_DELTAZ_DEPTH"}, + + {0x130, "GPUREG_FRAGOP_SHADOW"}, + + {0x140, "GPUREG_LIGHT0_SPECULAR0"}, + {0x141, "GPUREG_LIGHT0_SPECULAR1"}, + {0x142, "GPUREG_LIGHT0_DIFFUSE"}, + {0x143, "GPUREG_LIGHT0_AMBIENT"}, + {0x144, "GPUREG_LIGHT0_XY"}, + {0x145, "GPUREG_LIGHT0_Z"}, + {0x146, "GPUREG_LIGHT0_SPOTDIR_XY"}, + {0x147, "GPUREG_LIGHT0_SPOTDIR_Z"}, + + {0x149, "GPUREG_LIGHT0_CONFIG"}, + {0x14A, "GPUREG_LIGHT0_ATTENUATION_BIAS"}, + {0x14B, "GPUREG_LIGHT0_ATTENUATION_SCALE"}, + + {0x150, "GPUREG_LIGHT1_SPECULAR0"}, + {0x151, "GPUREG_LIGHT1_SPECULAR1"}, + {0x152, "GPUREG_LIGHT1_DIFFUSE"}, + {0x153, "GPUREG_LIGHT1_AMBIENT"}, + {0x154, "GPUREG_LIGHT1_XY"}, + {0x155, "GPUREG_LIGHT1_Z"}, + {0x156, "GPUREG_LIGHT1_SPOTDIR_XY"}, + {0x157, "GPUREG_LIGHT1_SPOTDIR_Z"}, + + {0x159, "GPUREG_LIGHT1_CONFIG"}, + {0x15A, "GPUREG_LIGHT1_ATTENUATION_BIAS"}, + {0x15B, "GPUREG_LIGHT1_ATTENUATION_SCALE"}, + + {0x160, "GPUREG_LIGHT2_SPECULAR0"}, + {0x161, "GPUREG_LIGHT2_SPECULAR1"}, + {0x162, "GPUREG_LIGHT2_DIFFUSE"}, + {0x163, "GPUREG_LIGHT2_AMBIENT"}, + {0x164, "GPUREG_LIGHT2_XY"}, + {0x165, "GPUREG_LIGHT2_Z"}, + {0x166, "GPUREG_LIGHT2_SPOTDIR_XY"}, + {0x167, "GPUREG_LIGHT2_SPOTDIR_Z"}, + + {0x169, "GPUREG_LIGHT2_CONFIG"}, + {0x16A, "GPUREG_LIGHT2_ATTENUATION_BIAS"}, + {0x16B, "GPUREG_LIGHT2_ATTENUATION_SCALE"}, + + {0x170, "GPUREG_LIGHT3_SPECULAR0"}, + {0x171, "GPUREG_LIGHT3_SPECULAR1"}, + {0x172, "GPUREG_LIGHT3_DIFFUSE"}, + {0x173, "GPUREG_LIGHT3_AMBIENT"}, + {0x174, "GPUREG_LIGHT3_XY"}, + {0x175, "GPUREG_LIGHT3_Z"}, + {0x176, "GPUREG_LIGHT3_SPOTDIR_XY"}, + {0x177, "GPUREG_LIGHT3_SPOTDIR_Z"}, + + {0x179, "GPUREG_LIGHT3_CONFIG"}, + {0x17A, "GPUREG_LIGHT3_ATTENUATION_BIAS"}, + {0x17B, "GPUREG_LIGHT3_ATTENUATION_SCALE"}, + + {0x180, "GPUREG_LIGHT4_SPECULAR0"}, + {0x181, "GPUREG_LIGHT4_SPECULAR1"}, + {0x182, "GPUREG_LIGHT4_DIFFUSE"}, + {0x183, "GPUREG_LIGHT4_AMBIENT"}, + {0x184, "GPUREG_LIGHT4_XY"}, + {0x185, "GPUREG_LIGHT4_Z"}, + {0x186, "GPUREG_LIGHT4_SPOTDIR_XY"}, + {0x187, "GPUREG_LIGHT4_SPOTDIR_Z"}, + + {0x189, "GPUREG_LIGHT4_CONFIG"}, + {0x18A, "GPUREG_LIGHT4_ATTENUATION_BIAS"}, + {0x18B, "GPUREG_LIGHT4_ATTENUATION_SCALE"}, + + {0x190, "GPUREG_LIGHT5_SPECULAR0"}, + {0x191, "GPUREG_LIGHT5_SPECULAR1"}, + {0x192, "GPUREG_LIGHT5_DIFFUSE"}, + {0x193, "GPUREG_LIGHT5_AMBIENT"}, + {0x194, "GPUREG_LIGHT5_XY"}, + {0x195, "GPUREG_LIGHT5_Z"}, + {0x196, "GPUREG_LIGHT5_SPOTDIR_XY"}, + {0x197, "GPUREG_LIGHT5_SPOTDIR_Z"}, + + {0x199, "GPUREG_LIGHT5_CONFIG"}, + {0x19A, "GPUREG_LIGHT5_ATTENUATION_BIAS"}, + {0x19B, "GPUREG_LIGHT5_ATTENUATION_SCALE"}, + + {0x1A0, "GPUREG_LIGHT6_SPECULAR0"}, + {0x1A1, "GPUREG_LIGHT6_SPECULAR1"}, + {0x1A2, "GPUREG_LIGHT6_DIFFUSE"}, + {0x1A3, "GPUREG_LIGHT6_AMBIENT"}, + {0x1A4, "GPUREG_LIGHT6_XY"}, + {0x1A5, "GPUREG_LIGHT6_Z"}, + {0x1A6, "GPUREG_LIGHT6_SPOTDIR_XY"}, + {0x1A7, "GPUREG_LIGHT6_SPOTDIR_Z"}, + + {0x1A9, "GPUREG_LIGHT6_CONFIG"}, + {0x1AA, "GPUREG_LIGHT6_ATTENUATION_BIAS"}, + {0x1AB, "GPUREG_LIGHT6_ATTENUATION_SCALE"}, + + {0x1B0, "GPUREG_LIGHT7_SPECULAR0"}, + {0x1B1, "GPUREG_LIGHT7_SPECULAR1"}, + {0x1B2, "GPUREG_LIGHT7_DIFFUSE"}, + {0x1B3, "GPUREG_LIGHT7_AMBIENT"}, + {0x1B4, "GPUREG_LIGHT7_XY"}, + {0x1B5, "GPUREG_LIGHT7_Z"}, + {0x1B6, "GPUREG_LIGHT7_SPOTDIR_XY"}, + {0x1B7, "GPUREG_LIGHT7_SPOTDIR_Z"}, + + {0x1B9, "GPUREG_LIGHT7_CONFIG"}, + {0x1BA, "GPUREG_LIGHT7_ATTENUATION_BIAS"}, + {0x1BB, "GPUREG_LIGHT7_ATTENUATION_SCALE"}, + + {0x1C0, "GPUREG_LIGHTING_AMBIENT"}, + + {0x1C2, "GPUREG_LIGHTING_NUM_LIGHTS"}, + {0x1C3, "GPUREG_LIGHTING_CONFIG0"}, + {0x1C4, "GPUREG_LIGHTING_CONFIG1"}, + {0x1C5, "GPUREG_LIGHTING_LUT_INDEX"}, + {0x1C6, "GPUREG_LIGHTING_ENABLE1"}, + + {0x1C8, "GPUREG_LIGHTING_LUT_DATA0"}, + {0x1C9, "GPUREG_LIGHTING_LUT_DATA1"}, + {0x1CA, "GPUREG_LIGHTING_LUT_DATA2"}, + {0x1CB, "GPUREG_LIGHTING_LUT_DATA3"}, + {0x1CC, "GPUREG_LIGHTING_LUT_DATA4"}, + {0x1CD, "GPUREG_LIGHTING_LUT_DATA5"}, + {0x1CE, "GPUREG_LIGHTING_LUT_DATA6"}, + {0x1CF, "GPUREG_LIGHTING_LUT_DATA7"}, + {0x1D0, "GPUREG_LIGHTING_LUTINPUT_ABS"}, + {0x1D1, "GPUREG_LIGHTING_LUTINPUT_SELECT"}, + {0x1D2, "GPUREG_LIGHTING_LUTINPUT_SCALE"}, + + {0x1D9, "GPUREG_LIGHTING_LIGHT_PERMUTATION"}, + + {0x200, "GPUREG_ATTRIBBUFFERS_LOC"}, + {0x201, "GPUREG_ATTRIBBUFFERS_FORMAT_LOW"}, + {0x202, "GPUREG_ATTRIBBUFFERS_FORMAT_HIGH"}, + {0x203, "GPUREG_ATTRIBBUFFER0_OFFSET"}, + {0x204, "GPUREG_ATTRIBBUFFER0_CONFIG1"}, + {0x205, "GPUREG_ATTRIBBUFFER0_CONFIG2"}, + {0x206, "GPUREG_ATTRIBBUFFER1_OFFSET"}, + {0x207, "GPUREG_ATTRIBBUFFER1_CONFIG1"}, + {0x208, "GPUREG_ATTRIBBUFFER1_CONFIG2"}, + {0x209, "GPUREG_ATTRIBBUFFER2_OFFSET"}, + {0x20A, "GPUREG_ATTRIBBUFFER2_CONFIG1"}, + {0x20B, "GPUREG_ATTRIBBUFFER2_CONFIG2"}, + {0x20C, "GPUREG_ATTRIBBUFFER3_OFFSET"}, + {0x20D, "GPUREG_ATTRIBBUFFER3_CONFIG1"}, + {0x20E, "GPUREG_ATTRIBBUFFER3_CONFIG2"}, + {0x20F, "GPUREG_ATTRIBBUFFER4_OFFSET"}, + {0x210, "GPUREG_ATTRIBBUFFER4_CONFIG1"}, + {0x211, "GPUREG_ATTRIBBUFFER4_CONFIG2"}, + {0x212, "GPUREG_ATTRIBBUFFER5_OFFSET"}, + {0x213, "GPUREG_ATTRIBBUFFER5_CONFIG1"}, + {0x214, "GPUREG_ATTRIBBUFFER5_CONFIG2"}, + {0x215, "GPUREG_ATTRIBBUFFER6_OFFSET"}, + {0x216, "GPUREG_ATTRIBBUFFER6_CONFIG1"}, + {0x217, "GPUREG_ATTRIBBUFFER6_CONFIG2"}, + {0x218, "GPUREG_ATTRIBBUFFER7_OFFSET"}, + {0x219, "GPUREG_ATTRIBBUFFER7_CONFIG1"}, + {0x21A, "GPUREG_ATTRIBBUFFER7_CONFIG2"}, + {0x21B, "GPUREG_ATTRIBBUFFER8_OFFSET"}, + {0x21C, "GPUREG_ATTRIBBUFFER8_CONFIG1"}, + {0x21D, "GPUREG_ATTRIBBUFFER8_CONFIG2"}, + {0x21E, "GPUREG_ATTRIBBUFFER9_OFFSET"}, + {0x21F, "GPUREG_ATTRIBBUFFER9_CONFIG1"}, + {0x220, "GPUREG_ATTRIBBUFFER9_CONFIG2"}, + {0x221, "GPUREG_ATTRIBBUFFER10_OFFSET"}, + {0x222, "GPUREG_ATTRIBBUFFER10_CONFIG1"}, + {0x223, "GPUREG_ATTRIBBUFFER10_CONFIG2"}, + {0x224, "GPUREG_ATTRIBBUFFER11_OFFSET"}, + {0x225, "GPUREG_ATTRIBBUFFER11_CONFIG1"}, + {0x226, "GPUREG_ATTRIBBUFFER11_CONFIG2"}, + {0x227, "GPUREG_INDEXBUFFER_CONFIG"}, + {0x228, "GPUREG_NUMVERTICES"}, + {0x229, "GPUREG_GEOSTAGE_CONFIG"}, + {0x22A, "GPUREG_VERTEX_OFFSET"}, + + {0x22D, "GPUREG_POST_VERTEX_CACHE_NUM"}, + {0x22E, "GPUREG_DRAWARRAYS"}, + {0x22F, "GPUREG_DRAWELEMENTS"}, + + {0x231, "GPUREG_VTX_FUNC"}, + {0x232, "GPUREG_FIXEDATTRIB_INDEX"}, + {0x233, "GPUREG_FIXEDATTRIB_DATA0"}, + {0x234, "GPUREG_FIXEDATTRIB_DATA1"}, + {0x235, "GPUREG_FIXEDATTRIB_DATA2"}, + + {0x238, "GPUREG_CMDBUF_SIZE0"}, + {0x239, "GPUREG_CMDBUF_SIZE1"}, + {0x23A, "GPUREG_CMDBUF_ADDR0"}, + {0x23B, "GPUREG_CMDBUF_ADDR1"}, + {0x23C, "GPUREG_CMDBUF_JUMP0"}, + {0x23D, "GPUREG_CMDBUF_JUMP1"}, + + {0x242, "GPUREG_VSH_NUM_ATTR"}, + + {0x244, "GPUREG_VSH_COM_MODE"}, + {0x245, "GPUREG_START_DRAW_FUNC0"}, + + {0x24A, "GPUREG_VSH_OUTMAP_TOTAL1"}, + + {0x251, "GPUREG_VSH_OUTMAP_TOTAL2"}, + {0x252, "GPUREG_GSH_MISC0"}, + {0x253, "GPUREG_GEOSTAGE_CONFIG2"}, + {0x254, "GPUREG_GSH_MISC1"}, + + {0x25E, "GPUREG_PRIMITIVE_CONFIG"}, + {0x25F, "GPUREG_RESTART_PRIMITIVE"}, + + {0x280, "GPUREG_GSH_BOOLUNIFORM"}, + {0x281, "GPUREG_GSH_INTUNIFORM_I0"}, + {0x282, "GPUREG_GSH_INTUNIFORM_I1"}, + {0x283, "GPUREG_GSH_INTUNIFORM_I2"}, + {0x284, "GPUREG_GSH_INTUNIFORM_I3"}, + + {0x289, "GPUREG_GSH_INPUTBUFFER_CONFIG"}, + {0x28A, "GPUREG_GSH_ENTRYPOINT"}, + {0x28B, "GPUREG_GSH_ATTRIBUTES_PERMUTATION_LOW"}, + {0x28C, "GPUREG_GSH_ATTRIBUTES_PERMUTATION_HIGH"}, + {0x28D, "GPUREG_GSH_OUTMAP_MASK"}, + + {0x28F, "GPUREG_GSH_CODETRANSFER_END"}, + {0x290, "GPUREG_GSH_FLOATUNIFORM_INDEX"}, + {0x291, "GPUREG_GSH_FLOATUNIFORM_DATA0"}, + {0x292, "GPUREG_GSH_FLOATUNIFORM_DATA1"}, + {0x293, "GPUREG_GSH_FLOATUNIFORM_DATA2"}, + {0x294, "GPUREG_GSH_FLOATUNIFORM_DATA3"}, + {0x295, "GPUREG_GSH_FLOATUNIFORM_DATA4"}, + {0x296, "GPUREG_GSH_FLOATUNIFORM_DATA5"}, + {0x297, "GPUREG_GSH_FLOATUNIFORM_DATA6"}, + {0x298, "GPUREG_GSH_FLOATUNIFORM_DATA7"}, + + {0x29B, "GPUREG_GSH_CODETRANSFER_INDEX"}, + {0x29C, "GPUREG_GSH_CODETRANSFER_DATA0"}, + {0x29D, "GPUREG_GSH_CODETRANSFER_DATA1"}, + {0x29E, "GPUREG_GSH_CODETRANSFER_DATA2"}, + {0x29F, "GPUREG_GSH_CODETRANSFER_DATA3"}, + {0x2A0, "GPUREG_GSH_CODETRANSFER_DATA4"}, + {0x2A1, "GPUREG_GSH_CODETRANSFER_DATA5"}, + {0x2A2, "GPUREG_GSH_CODETRANSFER_DATA6"}, + {0x2A3, "GPUREG_GSH_CODETRANSFER_DATA7"}, + + {0x2A5, "GPUREG_GSH_OPDESCS_INDEX"}, + {0x2A6, "GPUREG_GSH_OPDESCS_DATA0"}, + {0x2A7, "GPUREG_GSH_OPDESCS_DATA1"}, + {0x2A8, "GPUREG_GSH_OPDESCS_DATA2"}, + {0x2A9, "GPUREG_GSH_OPDESCS_DATA3"}, + {0x2AA, "GPUREG_GSH_OPDESCS_DATA4"}, + {0x2AB, "GPUREG_GSH_OPDESCS_DATA5"}, + {0x2AC, "GPUREG_GSH_OPDESCS_DATA6"}, + {0x2AD, "GPUREG_GSH_OPDESCS_DATA7"}, + + {0x2B0, "GPUREG_VSH_BOOLUNIFORM"}, + {0x2B1, "GPUREG_VSH_INTUNIFORM_I0"}, + {0x2B2, "GPUREG_VSH_INTUNIFORM_I1"}, + {0x2B3, "GPUREG_VSH_INTUNIFORM_I2"}, + {0x2B4, "GPUREG_VSH_INTUNIFORM_I3"}, + + {0x2B9, "GPUREG_VSH_INPUTBUFFER_CONFIG"}, + {0x2BA, "GPUREG_VSH_ENTRYPOINT"}, + {0x2BB, "GPUREG_VSH_ATTRIBUTES_PERMUTATION_LOW"}, + {0x2BC, "GPUREG_VSH_ATTRIBUTES_PERMUTATION_HIGH"}, + {0x2BD, "GPUREG_VSH_OUTMAP_MASK"}, + + {0x2BF, "GPUREG_VSH_CODETRANSFER_END"}, + {0x2C0, "GPUREG_VSH_FLOATUNIFORM_INDEX"}, + {0x2C1, "GPUREG_VSH_FLOATUNIFORM_DATA0"}, + {0x2C2, "GPUREG_VSH_FLOATUNIFORM_DATA1"}, + {0x2C3, "GPUREG_VSH_FLOATUNIFORM_DATA2"}, + {0x2C4, "GPUREG_VSH_FLOATUNIFORM_DATA3"}, + {0x2C5, "GPUREG_VSH_FLOATUNIFORM_DATA4"}, + {0x2C6, "GPUREG_VSH_FLOATUNIFORM_DATA5"}, + {0x2C7, "GPUREG_VSH_FLOATUNIFORM_DATA6"}, + {0x2C8, "GPUREG_VSH_FLOATUNIFORM_DATA7"}, + + {0x2CB, "GPUREG_VSH_CODETRANSFER_INDEX"}, + {0x2CC, "GPUREG_VSH_CODETRANSFER_DATA0"}, + {0x2CD, "GPUREG_VSH_CODETRANSFER_DATA1"}, + {0x2CE, "GPUREG_VSH_CODETRANSFER_DATA2"}, + {0x2CF, "GPUREG_VSH_CODETRANSFER_DATA3"}, + {0x2D0, "GPUREG_VSH_CODETRANSFER_DATA4"}, + {0x2D1, "GPUREG_VSH_CODETRANSFER_DATA5"}, + {0x2D2, "GPUREG_VSH_CODETRANSFER_DATA6"}, + {0x2D3, "GPUREG_VSH_CODETRANSFER_DATA7"}, + + {0x2D5, "GPUREG_VSH_OPDESCS_INDEX"}, + {0x2D6, "GPUREG_VSH_OPDESCS_DATA0"}, + {0x2D7, "GPUREG_VSH_OPDESCS_DATA1"}, + {0x2D8, "GPUREG_VSH_OPDESCS_DATA2"}, + {0x2D9, "GPUREG_VSH_OPDESCS_DATA3"}, + {0x2DA, "GPUREG_VSH_OPDESCS_DATA4"}, + {0x2DB, "GPUREG_VSH_OPDESCS_DATA5"}, + {0x2DC, "GPUREG_VSH_OPDESCS_DATA6"}, + {0x2DD, "GPUREG_VSH_OPDESCS_DATA7"}, }; std::string Regs::GetCommandName(int index) { @@ -516,5 +515,4 @@ void State::Reset() { Zero(immediate); primitive_assembler.Reconfigure(Regs::TriangleTopology::List); } - } diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 7099c31a0..b2db609ec 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -16,15 +16,16 @@ #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" -#include "common/vector_math.h" #include "common/logging/log.h" +#include "common/vector_math.h" namespace Pica { // Returns index corresponding to the Regs member labeled by field_name // TODO: Due to Visual studio bug 209229, offsetof does not return constant expressions // when used with array elements (e.g. PICA_REG_INDEX(vs_uniform_setup.set_value[1])). -// For details cf. https://connect.microsoft.com/VisualStudio/feedback/details/209229/offsetof-does-not-produce-a-constant-expression-for-array-members +// For details cf. +// https://connect.microsoft.com/VisualStudio/feedback/details/209229/offsetof-does-not-produce-a-constant-expression-for-array-members // Hopefully, this will be fixed sometime in the future. // For lack of better alternatives, we currently hardcode the offsets when constant // expressions are needed via PICA_REG_INDEX_WORKAROUND (on sane compilers, static_asserts @@ -37,8 +38,9 @@ namespace Pica { // really is this annoying. This macro just forwards its first argument to PICA_REG_INDEX // and then performs a (no-op) cast to size_t iff the second argument matches the expected // field offset. Otherwise, the compiler will fail to compile this code. -#define PICA_REG_INDEX_WORKAROUND(field_name, backup_workaround_index) \ - ((typename std::enable_if<backup_workaround_index == PICA_REG_INDEX(field_name), size_t>::type)PICA_REG_INDEX(field_name)) +#define PICA_REG_INDEX_WORKAROUND(field_name, backup_workaround_index) \ + ((typename std::enable_if<backup_workaround_index == PICA_REG_INDEX(field_name), \ + size_t>::type)PICA_REG_INDEX(field_name)) #endif // _MSC_VER struct Regs { @@ -51,8 +53,8 @@ struct Regs { enum class CullMode : u32 { // Select which polygons are considered to be "frontfacing". - KeepAll = 0, - KeepClockWise = 1, + KeepAll = 0, + KeepClockWise = 1, KeepCounterClockWise = 2, // TODO: What does the third value imply? }; @@ -69,48 +71,47 @@ struct Regs { INSERT_PADDING_WORDS(0x9); - BitField<0, 24, u32> viewport_depth_range; // float24 + BitField<0, 24, u32> viewport_depth_range; // float24 BitField<0, 24, u32> viewport_depth_near_plane; // float24 BitField<0, 3, u32> vs_output_total; union VSOutputAttributes { // Maps components of output vertex attributes to semantics - enum Semantic : u32 - { - POSITION_X = 0, - POSITION_Y = 1, - POSITION_Z = 2, - POSITION_W = 3, - - QUATERNION_X = 4, - QUATERNION_Y = 5, - QUATERNION_Z = 6, - QUATERNION_W = 7, - - COLOR_R = 8, - COLOR_G = 9, - COLOR_B = 10, - COLOR_A = 11, - - TEXCOORD0_U = 12, - TEXCOORD0_V = 13, - TEXCOORD1_U = 14, - TEXCOORD1_V = 15, + enum Semantic : u32 { + POSITION_X = 0, + POSITION_Y = 1, + POSITION_Z = 2, + POSITION_W = 3, + + QUATERNION_X = 4, + QUATERNION_Y = 5, + QUATERNION_Z = 6, + QUATERNION_W = 7, + + COLOR_R = 8, + COLOR_G = 9, + COLOR_B = 10, + COLOR_A = 11, + + TEXCOORD0_U = 12, + TEXCOORD0_V = 13, + TEXCOORD1_U = 14, + TEXCOORD1_V = 15, // TODO: Not verified - VIEW_X = 18, - VIEW_Y = 19, - VIEW_Z = 20, + VIEW_X = 18, + VIEW_Y = 19, + VIEW_Z = 20, - TEXCOORD2_U = 22, - TEXCOORD2_V = 23, + TEXCOORD2_U = 22, + TEXCOORD2_V = 23, - INVALID = 31, + INVALID = 31, }; - BitField< 0, 5, Semantic> map_x; - BitField< 8, 5, Semantic> map_y; + BitField<0, 5, Semantic> map_x; + BitField<8, 5, Semantic> map_y; BitField<16, 5, Semantic> map_z; BitField<24, 5, Semantic> map_w; } vs_output_attributes[7]; @@ -128,77 +129,78 @@ struct Regs { BitField<0, 2, ScissorMode> mode; union { - BitField< 0, 16, u32> x1; + BitField<0, 16, u32> x1; BitField<16, 16, u32> y1; }; union { - BitField< 0, 16, u32> x2; + BitField<0, 16, u32> x2; BitField<16, 16, u32> y2; }; } scissor_test; union { - BitField< 0, 10, s32> x; + BitField<0, 10, s32> x; BitField<16, 10, s32> y; } viewport_corner; INSERT_PADDING_WORDS(0x1); - //TODO: early depth + // TODO: early depth INSERT_PADDING_WORDS(0x1); INSERT_PADDING_WORDS(0x2); enum DepthBuffering : u32 { - WBuffering = 0, - ZBuffering = 1, + WBuffering = 0, + ZBuffering = 1, }; - BitField< 0, 1, DepthBuffering> depthmap_enable; + BitField<0, 1, DepthBuffering> depthmap_enable; INSERT_PADDING_WORDS(0x12); struct TextureConfig { enum TextureType : u32 { - Texture2D = 0, - TextureCube = 1, - Shadow2D = 2, + Texture2D = 0, + TextureCube = 1, + Shadow2D = 2, Projection2D = 3, - ShadowCube = 4, - Disabled = 5, + ShadowCube = 4, + Disabled = 5, }; enum WrapMode : u32 { - ClampToEdge = 0, - ClampToBorder = 1, - Repeat = 2, + ClampToEdge = 0, + ClampToBorder = 1, + Repeat = 2, MirroredRepeat = 3, }; enum TextureFilter : u32 { Nearest = 0, - Linear = 1 + Linear = 1, }; union { u32 raw; - BitField< 0, 8, u32> r; - BitField< 8, 8, u32> g; + BitField<0, 8, u32> r; + BitField<8, 8, u32> g; BitField<16, 8, u32> b; BitField<24, 8, u32> a; } border_color; union { - BitField< 0, 16, u32> height; + BitField<0, 16, u32> height; BitField<16, 16, u32> width; }; union { - BitField< 1, 1, TextureFilter> mag_filter; - BitField< 2, 1, TextureFilter> min_filter; - BitField< 8, 2, WrapMode> wrap_t; + BitField<1, 1, TextureFilter> mag_filter; + BitField<2, 1, TextureFilter> min_filter; + BitField<8, 2, WrapMode> wrap_t; BitField<12, 2, WrapMode> wrap_s; - BitField<28, 2, TextureType> type; ///< @note Only valid for texture 0 according to 3DBrew. + BitField<28, 2, TextureType> + type; ///< @note Only valid for texture 0 according to 3DBrew. }; INSERT_PADDING_WORDS(0x1); @@ -216,39 +218,39 @@ struct Regs { }; enum class TextureFormat : u32 { - RGBA8 = 0, - RGB8 = 1, - RGB5A1 = 2, - RGB565 = 3, - RGBA4 = 4, - IA8 = 5, - RG8 = 6, ///< @note Also called HILO8 in 3DBrew. - I8 = 7, - A8 = 8, - IA4 = 9, - I4 = 10, - A4 = 11, - ETC1 = 12, // compressed - ETC1A4 = 13, // compressed + RGBA8 = 0, + RGB8 = 1, + RGB5A1 = 2, + RGB565 = 3, + RGBA4 = 4, + IA8 = 5, + RG8 = 6, ///< @note Also called HILO8 in 3DBrew. + I8 = 7, + A8 = 8, + IA4 = 9, + I4 = 10, + A4 = 11, + ETC1 = 12, // compressed + ETC1A4 = 13, // compressed }; enum class LogicOp : u32 { - Clear = 0, - And = 1, - AndReverse = 2, - Copy = 3, - Set = 4, - CopyInverted = 5, - NoOp = 6, - Invert = 7, - Nand = 8, - Or = 9, - Nor = 10, - Xor = 11, - Equiv = 12, - AndInverted = 13, - OrReverse = 14, - OrInverted = 15, + Clear = 0, + And = 1, + AndReverse = 2, + Copy = 3, + Set = 4, + CopyInverted = 5, + NoOp = 6, + Invert = 7, + Nand = 8, + Or = 9, + Nor = 10, + Xor = 11, + Equiv = 12, + AndInverted = 13, + OrReverse = 14, + OrInverted = 15, }; static unsigned NibblesPerPixel(TextureFormat format) { @@ -273,15 +275,15 @@ struct Regs { case TextureFormat::I8: case TextureFormat::A8: case TextureFormat::IA4: - default: // placeholder for yet unknown formats + default: // placeholder for yet unknown formats return 2; } } union { - BitField< 0, 1, u32> texture0_enable; - BitField< 1, 1, u32> texture1_enable; - BitField< 2, 1, u32> texture2_enable; + BitField<0, 1, u32> texture0_enable; + BitField<1, 1, u32> texture1_enable; + BitField<2, 1, u32> texture2_enable; }; TextureConfig texture0; INSERT_PADDING_WORDS(0x8); @@ -302,63 +304,63 @@ struct Regs { }; const std::array<FullTextureConfig, 3> GetTextures() const { return {{ - { texture0_enable.ToBool(), texture0, texture0_format }, - { texture1_enable.ToBool(), texture1, texture1_format }, - { texture2_enable.ToBool(), texture2, texture2_format } - }}; + {texture0_enable.ToBool(), texture0, texture0_format}, + {texture1_enable.ToBool(), texture1, texture1_format}, + {texture2_enable.ToBool(), texture2, texture2_format}, + }}; } // 0xc0-0xff: Texture Combiner (akin to glTexEnv) struct TevStageConfig { enum class Source : u32 { - PrimaryColor = 0x0, - PrimaryFragmentColor = 0x1, + PrimaryColor = 0x0, + PrimaryFragmentColor = 0x1, SecondaryFragmentColor = 0x2, - Texture0 = 0x3, - Texture1 = 0x4, - Texture2 = 0x5, - Texture3 = 0x6, + Texture0 = 0x3, + Texture1 = 0x4, + Texture2 = 0x5, + Texture3 = 0x6, - PreviousBuffer = 0xd, - Constant = 0xe, - Previous = 0xf, + PreviousBuffer = 0xd, + Constant = 0xe, + Previous = 0xf, }; enum class ColorModifier : u32 { - SourceColor = 0x0, + SourceColor = 0x0, OneMinusSourceColor = 0x1, - SourceAlpha = 0x2, + SourceAlpha = 0x2, OneMinusSourceAlpha = 0x3, - SourceRed = 0x4, - OneMinusSourceRed = 0x5, + SourceRed = 0x4, + OneMinusSourceRed = 0x5, - SourceGreen = 0x8, + SourceGreen = 0x8, OneMinusSourceGreen = 0x9, - SourceBlue = 0xc, - OneMinusSourceBlue = 0xd, + SourceBlue = 0xc, + OneMinusSourceBlue = 0xd, }; enum class AlphaModifier : u32 { - SourceAlpha = 0x0, + SourceAlpha = 0x0, OneMinusSourceAlpha = 0x1, - SourceRed = 0x2, - OneMinusSourceRed = 0x3, - SourceGreen = 0x4, + SourceRed = 0x2, + OneMinusSourceRed = 0x3, + SourceGreen = 0x4, OneMinusSourceGreen = 0x5, - SourceBlue = 0x6, - OneMinusSourceBlue = 0x7, + SourceBlue = 0x6, + OneMinusSourceBlue = 0x7, }; enum class Operation : u32 { - Replace = 0, - Modulate = 1, - Add = 2, - AddSigned = 3, - Lerp = 4, - Subtract = 5, - Dot3_RGB = 6, + Replace = 0, + Modulate = 1, + Add = 2, + AddSigned = 3, + Lerp = 4, + Subtract = 5, + Dot3_RGB = 6, MultiplyThenAdd = 8, AddThenMultiply = 9, @@ -366,9 +368,9 @@ struct Regs { union { u32 sources_raw; - BitField< 0, 4, Source> color_source1; - BitField< 4, 4, Source> color_source2; - BitField< 8, 4, Source> color_source3; + BitField<0, 4, Source> color_source1; + BitField<4, 4, Source> color_source2; + BitField<8, 4, Source> color_source3; BitField<16, 4, Source> alpha_source1; BitField<20, 4, Source> alpha_source2; BitField<24, 4, Source> alpha_source3; @@ -376,9 +378,9 @@ struct Regs { union { u32 modifiers_raw; - BitField< 0, 4, ColorModifier> color_modifier1; - BitField< 4, 4, ColorModifier> color_modifier2; - BitField< 8, 4, ColorModifier> color_modifier3; + BitField<0, 4, ColorModifier> color_modifier1; + BitField<4, 4, ColorModifier> color_modifier2; + BitField<8, 4, ColorModifier> color_modifier3; BitField<12, 3, AlphaModifier> alpha_modifier1; BitField<16, 3, AlphaModifier> alpha_modifier2; BitField<20, 3, AlphaModifier> alpha_modifier3; @@ -386,21 +388,21 @@ struct Regs { union { u32 ops_raw; - BitField< 0, 4, Operation> color_op; + BitField<0, 4, Operation> color_op; BitField<16, 4, Operation> alpha_op; }; union { u32 const_color; - BitField< 0, 8, u32> const_r; - BitField< 8, 8, u32> const_g; + BitField<0, 8, u32> const_r; + BitField<8, 8, u32> const_g; BitField<16, 8, u32> const_b; BitField<24, 8, u32> const_a; }; union { u32 scales_raw; - BitField< 0, 2, u32> color_scale; + BitField<0, 2, u32> color_scale; BitField<16, 2, u32> alpha_scale; }; @@ -424,8 +426,8 @@ struct Regs { enum class FogMode : u32 { None = 0, - Fog = 5, - Gas = 7, + Fog = 5, + Gas = 7, }; union { @@ -435,7 +437,7 @@ struct Regs { union { // Tev stages 0-3 write their output to the combiner buffer if the corresponding bit in // these masks are set - BitField< 8, 4, u32> update_mask_rgb; + BitField<8, 4, u32> update_mask_rgb; BitField<12, 4, u32> update_mask_a; bool TevStageUpdatesCombinerBufferColor(unsigned stage_index) const { @@ -450,8 +452,8 @@ struct Regs { union { u32 raw; - BitField< 0, 8, u32> r; - BitField< 8, 8, u32> g; + BitField<0, 8, u32> r; + BitField<8, 8, u32> g; BitField<16, 8, u32> b; } fog_color; @@ -469,66 +471,64 @@ struct Regs { union { u32 raw; - BitField< 0, 8, u32> r; - BitField< 8, 8, u32> g; + BitField<0, 8, u32> r; + BitField<8, 8, u32> g; BitField<16, 8, u32> b; BitField<24, 8, u32> a; } tev_combiner_buffer_color; INSERT_PADDING_WORDS(0x2); - const std::array<Regs::TevStageConfig,6> GetTevStages() const { - return {{ tev_stage0, tev_stage1, - tev_stage2, tev_stage3, - tev_stage4, tev_stage5 }}; + const std::array<Regs::TevStageConfig, 6> GetTevStages() const { + return {{tev_stage0, tev_stage1, tev_stage2, tev_stage3, tev_stage4, tev_stage5}}; }; enum class BlendEquation : u32 { - Add = 0, - Subtract = 1, + Add = 0, + Subtract = 1, ReverseSubtract = 2, - Min = 3, - Max = 4, + Min = 3, + Max = 4, }; enum class BlendFactor : u32 { - Zero = 0, - One = 1, - SourceColor = 2, - OneMinusSourceColor = 3, - DestColor = 4, - OneMinusDestColor = 5, - SourceAlpha = 6, - OneMinusSourceAlpha = 7, - DestAlpha = 8, - OneMinusDestAlpha = 9, - ConstantColor = 10, - OneMinusConstantColor = 11, - ConstantAlpha = 12, - OneMinusConstantAlpha = 13, - SourceAlphaSaturate = 14, + Zero = 0, + One = 1, + SourceColor = 2, + OneMinusSourceColor = 3, + DestColor = 4, + OneMinusDestColor = 5, + SourceAlpha = 6, + OneMinusSourceAlpha = 7, + DestAlpha = 8, + OneMinusDestAlpha = 9, + ConstantColor = 10, + OneMinusConstantColor = 11, + ConstantAlpha = 12, + OneMinusConstantAlpha = 13, + SourceAlphaSaturate = 14, }; enum class CompareFunc : u32 { - Never = 0, - Always = 1, - Equal = 2, - NotEqual = 3, - LessThan = 4, - LessThanOrEqual = 5, - GreaterThan = 6, + Never = 0, + Always = 1, + Equal = 2, + NotEqual = 3, + LessThan = 4, + LessThanOrEqual = 5, + GreaterThan = 6, GreaterThanOrEqual = 7, }; enum class StencilAction : u32 { - Keep = 0, - Zero = 1, - Replace = 2, - Increment = 3, - Decrement = 4, - Invert = 5, - IncrementWrap = 6, - DecrementWrap = 7 + Keep = 0, + Zero = 1, + Replace = 2, + Increment = 3, + Decrement = 4, + Invert = 5, + IncrementWrap = 6, + DecrementWrap = 7, }; struct { @@ -538,8 +538,8 @@ struct Regs { }; union { - BitField< 0, 8, BlendEquation> blend_equation_rgb; - BitField< 8, 8, BlendEquation> blend_equation_a; + BitField<0, 8, BlendEquation> blend_equation_rgb; + BitField<8, 8, BlendEquation> blend_equation_a; BitField<16, 4, BlendFactor> factor_source_rgb; BitField<20, 4, BlendFactor> factor_dest_rgb; @@ -554,16 +554,16 @@ struct Regs { union { u32 raw; - BitField< 0, 8, u32> r; - BitField< 8, 8, u32> g; + BitField<0, 8, u32> r; + BitField<8, 8, u32> g; BitField<16, 8, u32> b; BitField<24, 8, u32> a; } blend_const; union { - BitField< 0, 1, u32> enable; - BitField< 4, 3, CompareFunc> func; - BitField< 8, 8, u32> ref; + BitField<0, 1, u32> enable; + BitField<4, 3, CompareFunc> func; + BitField<8, 8, u32> ref; } alpha_test; struct { @@ -572,13 +572,13 @@ struct Regs { u32 raw_func; // If true, enable stencil testing - BitField< 0, 1, u32> enable; + BitField<0, 1, u32> enable; // Comparison operation for stencil testing - BitField< 4, 3, CompareFunc> func; + BitField<4, 3, CompareFunc> func; // Mask used to control writing to the stencil buffer - BitField< 8, 8, u32> write_mask; + BitField<8, 8, u32> write_mask; // Value to compare against for stencil testing BitField<16, 8, u32> reference_value; @@ -592,21 +592,21 @@ struct Regs { u32 raw_op; // Action to perform when the stencil test fails - BitField< 0, 3, StencilAction> action_stencil_fail; + BitField<0, 3, StencilAction> action_stencil_fail; // Action to perform when stencil testing passed but depth testing fails - BitField< 4, 3, StencilAction> action_depth_fail; + BitField<4, 3, StencilAction> action_depth_fail; // Action to perform when both stencil and depth testing pass - BitField< 8, 3, StencilAction> action_depth_pass; + BitField<8, 3, StencilAction> action_depth_pass; }; } stencil_test; union { - BitField< 0, 1, u32> depth_test_enable; - BitField< 4, 3, CompareFunc> depth_test_func; - BitField< 8, 1, u32> red_enable; - BitField< 9, 1, u32> green_enable; + BitField<0, 1, u32> depth_test_enable; + BitField<4, 3, CompareFunc> depth_test_func; + BitField<8, 1, u32> red_enable; + BitField<9, 1, u32> green_enable; BitField<10, 1, u32> blue_enable; BitField<11, 1, u32> alpha_enable; BitField<12, 1, u32> depth_write_enable; @@ -617,16 +617,16 @@ struct Regs { // Components are laid out in reverse byte order, most significant bits first. enum class ColorFormat : u32 { - RGBA8 = 0, - RGB8 = 1, + RGBA8 = 0, + RGB8 = 1, RGB5A1 = 2, RGB565 = 3, - RGBA4 = 4, + RGBA4 = 4, }; enum class DepthFormat : u32 { - D16 = 0, - D24 = 2, + D16 = 0, + D24 = 2, D24S8 = 3, }; @@ -673,7 +673,7 @@ struct Regs { // while the height is stored as the actual height minus one. // Hence, don't access these fields directly but use the accessors // GetWidth() and GetHeight() instead. - BitField< 0, 11, u32> width; + BitField<0, 11, u32> width; BitField<12, 10, u32> height; }; @@ -759,10 +759,12 @@ struct Regs { /// Selects which lighting components are affected by fresnel enum class LightingFresnelSelector { - None = 0, ///< Fresnel is disabled - PrimaryAlpha = 1, ///< Primary (diffuse) lighting alpha is affected by fresnel - SecondaryAlpha = 2, ///< Secondary (specular) lighting alpha is affected by fresnel - Both = PrimaryAlpha | SecondaryAlpha, ///< Both primary and secondary lighting alphas are affected by fresnel + None = 0, ///< Fresnel is disabled + PrimaryAlpha = 1, ///< Primary (diffuse) lighting alpha is affected by fresnel + SecondaryAlpha = 2, ///< Secondary (specular) lighting alpha is affected by fresnel + Both = + PrimaryAlpha | + SecondaryAlpha, ///< Both primary and secondary lighting alphas are affected by fresnel }; /// Factor used to scale the output of a lighting LUT @@ -789,57 +791,63 @@ struct Regs { }; union LightColor { - BitField< 0, 10, u32> b; + BitField<0, 10, u32> b; BitField<10, 10, u32> g; BitField<20, 10, u32> r; Math::Vec3f ToVec3f() const { - // These fields are 10 bits wide, however 255 corresponds to 1.0f for each color component + // These fields are 10 bits wide, however 255 corresponds to 1.0f for each color + // component return Math::MakeVec((f32)r / 255.f, (f32)g / 255.f, (f32)b / 255.f); } }; - /// Returns true if the specified lighting sampler is supported by the current Pica lighting configuration + /// Returns true if the specified lighting sampler is supported by the current Pica lighting + /// configuration static bool IsLightingSamplerSupported(LightingConfig config, LightingSampler sampler) { switch (sampler) { case LightingSampler::Distribution0: return (config != LightingConfig::Config1); case LightingSampler::Distribution1: - return (config != LightingConfig::Config0) && (config != LightingConfig::Config1) && (config != LightingConfig::Config5); + return (config != LightingConfig::Config0) && (config != LightingConfig::Config1) && + (config != LightingConfig::Config5); case LightingSampler::Fresnel: - return (config != LightingConfig::Config0) && (config != LightingConfig::Config2) && (config != LightingConfig::Config4); + return (config != LightingConfig::Config0) && (config != LightingConfig::Config2) && + (config != LightingConfig::Config4); case LightingSampler::ReflectRed: return (config != LightingConfig::Config3); case LightingSampler::ReflectGreen: case LightingSampler::ReflectBlue: - return (config == LightingConfig::Config4) || (config == LightingConfig::Config5) || (config == LightingConfig::Config7); + return (config == LightingConfig::Config4) || (config == LightingConfig::Config5) || + (config == LightingConfig::Config7); default: UNREACHABLE_MSG("Regs::IsLightingSamplerSupported: Reached " "unreachable section, sampler should be one " "of Distribution0, Distribution1, Fresnel, " "ReflectRed, ReflectGreen or ReflectBlue, instead " - "got %i", static_cast<int>(config)); + "got %i", + static_cast<int>(config)); } } struct { struct LightSrc { - LightColor specular_0; // material.specular_0 * light.specular_0 - LightColor specular_1; // material.specular_1 * light.specular_1 - LightColor diffuse; // material.diffuse * light.diffuse - LightColor ambient; // material.ambient * light.ambient + LightColor specular_0; // material.specular_0 * light.specular_0 + LightColor specular_1; // material.specular_1 * light.specular_1 + LightColor diffuse; // material.diffuse * light.diffuse + LightColor ambient; // material.ambient * light.ambient // Encoded as 16-bit floating point union { - BitField< 0, 16, u32> x; + BitField<0, 16, u32> x; BitField<16, 16, u32> y; }; union { - BitField< 0, 16, u32> z; + BitField<0, 16, u32> z; }; INSERT_PADDING_WORDS(0x3); @@ -854,7 +862,8 @@ struct Regs { INSERT_PADDING_WORDS(0x4); }; - static_assert(sizeof(LightSrc) == 0x10 * sizeof(u32), "LightSrc structure must be 0x10 words"); + static_assert(sizeof(LightSrc) == 0x10 * sizeof(u32), + "LightSrc structure must be 0x10 words"); LightSrc light[8]; LightColor global_ambient; // Emission + (material.ambient * lighting.ambient) @@ -862,8 +871,8 @@ struct Regs { BitField<0, 3, u32> num_lights; // Number of enabled lights - 1 union { - BitField< 2, 2, LightingFresnelSelector> fresnel_selector; - BitField< 4, 4, LightingConfig> config; + BitField<2, 2, LightingFresnelSelector> fresnel_selector; + BitField<4, 4, LightingConfig> config; BitField<22, 2, u32> bump_selector; // 0: Texture 0, 1: Texture 1, 2: Texture 2 BitField<27, 1, u32> clamp_highlights; BitField<28, 2, LightingBumpMode> bump_mode; @@ -892,16 +901,17 @@ struct Regs { } config1; bool IsDistAttenDisabled(unsigned index) const { - const unsigned disable[] = { config1.disable_dist_atten_light_0, config1.disable_dist_atten_light_1, - config1.disable_dist_atten_light_2, config1.disable_dist_atten_light_3, - config1.disable_dist_atten_light_4, config1.disable_dist_atten_light_5, - config1.disable_dist_atten_light_6, config1.disable_dist_atten_light_7 }; + const unsigned disable[] = { + config1.disable_dist_atten_light_0, config1.disable_dist_atten_light_1, + config1.disable_dist_atten_light_2, config1.disable_dist_atten_light_3, + config1.disable_dist_atten_light_4, config1.disable_dist_atten_light_5, + config1.disable_dist_atten_light_6, config1.disable_dist_atten_light_7}; return disable[index] != 0; } union { - BitField<0, 8, u32> index; ///< Index at which to set data in the LUT - BitField<8, 5, u32> type; ///< Type of LUT for which to set data + BitField<0, 8, u32> index; ///< Index at which to set data in the LUT + BitField<8, 5, u32> type; ///< Type of LUT for which to set data } lut_config; BitField<0, 1, u32> disable; @@ -917,9 +927,9 @@ struct Regs { // abs mode is disabled, LUT indexes are in the range of (-1.0, 1.0). Otherwise, they are in // the range of (0.0, 1.0). union { - BitField< 1, 1, u32> disable_d0; - BitField< 5, 1, u32> disable_d1; - BitField< 9, 1, u32> disable_sp; + BitField<1, 1, u32> disable_d0; + BitField<5, 1, u32> disable_d1; + BitField<9, 1, u32> disable_sp; BitField<13, 1, u32> disable_fr; BitField<17, 1, u32> disable_rb; BitField<21, 1, u32> disable_rg; @@ -927,9 +937,9 @@ struct Regs { } abs_lut_input; union { - BitField< 0, 3, LightingLutInput> d0; - BitField< 4, 3, LightingLutInput> d1; - BitField< 8, 3, LightingLutInput> sp; + BitField<0, 3, LightingLutInput> d0; + BitField<4, 3, LightingLutInput> d1; + BitField<8, 3, LightingLutInput> sp; BitField<12, 3, LightingLutInput> fr; BitField<16, 3, LightingLutInput> rb; BitField<20, 3, LightingLutInput> rg; @@ -937,9 +947,9 @@ struct Regs { } lut_input; union { - BitField< 0, 3, LightingScale> d0; - BitField< 4, 3, LightingScale> d1; - BitField< 8, 3, LightingScale> sp; + BitField<0, 3, LightingScale> d0; + BitField<4, 3, LightingScale> d1; + BitField<8, 3, LightingScale> sp; BitField<12, 3, LightingScale> fr; BitField<16, 3, LightingScale> rb; BitField<20, 3, LightingScale> rg; @@ -972,9 +982,9 @@ struct Regs { // above), the first N slots below will be set to integers within the range of 0-7, // corresponding to the actual light that is enabled for each slot. - BitField< 0, 3, u32> slot_0; - BitField< 4, 3, u32> slot_1; - BitField< 8, 3, u32> slot_2; + BitField<0, 3, u32> slot_0; + BitField<4, 3, u32> slot_1; + BitField<8, 3, u32> slot_2; BitField<12, 3, u32> slot_3; BitField<16, 3, u32> slot_4; BitField<20, 3, u32> slot_5; @@ -982,7 +992,8 @@ struct Regs { BitField<28, 3, u32> slot_7; unsigned GetNum(unsigned index) const { - const unsigned enable_slots[] = { slot_0, slot_1, slot_2, slot_3, slot_4, slot_5, slot_6, slot_7 }; + const unsigned enable_slots[] = {slot_0, slot_1, slot_2, slot_3, + slot_4, slot_5, slot_6, slot_7}; return enable_slots[index]; } } light_enable; @@ -1006,58 +1017,54 @@ struct Regs { // Descriptor for internal vertex attributes union { - BitField< 0, 2, VertexAttributeFormat> format0; // size of one element - BitField< 2, 2, u64> size0; // number of elements minus 1 - BitField< 4, 2, VertexAttributeFormat> format1; - BitField< 6, 2, u64> size1; - BitField< 8, 2, VertexAttributeFormat> format2; - BitField<10, 2, u64> size2; - BitField<12, 2, VertexAttributeFormat> format3; - BitField<14, 2, u64> size3; - BitField<16, 2, VertexAttributeFormat> format4; - BitField<18, 2, u64> size4; - BitField<20, 2, VertexAttributeFormat> format5; - BitField<22, 2, u64> size5; - BitField<24, 2, VertexAttributeFormat> format6; - BitField<26, 2, u64> size6; - BitField<28, 2, VertexAttributeFormat> format7; - BitField<30, 2, u64> size7; - BitField<32, 2, VertexAttributeFormat> format8; - BitField<34, 2, u64> size8; - BitField<36, 2, VertexAttributeFormat> format9; - BitField<38, 2, u64> size9; - BitField<40, 2, VertexAttributeFormat> format10; - BitField<42, 2, u64> size10; - BitField<44, 2, VertexAttributeFormat> format11; - BitField<46, 2, u64> size11; + BitField<0, 2, VertexAttributeFormat> format0; // size of one element + BitField<2, 2, u64> size0; // number of elements minus 1 + BitField<4, 2, VertexAttributeFormat> format1; + BitField<6, 2, u64> size1; + BitField<8, 2, VertexAttributeFormat> format2; + BitField<10, 2, u64> size2; + BitField<12, 2, VertexAttributeFormat> format3; + BitField<14, 2, u64> size3; + BitField<16, 2, VertexAttributeFormat> format4; + BitField<18, 2, u64> size4; + BitField<20, 2, VertexAttributeFormat> format5; + BitField<22, 2, u64> size5; + BitField<24, 2, VertexAttributeFormat> format6; + BitField<26, 2, u64> size6; + BitField<28, 2, VertexAttributeFormat> format7; + BitField<30, 2, u64> size7; + BitField<32, 2, VertexAttributeFormat> format8; + BitField<34, 2, u64> size8; + BitField<36, 2, VertexAttributeFormat> format9; + BitField<38, 2, u64> size9; + BitField<40, 2, VertexAttributeFormat> format10; + BitField<42, 2, u64> size10; + BitField<44, 2, VertexAttributeFormat> format11; + BitField<46, 2, u64> size11; BitField<48, 12, u64> attribute_mask; // number of total attributes minus 1 - BitField<60, 4, u64> num_extra_attributes; + BitField<60, 4, u64> num_extra_attributes; }; inline VertexAttributeFormat GetFormat(int n) const { - VertexAttributeFormat formats[] = { - format0, format1, format2, format3, - format4, format5, format6, format7, - format8, format9, format10, format11 - }; + VertexAttributeFormat formats[] = {format0, format1, format2, format3, + format4, format5, format6, format7, + format8, format9, format10, format11}; return formats[n]; } inline int GetNumElements(int n) const { - u64 sizes[] = { - size0, size1, size2, size3, - size4, size5, size6, size7, - size8, size9, size10, size11 - }; - return (int)sizes[n]+1; + u64 sizes[] = {size0, size1, size2, size3, size4, size5, + size6, size7, size8, size9, size10, size11}; + return (int)sizes[n] + 1; } inline int GetElementSizeInBytes(int n) const { - return (GetFormat(n) == VertexAttributeFormat::FLOAT) ? 4 : - (GetFormat(n) == VertexAttributeFormat::SHORT) ? 2 : 1; + return (GetFormat(n) == VertexAttributeFormat::FLOAT) + ? 4 + : (GetFormat(n) == VertexAttributeFormat::SHORT) ? 2 : 1; } inline int GetStride(int n) const { @@ -1069,7 +1076,7 @@ struct Regs { } inline int GetNumTotalAttributes() const { - return (int)num_extra_attributes+1; + return (int)num_extra_attributes + 1; } // Attribute loaders map the source vertex data to input attributes @@ -1079,9 +1086,9 @@ struct Regs { u32 data_offset; union { - BitField< 0, 4, u64> comp0; - BitField< 4, 4, u64> comp1; - BitField< 8, 4, u64> comp2; + BitField<0, 4, u64> comp0; + BitField<4, 4, u64> comp1; + BitField<8, 4, u64> comp2; BitField<12, 4, u64> comp3; BitField<16, 4, u64> comp4; BitField<20, 4, u64> comp5; @@ -1099,11 +1106,8 @@ struct Regs { }; inline int GetComponent(int n) const { - u64 components[] = { - comp0, comp1, comp2, comp3, - comp4, comp5, comp6, comp7, - comp8, comp9, comp10, comp11 - }; + u64 components[] = {comp0, comp1, comp2, comp3, comp4, comp5, + comp6, comp7, comp8, comp9, comp10, comp11}; return (int)components[n]; } } attribute_loaders[12]; @@ -1157,8 +1161,8 @@ struct Regs { // kicked off. // 2) Games can configure these registers to provide a command list subroutine mechanism. - BitField< 0, 20, u32> size[2]; ///< Size (in bytes / 8) of each channel's command buffer - BitField< 0, 28, u32> addr[2]; ///< Physical address / 8 of each channel's command buffer + BitField<0, 20, u32> size[2]; ///< Size (in bytes / 8) of each channel's command buffer + BitField<0, 28, u32> addr[2]; ///< Physical address / 8 of each channel's command buffer u32 trigger[2]; ///< Triggers execution of the channel's command buffer when written to unsigned GetSize(unsigned index) const { @@ -1176,7 +1180,7 @@ struct Regs { enum class GPUMode : u32 { Drawing = 0, - Configuring = 1 + Configuring = 1, }; GPUMode gpu_mode; @@ -1184,9 +1188,9 @@ struct Regs { INSERT_PADDING_WORDS(0x18); enum class TriangleTopology : u32 { - List = 0, - Strip = 1, - Fan = 2, + List = 0, + Strip = 1, + Fan = 2, Shader = 3, // Programmable setup unit implemented in a geometry shader }; @@ -1200,8 +1204,8 @@ struct Regs { BitField<0, 16, u32> bool_uniforms; union { - BitField< 0, 8, u32> x; - BitField< 8, 8, u32> y; + BitField<0, 8, u32> x; + BitField<8, 8, u32> y; BitField<16, 8, u32> z; BitField<24, 8, u32> w; } int_uniforms[4]; @@ -1217,9 +1221,9 @@ struct Regs { BitField<0, 16, u32> main_offset; union { - BitField< 0, 4, u64> attribute0_register; - BitField< 4, 4, u64> attribute1_register; - BitField< 8, 4, u64> attribute2_register; + BitField<0, 4, u64> attribute0_register; + BitField<4, 4, u64> attribute1_register; + BitField<8, 4, u64> attribute2_register; BitField<12, 4, u64> attribute3_register; BitField<16, 4, u64> attribute4_register; BitField<20, 4, u64> attribute5_register; @@ -1236,10 +1240,12 @@ struct Regs { int GetRegisterForAttribute(int attribute_index) const { u64 fields[] = { - attribute0_register, attribute1_register, attribute2_register, attribute3_register, - attribute4_register, attribute5_register, attribute6_register, attribute7_register, - attribute8_register, attribute9_register, attribute10_register, attribute11_register, - attribute12_register, attribute13_register, attribute14_register, attribute15_register, + attribute0_register, attribute1_register, attribute2_register, + attribute3_register, attribute4_register, attribute5_register, + attribute6_register, attribute7_register, attribute8_register, + attribute9_register, attribute10_register, attribute11_register, + attribute12_register, attribute13_register, attribute14_register, + attribute15_register, }; return (int)fields[attribute_index]; } @@ -1251,10 +1257,9 @@ struct Regs { INSERT_PADDING_WORDS(0x2); struct { - enum Format : u32 - { + enum Format : u32 { FLOAT24 = 0, - FLOAT32 = 1 + FLOAT32 = 1, }; bool IsFloat32() const { @@ -1263,7 +1268,8 @@ struct Regs { union { // Index of the next uniform to write to - // TODO: ctrulib uses 8 bits for this, however that seems to yield lots of invalid indices + // TODO: ctrulib uses 8 bits for this, however that seems to yield lots of invalid + // indices // TODO: Maybe the uppermost index is for the geometry shader? Investigate! BitField<0, 7, u32> index; @@ -1315,12 +1321,12 @@ struct Regs { return sizeof(Regs) / sizeof(u32); } - const u32& operator [] (int index) const { + const u32& operator[](int index) const { const u32* content = reinterpret_cast<const u32*>(this); return content[index]; } - u32& operator [] (int index) { + u32& operator[](int index) { u32* content = reinterpret_cast<u32*>(this); return content[index]; } @@ -1339,7 +1345,9 @@ private: // is technically allowed since C++11. This macro should be enabled once MSVC adds // support for that. #ifndef _MSC_VER -#define ASSERT_REG_POSITION(field_name, position) static_assert(offsetof(Regs, field_name) == position * 4, "Field "#field_name" has invalid position") +#define ASSERT_REG_POSITION(field_name, position) \ + static_assert(offsetof(Regs, field_name) == position * 4, \ + "Field " #field_name " has invalid position") ASSERT_REG_POSITION(trigger_irq, 0x10); ASSERT_REG_POSITION(cull_mode, 0x40); @@ -1392,11 +1400,15 @@ ASSERT_REG_POSITION(vs, 0x2b0); #undef ASSERT_REG_POSITION #endif // !defined(_MSC_VER) -static_assert(sizeof(Regs::ShaderConfig) == 0x30 * sizeof(u32), "ShaderConfig structure has incorrect size"); +static_assert(sizeof(Regs::ShaderConfig) == 0x30 * sizeof(u32), + "ShaderConfig structure has incorrect size"); -// The total number of registers is chosen arbitrarily, but let's make sure it's not some odd value anyway. -static_assert(sizeof(Regs) <= 0x300 * sizeof(u32), "Register set structure larger than it should be"); -static_assert(sizeof(Regs) >= 0x300 * sizeof(u32), "Register set structure smaller than it should be"); +// The total number of registers is chosen arbitrarily, but let's make sure it's not some odd value +// anyway. +static_assert(sizeof(Regs) <= 0x300 * sizeof(u32), + "Register set structure larger than it should be"); +static_assert(sizeof(Regs) >= 0x300 * sizeof(u32), + "Register set structure smaller than it should be"); /// Initialize Pica state void Init(); diff --git a/src/video_core/pica_state.h b/src/video_core/pica_state.h index 01f4285a8..e4f2e6d5d 100644 --- a/src/video_core/pica_state.h +++ b/src/video_core/pica_state.h @@ -5,10 +5,8 @@ #pragma once #include <array> - #include "common/bit_field.h" #include "common/common_types.h" - #include "video_core/pica.h" #include "video_core/primitive_assembly.h" #include "video_core/shader/shader.h" @@ -33,7 +31,7 @@ struct State { u32 raw; // LUT value, encoded as 12-bit fixed point, with 12 fraction bits - BitField< 0, 12, u32> value; // 0.0.12 fixed point + BitField<0, 12, u32> value; // 0.0.12 fixed point // Used by HW for efficient interpolation, Citra does not use these BitField<12, 12, s32> difference; // 1.0.11 fixed point @@ -51,8 +49,8 @@ struct State { // Used for raw access u32 raw; - BitField< 0, 13, s32> difference; // 1.1.11 fixed point - BitField<13, 11, u32> value; // 0.0.11 fixed point + BitField<0, 13, s32> difference; // 1.1.11 fixed point + BitField<13, 11, u32> value; // 0.0.11 fixed point }; std::array<LutEntry, 128> lut; diff --git a/src/video_core/pica_types.h b/src/video_core/pica_types.h index 3b7bfbdca..5d7e10066 100644 --- a/src/video_core/pica_types.h +++ b/src/video_core/pica_types.h @@ -6,7 +6,6 @@ #include <cmath> #include <cstring> - #include "common/common_types.h" namespace Pica { @@ -22,7 +21,7 @@ namespace Pica { * * @todo Verify on HW if this conversion is sufficiently accurate. */ -template<unsigned M, unsigned E> +template <unsigned M, unsigned E> struct Float { public: static Float<M, E> FromFloat32(float val) { @@ -58,7 +57,7 @@ public: return value; } - Float<M, E> operator * (const Float<M, E>& flt) const { + Float<M, E> operator*(const Float<M, E>& flt) const { if ((this->value == 0.f && !std::isnan(flt.value)) || (flt.value == 0.f && !std::isnan(this->value))) // PICA gives 0 instead of NaN when multiplying by inf @@ -66,67 +65,68 @@ public: return Float<M, E>::FromFloat32(ToFloat32() * flt.ToFloat32()); } - Float<M, E> operator / (const Float<M, E>& flt) const { + Float<M, E> operator/(const Float<M, E>& flt) const { return Float<M, E>::FromFloat32(ToFloat32() / flt.ToFloat32()); } - Float<M, E> operator + (const Float<M, E>& flt) const { + Float<M, E> operator+(const Float<M, E>& flt) const { return Float<M, E>::FromFloat32(ToFloat32() + flt.ToFloat32()); } - Float<M, E> operator - (const Float<M, E>& flt) const { + Float<M, E> operator-(const Float<M, E>& flt) const { return Float<M, E>::FromFloat32(ToFloat32() - flt.ToFloat32()); } - Float<M, E>& operator *= (const Float<M, E>& flt) { + Float<M, E>& operator*=(const Float<M, E>& flt) { if ((this->value == 0.f && !std::isnan(flt.value)) || (flt.value == 0.f && !std::isnan(this->value))) // PICA gives 0 instead of NaN when multiplying by inf *this = Zero(); - else value *= flt.ToFloat32(); + else + value *= flt.ToFloat32(); return *this; } - Float<M, E>& operator /= (const Float<M, E>& flt) { + Float<M, E>& operator/=(const Float<M, E>& flt) { value /= flt.ToFloat32(); return *this; } - Float<M, E>& operator += (const Float<M, E>& flt) { + Float<M, E>& operator+=(const Float<M, E>& flt) { value += flt.ToFloat32(); return *this; } - Float<M, E>& operator -= (const Float<M, E>& flt) { + Float<M, E>& operator-=(const Float<M, E>& flt) { value -= flt.ToFloat32(); return *this; } - Float<M, E> operator - () const { + Float<M, E> operator-() const { return Float<M, E>::FromFloat32(-ToFloat32()); } - bool operator < (const Float<M, E>& flt) const { + bool operator<(const Float<M, E>& flt) const { return ToFloat32() < flt.ToFloat32(); } - bool operator > (const Float<M, E>& flt) const { + bool operator>(const Float<M, E>& flt) const { return ToFloat32() > flt.ToFloat32(); } - bool operator >= (const Float<M, E>& flt) const { + bool operator>=(const Float<M, E>& flt) const { return ToFloat32() >= flt.ToFloat32(); } - bool operator <= (const Float<M, E>& flt) const { + bool operator<=(const Float<M, E>& flt) const { return ToFloat32() <= flt.ToFloat32(); } - bool operator == (const Float<M, E>& flt) const { + bool operator==(const Float<M, E>& flt) const { return ToFloat32() == flt.ToFloat32(); } - bool operator != (const Float<M, E>& flt) const { + bool operator!=(const Float<M, E>& flt) const { return ToFloat32() != flt.ToFloat32(); } diff --git a/src/video_core/primitive_assembly.cpp b/src/video_core/primitive_assembly.cpp index 68ea3c08a..be7377290 100644 --- a/src/video_core/primitive_assembly.cpp +++ b/src/video_core/primitive_assembly.cpp @@ -3,69 +3,66 @@ // Refer to the license.txt file included. #include "common/logging/log.h" - #include "video_core/pica.h" #include "video_core/primitive_assembly.h" #include "video_core/shader/shader.h" namespace Pica { -template<typename VertexType> +template <typename VertexType> PrimitiveAssembler<VertexType>::PrimitiveAssembler(Regs::TriangleTopology topology) - : topology(topology), buffer_index(0) { -} + : topology(topology), buffer_index(0) {} -template<typename VertexType> -void PrimitiveAssembler<VertexType>::SubmitVertex(VertexType& vtx, TriangleHandler triangle_handler) -{ +template <typename VertexType> +void PrimitiveAssembler<VertexType>::SubmitVertex(VertexType& vtx, + TriangleHandler triangle_handler) { switch (topology) { - // TODO: Figure out what's different with TriangleTopology::Shader. - case Regs::TriangleTopology::List: - case Regs::TriangleTopology::Shader: - if (buffer_index < 2) { - buffer[buffer_index++] = vtx; - } else { - buffer_index = 0; + // TODO: Figure out what's different with TriangleTopology::Shader. + case Regs::TriangleTopology::List: + case Regs::TriangleTopology::Shader: + if (buffer_index < 2) { + buffer[buffer_index++] = vtx; + } else { + buffer_index = 0; - triangle_handler(buffer[0], buffer[1], vtx); - } - break; + triangle_handler(buffer[0], buffer[1], vtx); + } + break; - case Regs::TriangleTopology::Strip: - case Regs::TriangleTopology::Fan: - if (strip_ready) - triangle_handler(buffer[0], buffer[1], vtx); + case Regs::TriangleTopology::Strip: + case Regs::TriangleTopology::Fan: + if (strip_ready) + triangle_handler(buffer[0], buffer[1], vtx); - buffer[buffer_index] = vtx; + buffer[buffer_index] = vtx; - strip_ready |= (buffer_index == 1); + strip_ready |= (buffer_index == 1); - if (topology == Regs::TriangleTopology::Strip) - buffer_index = !buffer_index; - else if (topology == Regs::TriangleTopology::Fan) - buffer_index = 1; - break; + if (topology == Regs::TriangleTopology::Strip) + buffer_index = !buffer_index; + else if (topology == Regs::TriangleTopology::Fan) + buffer_index = 1; + break; - default: - LOG_ERROR(HW_GPU, "Unknown triangle topology %x:", (int)topology); - break; + default: + LOG_ERROR(HW_GPU, "Unknown triangle topology %x:", (int)topology); + break; } } -template<typename VertexType> +template <typename VertexType> void PrimitiveAssembler<VertexType>::Reset() { buffer_index = 0; strip_ready = false; } -template<typename VertexType> +template <typename VertexType> void PrimitiveAssembler<VertexType>::Reconfigure(Regs::TriangleTopology topology) { Reset(); this->topology = topology; } // explicitly instantiate use cases -template -struct PrimitiveAssembler<Shader::OutputVertex>; +template struct PrimitiveAssembler<Shader::OutputVertex>; } // namespace diff --git a/src/video_core/primitive_assembly.h b/src/video_core/primitive_assembly.h index 9396b4c85..0384d5984 100644 --- a/src/video_core/primitive_assembly.h +++ b/src/video_core/primitive_assembly.h @@ -5,7 +5,6 @@ #pragma once #include <functional> - #include "video_core/pica.h" namespace Pica { @@ -14,11 +13,9 @@ namespace Pica { * Utility class to build triangles from a series of vertices, * according to a given triangle topology. */ -template<typename VertexType> +template <typename VertexType> struct PrimitiveAssembler { - using TriangleHandler = std::function<void(VertexType& v0, - VertexType& v1, - VertexType& v2)>; + using TriangleHandler = std::function<void(VertexType& v0, VertexType& v1, VertexType& v2)>; PrimitiveAssembler(Regs::TriangleTopology topology = Regs::TriangleTopology::List); @@ -48,5 +45,4 @@ private: bool strip_ready = false; }; - } // namespace diff --git a/src/video_core/rasterizer.cpp b/src/video_core/rasterizer.cpp index 6f369a00e..6c4bbed33 100644 --- a/src/video_core/rasterizer.cpp +++ b/src/video_core/rasterizer.cpp @@ -5,7 +5,6 @@ #include <algorithm> #include <array> #include <cmath> - #include "common/assert.h" #include "common/bit_field.h" #include "common/color.h" @@ -14,17 +13,15 @@ #include "common/math_util.h" #include "common/microprofile.h" #include "common/vector_math.h" - -#include "core/memory.h" #include "core/hw/gpu.h" - +#include "core/memory.h" #include "video_core/debug_utils/debug_utils.h" #include "video_core/pica.h" #include "video_core/pica_state.h" #include "video_core/pica_types.h" #include "video_core/rasterizer.h" -#include "video_core/utils.h" #include "video_core/shader/shader.h" +#include "video_core/utils.h" namespace Pica { @@ -39,8 +36,10 @@ static void DrawPixel(int x, int y, const Math::Vec4<u8>& color) { y = framebuffer.height - y; const u32 coarse_y = y & ~7; - u32 bytes_per_pixel = GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(framebuffer.color_format.Value())); - u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * framebuffer.width * bytes_per_pixel; + u32 bytes_per_pixel = + GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(framebuffer.color_format.Value())); + u32 dst_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + + coarse_y * framebuffer.width * bytes_per_pixel; u8* dst_pixel = Memory::GetPhysicalPointer(addr) + dst_offset; switch (framebuffer.color_format) { @@ -65,7 +64,8 @@ static void DrawPixel(int x, int y, const Math::Vec4<u8>& color) { break; default: - LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", framebuffer.color_format.Value()); + LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", + framebuffer.color_format.Value()); UNIMPLEMENTED(); } } @@ -77,8 +77,10 @@ static const Math::Vec4<u8> GetPixel(int x, int y) { y = framebuffer.height - y; const u32 coarse_y = y & ~7; - u32 bytes_per_pixel = GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(framebuffer.color_format.Value())); - u32 src_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * framebuffer.width * bytes_per_pixel; + u32 bytes_per_pixel = + GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(framebuffer.color_format.Value())); + u32 src_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + + coarse_y * framebuffer.width * bytes_per_pixel; u8* src_pixel = Memory::GetPhysicalPointer(addr) + src_offset; switch (framebuffer.color_format) { @@ -98,7 +100,8 @@ static const Math::Vec4<u8> GetPixel(int x, int y) { return Color::DecodeRGBA4(src_pixel); default: - LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", framebuffer.color_format.Value()); + LOG_CRITICAL(Render_Software, "Unknown framebuffer color format %x", + framebuffer.color_format.Value()); UNIMPLEMENTED(); } @@ -120,16 +123,16 @@ static u32 GetDepth(int x, int y) { u8* src_pixel = depth_buffer + src_offset; switch (framebuffer.depth_format) { - case Regs::DepthFormat::D16: - return Color::DecodeD16(src_pixel); - case Regs::DepthFormat::D24: - return Color::DecodeD24(src_pixel); - case Regs::DepthFormat::D24S8: - return Color::DecodeD24S8(src_pixel).x; - default: - LOG_CRITICAL(HW_GPU, "Unimplemented depth format %u", framebuffer.depth_format); - UNIMPLEMENTED(); - return 0; + case Regs::DepthFormat::D16: + return Color::DecodeD16(src_pixel); + case Regs::DepthFormat::D24: + return Color::DecodeD24(src_pixel); + case Regs::DepthFormat::D24S8: + return Color::DecodeD24S8(src_pixel).x; + default: + LOG_CRITICAL(HW_GPU, "Unimplemented depth format %u", framebuffer.depth_format); + UNIMPLEMENTED(); + return 0; } } @@ -148,12 +151,15 @@ static u8 GetStencil(int x, int y) { u8* src_pixel = depth_buffer + src_offset; switch (framebuffer.depth_format) { - case Regs::DepthFormat::D24S8: - return Color::DecodeD24S8(src_pixel).y; + case Regs::DepthFormat::D24S8: + return Color::DecodeD24S8(src_pixel).y; - default: - LOG_WARNING(HW_GPU, "GetStencil called for function which doesn't have a stencil component (format %u)", framebuffer.depth_format); - return 0; + default: + LOG_WARNING( + HW_GPU, + "GetStencil called for function which doesn't have a stencil component (format %u)", + framebuffer.depth_format); + return 0; } } @@ -172,22 +178,22 @@ static void SetDepth(int x, int y, u32 value) { u8* dst_pixel = depth_buffer + dst_offset; switch (framebuffer.depth_format) { - case Regs::DepthFormat::D16: - Color::EncodeD16(value, dst_pixel); - break; - - case Regs::DepthFormat::D24: - Color::EncodeD24(value, dst_pixel); - break; - - case Regs::DepthFormat::D24S8: - Color::EncodeD24X8(value, dst_pixel); - break; - - default: - LOG_CRITICAL(HW_GPU, "Unimplemented depth format %u", framebuffer.depth_format); - UNIMPLEMENTED(); - break; + case Regs::DepthFormat::D16: + Color::EncodeD16(value, dst_pixel); + break; + + case Regs::DepthFormat::D24: + Color::EncodeD24(value, dst_pixel); + break; + + case Regs::DepthFormat::D24S8: + Color::EncodeD24X8(value, dst_pixel); + break; + + default: + LOG_CRITICAL(HW_GPU, "Unimplemented depth format %u", framebuffer.depth_format); + UNIMPLEMENTED(); + break; } } @@ -206,19 +212,19 @@ static void SetStencil(int x, int y, u8 value) { u8* dst_pixel = depth_buffer + dst_offset; switch (framebuffer.depth_format) { - case Pica::Regs::DepthFormat::D16: - case Pica::Regs::DepthFormat::D24: - // Nothing to do - break; - - case Pica::Regs::DepthFormat::D24S8: - Color::EncodeX24S8(value, dst_pixel); - break; - - default: - LOG_CRITICAL(HW_GPU, "Unimplemented depth format %u", framebuffer.depth_format); - UNIMPLEMENTED(); - break; + case Pica::Regs::DepthFormat::D16: + case Pica::Regs::DepthFormat::D24: + // Nothing to do + break; + + case Pica::Regs::DepthFormat::D24S8: + Color::EncodeX24S8(value, dst_pixel); + break; + + default: + LOG_CRITICAL(HW_GPU, "Unimplemented depth format %u", framebuffer.depth_format); + UNIMPLEMENTED(); + break; } } @@ -262,15 +268,19 @@ struct Fix12P4 { Fix12P4() {} Fix12P4(u16 val) : val(val) {} - static u16 FracMask() { return 0xF; } - static u16 IntMask() { return (u16)~0xF; } + static u16 FracMask() { + return 0xF; + } + static u16 IntMask() { + return (u16)~0xF; + } operator u16() const { return val; } - bool operator < (const Fix12P4& oth) const { - return (u16)*this < (u16)oth; + bool operator<(const Fix12P4& oth) const { + return (u16) * this < (u16)oth; } private: @@ -283,9 +293,8 @@ private: * * @todo define orientation concretely. */ -static int SignedArea (const Math::Vec2<Fix12P4>& vtx1, - const Math::Vec2<Fix12P4>& vtx2, - const Math::Vec2<Fix12P4>& vtx3) { +static int SignedArea(const Math::Vec2<Fix12P4>& vtx1, const Math::Vec2<Fix12P4>& vtx2, + const Math::Vec2<Fix12P4>& vtx3) { const auto vec1 = Math::MakeVec(vtx2 - vtx1, 0); const auto vec2 = Math::MakeVec(vtx3 - vtx1, 0); // TODO: There is a very small chance this will overflow for sizeof(int) == 4 @@ -298,11 +307,8 @@ MICROPROFILE_DEFINE(GPU_Rasterization, "GPU", "Rasterization", MP_RGB(50, 50, 24 * Helper function for ProcessTriangle with the "reversed" flag to allow for implementing * culling via recursion. */ -static void ProcessTriangleInternal(const Shader::OutputVertex& v0, - const Shader::OutputVertex& v1, - const Shader::OutputVertex& v2, - bool reversed = false) -{ +static void ProcessTriangleInternal(const Shader::OutputVertex& v0, const Shader::OutputVertex& v1, + const Shader::OutputVertex& v2, bool reversed = false) { const auto& regs = g_state.regs; MICROPROFILE_SCOPE(GPU_Rasterization); @@ -316,9 +322,9 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, return Math::Vec3<Fix12P4>{FloatToFix(vec.x), FloatToFix(vec.y), FloatToFix(vec.z)}; }; - Math::Vec3<Fix12P4> vtxpos[3]{ ScreenToRasterizerCoordinates(v0.screenpos), - ScreenToRasterizerCoordinates(v1.screenpos), - ScreenToRasterizerCoordinates(v2.screenpos) }; + Math::Vec3<Fix12P4> vtxpos[3]{ScreenToRasterizerCoordinates(v0.screenpos), + ScreenToRasterizerCoordinates(v1.screenpos), + ScreenToRasterizerCoordinates(v2.screenpos)}; if (regs.cull_mode == Regs::CullMode::KeepAll) { // Make sure we always end up with a triangle wound counter-clockwise @@ -344,8 +350,8 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, u16 max_y = std::max({vtxpos[0].y, vtxpos[1].y, vtxpos[2].y}); // Convert the scissor box coordinates to 12.4 fixed point - u16 scissor_x1 = (u16)( regs.scissor_test.x1 << 4); - u16 scissor_y1 = (u16)( regs.scissor_test.y1 << 4); + u16 scissor_x1 = (u16)(regs.scissor_test.x1 << 4); + u16 scissor_y1 = (u16)(regs.scissor_test.y1 << 4); // x2,y2 have +1 added to cover the entire sub-pixel area u16 scissor_x2 = (u16)((regs.scissor_test.x2 + 1) << 4); u16 scissor_y2 = (u16)((regs.scissor_test.y2 + 1) << 4); @@ -369,27 +375,32 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, // NOTE: These are the PSP filling rules. Not sure if the 3DS uses the same ones... auto IsRightSideOrFlatBottomEdge = [](const Math::Vec2<Fix12P4>& vtx, const Math::Vec2<Fix12P4>& line1, - const Math::Vec2<Fix12P4>& line2) - { + const Math::Vec2<Fix12P4>& line2) { if (line1.y == line2.y) { // just check if vertex is above us => bottom line parallel to x-axis return vtx.y < line1.y; } else { // check if vertex is on our left => right side // TODO: Not sure how likely this is to overflow - return (int)vtx.x < (int)line1.x + ((int)line2.x - (int)line1.x) * ((int)vtx.y - (int)line1.y) / ((int)line2.y - (int)line1.y); + return (int)vtx.x < (int)line1.x + + ((int)line2.x - (int)line1.x) * ((int)vtx.y - (int)line1.y) / + ((int)line2.y - (int)line1.y); } }; - int bias0 = IsRightSideOrFlatBottomEdge(vtxpos[0].xy(), vtxpos[1].xy(), vtxpos[2].xy()) ? -1 : 0; - int bias1 = IsRightSideOrFlatBottomEdge(vtxpos[1].xy(), vtxpos[2].xy(), vtxpos[0].xy()) ? -1 : 0; - int bias2 = IsRightSideOrFlatBottomEdge(vtxpos[2].xy(), vtxpos[0].xy(), vtxpos[1].xy()) ? -1 : 0; + int bias0 = + IsRightSideOrFlatBottomEdge(vtxpos[0].xy(), vtxpos[1].xy(), vtxpos[2].xy()) ? -1 : 0; + int bias1 = + IsRightSideOrFlatBottomEdge(vtxpos[1].xy(), vtxpos[2].xy(), vtxpos[0].xy()) ? -1 : 0; + int bias2 = + IsRightSideOrFlatBottomEdge(vtxpos[2].xy(), vtxpos[0].xy(), vtxpos[1].xy()) ? -1 : 0; auto w_inverse = Math::MakeVec(v0.pos.w, v1.pos.w, v2.pos.w); auto textures = regs.GetTextures(); auto tev_stages = regs.GetTevStages(); - bool stencil_action_enable = g_state.regs.output_merger.stencil_test.enable && g_state.regs.framebuffer.depth_format == Regs::DepthFormat::D24S8; + bool stencil_action_enable = g_state.regs.output_merger.stencil_test.enable && + g_state.regs.framebuffer.depth_format == Regs::DepthFormat::D24S8; const auto stencil_test = g_state.regs.output_merger.stencil_test; // Enter rasterization loop, starting at the center of the topleft bounding box corner. @@ -397,10 +408,10 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, for (u16 y = min_y + 8; y < max_y; y += 0x10) { for (u16 x = min_x + 8; x < max_x; x += 0x10) { - // Do not process the pixel if it's inside the scissor box and the scissor mode is set to Exclude + // Do not process the pixel if it's inside the scissor box and the scissor mode is set + // to Exclude if (regs.scissor_test.mode == Regs::ScissorMode::Exclude) { - if (x >= scissor_x1 && x < scissor_x2 && - y >= scissor_y1 && y < scissor_y2) + if (x >= scissor_x1 && x < scissor_x2 && y >= scissor_y1 && y < scissor_y2) continue; } @@ -414,15 +425,18 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, if (w0 < 0 || w1 < 0 || w2 < 0) continue; - auto baricentric_coordinates = Math::MakeVec(float24::FromFloat32(static_cast<float>(w0)), - float24::FromFloat32(static_cast<float>(w1)), - float24::FromFloat32(static_cast<float>(w2))); - float24 interpolated_w_inverse = float24::FromFloat32(1.0f) / Math::Dot(w_inverse, baricentric_coordinates); + auto baricentric_coordinates = + Math::MakeVec(float24::FromFloat32(static_cast<float>(w0)), + float24::FromFloat32(static_cast<float>(w1)), + float24::FromFloat32(static_cast<float>(w2))); + float24 interpolated_w_inverse = + float24::FromFloat32(1.0f) / Math::Dot(w_inverse, baricentric_coordinates); // interpolated_z = z / w - float interpolated_z_over_w = (v0.screenpos[2].ToFloat32() * w0 + - v1.screenpos[2].ToFloat32() * w1 + - v2.screenpos[2].ToFloat32() * w2) / wsum; + float interpolated_z_over_w = + (v0.screenpos[2].ToFloat32() * w0 + v1.screenpos[2].ToFloat32() * w1 + + v2.screenpos[2].ToFloat32() * w2) / + wsum; // Not fully accurate. About 3 bits in precision are missing. // Z-Buffer (z / w * scale + offset) @@ -461,10 +475,18 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, }; Math::Vec4<u8> primary_color{ - (u8)(GetInterpolatedAttribute(v0.color.r(), v1.color.r(), v2.color.r()).ToFloat32() * 255), - (u8)(GetInterpolatedAttribute(v0.color.g(), v1.color.g(), v2.color.g()).ToFloat32() * 255), - (u8)(GetInterpolatedAttribute(v0.color.b(), v1.color.b(), v2.color.b()).ToFloat32() * 255), - (u8)(GetInterpolatedAttribute(v0.color.a(), v1.color.a(), v2.color.a()).ToFloat32() * 255) + (u8)( + GetInterpolatedAttribute(v0.color.r(), v1.color.r(), v2.color.r()).ToFloat32() * + 255), + (u8)( + GetInterpolatedAttribute(v0.color.g(), v1.color.g(), v2.color.g()).ToFloat32() * + 255), + (u8)( + GetInterpolatedAttribute(v0.color.b(), v1.color.b(), v2.color.b()).ToFloat32() * + 255), + (u8)( + GetInterpolatedAttribute(v0.color.a(), v1.color.a(), v2.color.a()).ToFloat32() * + 255), }; Math::Vec2<float24> uv[3]; @@ -489,7 +511,7 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, // Only unit 0 respects the texturing type (according to 3DBrew) // TODO: Refactor so cubemaps and shadowmaps can be handled if (i == 0) { - switch(texture.config.type) { + switch (texture.config.type) { case Regs::TextureConfig::Texture2D: break; case Regs::TextureConfig::Projection2D: { @@ -506,51 +528,58 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, } } - int s = (int)(u * float24::FromFloat32(static_cast<float>(texture.config.width))).ToFloat32(); - int t = (int)(v * float24::FromFloat32(static_cast<float>(texture.config.height))).ToFloat32(); + int s = (int)(u * float24::FromFloat32(static_cast<float>(texture.config.width))) + .ToFloat32(); + int t = (int)(v * float24::FromFloat32(static_cast<float>(texture.config.height))) + .ToFloat32(); - - static auto GetWrappedTexCoord = [](Regs::TextureConfig::WrapMode mode, int val, unsigned size) { + static auto GetWrappedTexCoord = [](Regs::TextureConfig::WrapMode mode, int val, + unsigned size) { switch (mode) { - case Regs::TextureConfig::ClampToEdge: - val = std::max(val, 0); - val = std::min(val, (int)size - 1); - return val; - - case Regs::TextureConfig::ClampToBorder: - return val; - - case Regs::TextureConfig::Repeat: - return (int)((unsigned)val % size); - - case Regs::TextureConfig::MirroredRepeat: - { - unsigned int coord = ((unsigned)val % (2 * size)); - if (coord >= size) - coord = 2 * size - 1 - coord; - return (int)coord; - } - - default: - LOG_ERROR(HW_GPU, "Unknown texture coordinate wrapping mode %x", (int)mode); - UNIMPLEMENTED(); - return 0; + case Regs::TextureConfig::ClampToEdge: + val = std::max(val, 0); + val = std::min(val, (int)size - 1); + return val; + + case Regs::TextureConfig::ClampToBorder: + return val; + + case Regs::TextureConfig::Repeat: + return (int)((unsigned)val % size); + + case Regs::TextureConfig::MirroredRepeat: { + unsigned int coord = ((unsigned)val % (2 * size)); + if (coord >= size) + coord = 2 * size - 1 - coord; + return (int)coord; + } + + default: + LOG_ERROR(HW_GPU, "Unknown texture coordinate wrapping mode %x", (int)mode); + UNIMPLEMENTED(); + return 0; } }; - if ((texture.config.wrap_s == Regs::TextureConfig::ClampToBorder && (s < 0 || s >= texture.config.width)) - || (texture.config.wrap_t == Regs::TextureConfig::ClampToBorder && (t < 0 || t >= texture.config.height))) { + if ((texture.config.wrap_s == Regs::TextureConfig::ClampToBorder && + (s < 0 || s >= texture.config.width)) || + (texture.config.wrap_t == Regs::TextureConfig::ClampToBorder && + (t < 0 || t >= texture.config.height))) { auto border_color = texture.config.border_color; - texture_color[i] = { border_color.r, border_color.g, border_color.b, border_color.a }; + texture_color[i] = {border_color.r, border_color.g, border_color.b, + border_color.a}; } else { // Textures are laid out from bottom to top, hence we invert the t coordinate. // NOTE: This may not be the right place for the inversion. // TODO: Check if this applies to ETC textures, too. s = GetWrappedTexCoord(texture.config.wrap_s, s, texture.config.width); - t = texture.config.height - 1 - GetWrappedTexCoord(texture.config.wrap_t, t, texture.config.height); + t = texture.config.height - 1 - + GetWrappedTexCoord(texture.config.wrap_t, t, texture.config.height); - u8* texture_data = Memory::GetPhysicalPointer(texture.config.GetPhysicalAddress()); - auto info = DebugUtils::TextureInfo::FromPicaRegister(texture.config, texture.format); + u8* texture_data = + Memory::GetPhysicalPointer(texture.config.GetPhysicalAddress()); + auto info = + DebugUtils::TextureInfo::FromPicaRegister(texture.config, texture.format); // TODO: Apply the min and mag filters to the texture texture_color[i] = DebugUtils::LookupTexture(texture_data, s, t, info); @@ -571,10 +600,11 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, Math::Vec4<u8> combiner_buffer = {0, 0, 0, 0}; Math::Vec4<u8> next_combiner_buffer = { regs.tev_combiner_buffer_color.r, regs.tev_combiner_buffer_color.g, - regs.tev_combiner_buffer_color.b, regs.tev_combiner_buffer_color.a + regs.tev_combiner_buffer_color.b, regs.tev_combiner_buffer_color.a, }; - for (unsigned tev_stage_index = 0; tev_stage_index < tev_stages.size(); ++tev_stage_index) { + for (unsigned tev_stage_index = 0; tev_stage_index < tev_stages.size(); + ++tev_stage_index) { const auto& tev_stage = tev_stages[tev_stage_index]; using Source = Regs::TevStageConfig::Source; using ColorModifier = Regs::TevStageConfig::ColorModifier; @@ -606,7 +636,8 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, return combiner_buffer; case Source::Constant: - return {tev_stage.const_r, tev_stage.const_g, tev_stage.const_b, tev_stage.const_a}; + return {tev_stage.const_r, tev_stage.const_g, tev_stage.const_b, + tev_stage.const_a}; case Source::Previous: return combiner_output; @@ -618,7 +649,8 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, } }; - static auto GetColorModifier = [](ColorModifier factor, const Math::Vec4<u8>& values) -> Math::Vec3<u8> { + static auto GetColorModifier = [](ColorModifier factor, + const Math::Vec4<u8>& values) -> Math::Vec3<u8> { switch (factor) { case ColorModifier::SourceColor: return values.rgb(); @@ -652,7 +684,8 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, } }; - static auto GetAlphaModifier = [](AlphaModifier factor, const Math::Vec4<u8>& values) -> u8 { + static auto GetAlphaModifier = [](AlphaModifier factor, + const Math::Vec4<u8>& values) -> u8 { switch (factor) { case AlphaModifier::SourceAlpha: return values.a(); @@ -680,7 +713,8 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, } }; - static auto ColorCombine = [](Operation op, const Math::Vec3<u8> input[3]) -> Math::Vec3<u8> { + static auto ColorCombine = [](Operation op, + const Math::Vec3<u8> input[3]) -> Math::Vec3<u8> { switch (op) { case Operation::Replace: return input[0]; @@ -688,8 +722,7 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, case Operation::Modulate: return ((input[0] * input[1]) / 255).Cast<u8>(); - case Operation::Add: - { + case Operation::Add: { auto result = input[0] + input[1]; result.r() = std::min(255, result.r()); result.g() = std::min(255, result.g()); @@ -697,10 +730,11 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, return result.Cast<u8>(); } - case Operation::AddSigned: - { - // TODO(bunnei): Verify that the color conversion from (float) 0.5f to (byte) 128 is correct - auto result = input[0].Cast<int>() + input[1].Cast<int>() - Math::MakeVec<int>(128, 128, 128); + case Operation::AddSigned: { + // TODO(bunnei): Verify that the color conversion from (float) 0.5f to + // (byte) 128 is correct + auto result = input[0].Cast<int>() + input[1].Cast<int>() - + Math::MakeVec<int>(128, 128, 128); result.r() = MathUtil::Clamp<int>(result.r(), 0, 255); result.g() = MathUtil::Clamp<int>(result.g(), 0, 255); result.b() = MathUtil::Clamp<int>(result.b(), 0, 255); @@ -708,10 +742,13 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, } case Operation::Lerp: - return ((input[0] * input[2] + input[1] * (Math::MakeVec<u8>(255, 255, 255) - input[2]).Cast<u8>()) / 255).Cast<u8>(); + return ((input[0] * input[2] + + input[1] * + (Math::MakeVec<u8>(255, 255, 255) - input[2]).Cast<u8>()) / + 255) + .Cast<u8>(); - case Operation::Subtract: - { + case Operation::Subtract: { auto result = input[0].Cast<int>() - input[1].Cast<int>(); result.r() = std::max(0, result.r()); result.g() = std::max(0, result.g()); @@ -719,8 +756,7 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, return result.Cast<u8>(); } - case Operation::MultiplyThenAdd: - { + case Operation::MultiplyThenAdd: { auto result = (input[0] * input[1] + 255 * input[2].Cast<int>()) / 255; result.r() = std::min(255, result.r()); result.g() = std::min(255, result.g()); @@ -728,8 +764,7 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, return result.Cast<u8>(); } - case Operation::AddThenMultiply: - { + case Operation::AddThenMultiply: { auto result = input[0] + input[1]; result.r() = std::min(255, result.r()); result.g() = std::min(255, result.g()); @@ -737,17 +772,19 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, result = (result * input[2].Cast<int>()) / 255; return result.Cast<u8>(); } - case Operation::Dot3_RGB: - { + case Operation::Dot3_RGB: { // Not fully accurate. // Worst case scenario seems to yield a +/-3 error - // Some HW results indicate that the per-component computation can't have a higher precision than 1/256, - // while dot3_rgb( (0x80,g0,b0),(0x7F,g1,b1) ) and dot3_rgb( (0x80,g0,b0),(0x80,g1,b1) ) give different results - int result = ((input[0].r() * 2 - 255) * (input[1].r() * 2 - 255) + 128) / 256 + - ((input[0].g() * 2 - 255) * (input[1].g() * 2 - 255) + 128) / 256 + - ((input[0].b() * 2 - 255) * (input[1].b() * 2 - 255) + 128) / 256; + // Some HW results indicate that the per-component computation can't have a + // higher precision than 1/256, + // while dot3_rgb( (0x80,g0,b0),(0x7F,g1,b1) ) and dot3_rgb( + // (0x80,g0,b0),(0x80,g1,b1) ) give different results + int result = + ((input[0].r() * 2 - 255) * (input[1].r() * 2 - 255) + 128) / 256 + + ((input[0].g() * 2 - 255) * (input[1].g() * 2 - 255) + 128) / 256 + + ((input[0].b() * 2 - 255) * (input[1].b() * 2 - 255) + 128) / 256; result = std::max(0, std::min(255, result)); - return { (u8)result, (u8)result, (u8)result }; + return {(u8)result, (u8)result, (u8)result}; } default: LOG_ERROR(HW_GPU, "Unknown color combiner operation %d", (int)op); @@ -756,7 +793,7 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, } }; - static auto AlphaCombine = [](Operation op, const std::array<u8,3>& input) -> u8 { + static auto AlphaCombine = [](Operation op, const std::array<u8, 3>& input) -> u8 { switch (op) { case Operation::Replace: return input[0]; @@ -767,9 +804,9 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, case Operation::Add: return std::min(255, input[0] + input[1]); - case Operation::AddSigned: - { - // TODO(bunnei): Verify that the color conversion from (float) 0.5f to (byte) 128 is correct + case Operation::AddSigned: { + // TODO(bunnei): Verify that the color conversion from (float) 0.5f to + // (byte) 128 is correct auto result = static_cast<int>(input[0]) + static_cast<int>(input[1]) - 128; return static_cast<u8>(MathUtil::Clamp<int>(result, 0, 255)); } @@ -801,32 +838,38 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, Math::Vec3<u8> color_result[3] = { GetColorModifier(tev_stage.color_modifier1, GetSource(tev_stage.color_source1)), GetColorModifier(tev_stage.color_modifier2, GetSource(tev_stage.color_source2)), - GetColorModifier(tev_stage.color_modifier3, GetSource(tev_stage.color_source3)) + GetColorModifier(tev_stage.color_modifier3, GetSource(tev_stage.color_source3)), }; auto color_output = ColorCombine(tev_stage.color_op, color_result); // alpha combiner - std::array<u8,3> alpha_result = {{ + std::array<u8, 3> alpha_result = {{ GetAlphaModifier(tev_stage.alpha_modifier1, GetSource(tev_stage.alpha_source1)), GetAlphaModifier(tev_stage.alpha_modifier2, GetSource(tev_stage.alpha_source2)), - GetAlphaModifier(tev_stage.alpha_modifier3, GetSource(tev_stage.alpha_source3)) + GetAlphaModifier(tev_stage.alpha_modifier3, GetSource(tev_stage.alpha_source3)), }}; auto alpha_output = AlphaCombine(tev_stage.alpha_op, alpha_result); - combiner_output[0] = std::min((unsigned)255, color_output.r() * tev_stage.GetColorMultiplier()); - combiner_output[1] = std::min((unsigned)255, color_output.g() * tev_stage.GetColorMultiplier()); - combiner_output[2] = std::min((unsigned)255, color_output.b() * tev_stage.GetColorMultiplier()); - combiner_output[3] = std::min((unsigned)255, alpha_output * tev_stage.GetAlphaMultiplier()); + combiner_output[0] = + std::min((unsigned)255, color_output.r() * tev_stage.GetColorMultiplier()); + combiner_output[1] = + std::min((unsigned)255, color_output.g() * tev_stage.GetColorMultiplier()); + combiner_output[2] = + std::min((unsigned)255, color_output.b() * tev_stage.GetColorMultiplier()); + combiner_output[3] = + std::min((unsigned)255, alpha_output * tev_stage.GetAlphaMultiplier()); combiner_buffer = next_combiner_buffer; - if (regs.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferColor(tev_stage_index)) { + if (regs.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferColor( + tev_stage_index)) { next_combiner_buffer.r() = combiner_output.r(); next_combiner_buffer.g() = combiner_output.g(); next_combiner_buffer.b() = combiner_output.b(); } - if (regs.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferAlpha(tev_stage_index)) { + if (regs.tev_combiner_buffer_input.TevStageUpdatesCombinerBufferAlpha( + tev_stage_index)) { next_combiner_buffer.a() = combiner_output.a(); } } @@ -897,21 +940,26 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, float fog_i = MathUtil::Clamp(floorf(fog_index), 0.0f, 127.0f); float fog_f = fog_index - fog_i; const auto& fog_lut_entry = g_state.fog.lut[static_cast<unsigned int>(fog_i)]; - float fog_factor = (fog_lut_entry.value + fog_lut_entry.difference * fog_f) / 2047.0f; // This is signed fixed point 1.11 + float fog_factor = (fog_lut_entry.value + fog_lut_entry.difference * fog_f) / + 2047.0f; // This is signed fixed point 1.11 fog_factor = MathUtil::Clamp(fog_factor, 0.0f, 1.0f); // Blend the fog for (unsigned i = 0; i < 3; i++) { - combiner_output[i] = fog_factor * combiner_output[i] + (1.0f - fog_factor) * fog_color[i]; + combiner_output[i] = + fog_factor * combiner_output[i] + (1.0f - fog_factor) * fog_color[i]; } } u8 old_stencil = 0; - auto UpdateStencil = [stencil_test, x, y, &old_stencil](Pica::Regs::StencilAction action) { - u8 new_stencil = PerformStencilAction(action, old_stencil, stencil_test.reference_value); + auto UpdateStencil = [stencil_test, x, y, + &old_stencil](Pica::Regs::StencilAction action) { + u8 new_stencil = + PerformStencilAction(action, old_stencil, stencil_test.reference_value); if (g_state.regs.framebuffer.allow_depth_stencil_write != 0) - SetStencil(x >> 4, y >> 4, (new_stencil & stencil_test.write_mask) | (old_stencil & ~stencil_test.write_mask)); + SetStencil(x >> 4, y >> 4, (new_stencil & stencil_test.write_mask) | + (old_stencil & ~stencil_test.write_mask)); }; if (stencil_action_enable) { @@ -1030,7 +1078,7 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, static_cast<u8>(output_merger.blend_const.r), static_cast<u8>(output_merger.blend_const.g), static_cast<u8>(output_merger.blend_const.b), - static_cast<u8>(output_merger.blend_const.a) + static_cast<u8>(output_merger.blend_const.a), }; switch (factor) { @@ -1091,12 +1139,13 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, return combiner_output[channel]; }; - static auto EvaluateBlendEquation = [](const Math::Vec4<u8>& src, const Math::Vec4<u8>& srcfactor, - const Math::Vec4<u8>& dest, const Math::Vec4<u8>& destfactor, - Regs::BlendEquation equation) { + static auto EvaluateBlendEquation = []( + const Math::Vec4<u8>& src, const Math::Vec4<u8>& srcfactor, + const Math::Vec4<u8>& dest, const Math::Vec4<u8>& destfactor, + Regs::BlendEquation equation) { Math::Vec4<int> result; - auto src_result = (src * srcfactor).Cast<int>(); + auto src_result = (src * srcfactor).Cast<int>(); auto dst_result = (dest * destfactor).Cast<int>(); switch (equation) { @@ -1134,10 +1183,9 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, UNIMPLEMENTED(); } - return Math::Vec4<u8>(MathUtil::Clamp(result.r(), 0, 255), - MathUtil::Clamp(result.g(), 0, 255), - MathUtil::Clamp(result.b(), 0, 255), - MathUtil::Clamp(result.a(), 0, 255)); + return Math::Vec4<u8>( + MathUtil::Clamp(result.r(), 0, 255), MathUtil::Clamp(result.g(), 0, 255), + MathUtil::Clamp(result.b(), 0, 255), MathUtil::Clamp(result.a(), 0, 255)); }; auto srcfactor = Math::MakeVec(LookupFactor(0, params.factor_source_rgb), @@ -1150,8 +1198,11 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, LookupFactor(2, params.factor_dest_rgb), LookupFactor(3, params.factor_dest_a)); - blend_output = EvaluateBlendEquation(combiner_output, srcfactor, dest, dstfactor, params.blend_equation_rgb); - blend_output.a() = EvaluateBlendEquation(combiner_output, srcfactor, dest, dstfactor, params.blend_equation_a).a(); + blend_output = EvaluateBlendEquation(combiner_output, srcfactor, dest, dstfactor, + params.blend_equation_rgb); + blend_output.a() = EvaluateBlendEquation(combiner_output, srcfactor, dest, + dstfactor, params.blend_equation_a) + .a(); } else { static auto LogicOp = [](u8 src, u8 dest, Regs::LogicOp op) -> u8 { switch (op) { @@ -1205,18 +1256,18 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, } }; - blend_output = Math::MakeVec( - LogicOp(combiner_output.r(), dest.r(), output_merger.logic_op), - LogicOp(combiner_output.g(), dest.g(), output_merger.logic_op), - LogicOp(combiner_output.b(), dest.b(), output_merger.logic_op), - LogicOp(combiner_output.a(), dest.a(), output_merger.logic_op)); + blend_output = + Math::MakeVec(LogicOp(combiner_output.r(), dest.r(), output_merger.logic_op), + LogicOp(combiner_output.g(), dest.g(), output_merger.logic_op), + LogicOp(combiner_output.b(), dest.b(), output_merger.logic_op), + LogicOp(combiner_output.a(), dest.a(), output_merger.logic_op)); } const Math::Vec4<u8> result = { - output_merger.red_enable ? blend_output.r() : dest.r(), + output_merger.red_enable ? blend_output.r() : dest.r(), output_merger.green_enable ? blend_output.g() : dest.g(), - output_merger.blue_enable ? blend_output.b() : dest.b(), - output_merger.alpha_enable ? blend_output.a() : dest.a() + output_merger.blue_enable ? blend_output.b() : dest.b(), + output_merger.alpha_enable ? blend_output.a() : dest.a(), }; if (regs.framebuffer.allow_color_write != 0) @@ -1225,8 +1276,7 @@ static void ProcessTriangleInternal(const Shader::OutputVertex& v0, } } -void ProcessTriangle(const Shader::OutputVertex& v0, - const Shader::OutputVertex& v1, +void ProcessTriangle(const Shader::OutputVertex& v0, const Shader::OutputVertex& v1, const Shader::OutputVertex& v2) { ProcessTriangleInternal(v0, v1, v2); } diff --git a/src/video_core/rasterizer.h b/src/video_core/rasterizer.h index a6a9634b4..6cbda3067 100644 --- a/src/video_core/rasterizer.h +++ b/src/video_core/rasterizer.h @@ -7,13 +7,12 @@ namespace Pica { namespace Shader { - struct OutputVertex; +struct OutputVertex; } namespace Rasterizer { -void ProcessTriangle(const Shader::OutputVertex& v0, - const Shader::OutputVertex& v1, +void ProcessTriangle(const Shader::OutputVertex& v0, const Shader::OutputVertex& v1, const Shader::OutputVertex& v2); } // namespace Rasterizer diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index bf7101665..71df233b5 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h @@ -5,7 +5,6 @@ #pragma once #include "common/common_types.h" - #include "core/hw/gpu.h" struct ScreenInfo; @@ -39,17 +38,25 @@ public: /// Notify rasterizer that any caches of the specified region should be flushed to 3DS memory virtual void FlushRegion(PAddr addr, u32 size) = 0; - /// Notify rasterizer that any caches of the specified region should be flushed to 3DS memory and invalidated + /// Notify rasterizer that any caches of the specified region should be flushed to 3DS memory + /// and invalidated virtual void FlushAndInvalidateRegion(PAddr addr, u32 size) = 0; /// Attempt to use a faster method to perform a display transfer - virtual bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) { return false; } + virtual bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) { + return false; + } /// Attempt to use a faster method to fill a region - virtual bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config) { return false; } + virtual bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config) { + return false; + } /// Attempt to use a faster method to display the framebuffer to screen - virtual bool AccelerateDisplay(const GPU::Regs::FramebufferConfig& config, PAddr framebuffer_addr, u32 pixel_stride, ScreenInfo& screen_info) { return false; } + virtual bool AccelerateDisplay(const GPU::Regs::FramebufferConfig& config, + PAddr framebuffer_addr, u32 pixel_stride, + ScreenInfo& screen_info) { + return false; + } }; - } diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp index 3f451e062..fd38175b3 100644 --- a/src/video_core/renderer_base.cpp +++ b/src/video_core/renderer_base.cpp @@ -4,11 +4,10 @@ #include <atomic> #include <memory> - #include "video_core/renderer_base.h" -#include "video_core/video_core.h" -#include "video_core/swrasterizer.h" #include "video_core/renderer_opengl/gl_rasterizer.h" +#include "video_core/swrasterizer.h" +#include "video_core/video_core.h" void RendererBase::RefreshRasterizerSetting() { bool hw_renderer_enabled = VideoCore::g_hw_renderer_enabled; diff --git a/src/video_core/renderer_base.h b/src/video_core/renderer_base.h index f68091cc8..589aca857 100644 --- a/src/video_core/renderer_base.h +++ b/src/video_core/renderer_base.h @@ -5,25 +5,17 @@ #pragma once #include <memory> - #include "common/common_types.h" - #include "video_core/rasterizer_interface.h" class EmuWindow; class RendererBase : NonCopyable { public: - /// Used to reference a framebuffer - enum kFramebuffer { - kFramebuffer_VirtualXFB = 0, - kFramebuffer_EFB, - kFramebuffer_Texture - }; + enum kFramebuffer { kFramebuffer_VirtualXFB = 0, kFramebuffer_EFB, kFramebuffer_Texture }; - virtual ~RendererBase() { - } + virtual ~RendererBase() {} /// Swap buffers (render frame) virtual void SwapBuffers() = 0; @@ -59,8 +51,8 @@ public: protected: std::unique_ptr<VideoCore::RasterizerInterface> rasterizer; - f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer - int m_current_frame = 0; ///< Current frame, should be set by the renderer + f32 m_current_fps = 0.0f; ///< Current framerate, should be set by the renderer + int m_current_frame = 0; ///< Current frame, should be set by the renderer private: bool opengl_rasterizer_active = false; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index f8393c618..60c9d9180 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -6,17 +6,13 @@ #include <string> #include <tuple> #include <utility> - #include <glad/glad.h> - #include "common/assert.h" #include "common/color.h" #include "common/logging/log.h" #include "common/math_util.h" #include "common/vector_math.h" - #include "core/hw/gpu.h" - #include "video_core/pica.h" #include "video_core/pica_state.h" #include "video_core/renderer_opengl/gl_rasterizer.h" @@ -32,8 +28,7 @@ static bool IsPassThroughTevStage(const Pica::Regs::TevStageConfig& stage) { stage.alpha_source1 == Pica::Regs::TevStageConfig::Source::Previous && stage.color_modifier1 == Pica::Regs::TevStageConfig::ColorModifier::SourceColor && stage.alpha_modifier1 == Pica::Regs::TevStageConfig::AlphaModifier::SourceAlpha && - stage.GetColorMultiplier() == 1 && - stage.GetAlphaMultiplier() == 1); + stage.GetColorMultiplier() == 1 && stage.GetAlphaMultiplier() == 1); } RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) { @@ -65,26 +60,34 @@ RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) { uniform_block_data.fog_lut_dirty = true; // Set vertex attributes - glVertexAttribPointer(GLShader::ATTRIBUTE_POSITION, 4, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, position)); + glVertexAttribPointer(GLShader::ATTRIBUTE_POSITION, 4, GL_FLOAT, GL_FALSE, + sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, position)); glEnableVertexAttribArray(GLShader::ATTRIBUTE_POSITION); - glVertexAttribPointer(GLShader::ATTRIBUTE_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, color)); + glVertexAttribPointer(GLShader::ATTRIBUTE_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), + (GLvoid*)offsetof(HardwareVertex, color)); glEnableVertexAttribArray(GLShader::ATTRIBUTE_COLOR); - glVertexAttribPointer(GLShader::ATTRIBUTE_TEXCOORD0, 2, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, tex_coord0)); - glVertexAttribPointer(GLShader::ATTRIBUTE_TEXCOORD1, 2, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, tex_coord1)); - glVertexAttribPointer(GLShader::ATTRIBUTE_TEXCOORD2, 2, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, tex_coord2)); + glVertexAttribPointer(GLShader::ATTRIBUTE_TEXCOORD0, 2, GL_FLOAT, GL_FALSE, + sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, tex_coord0)); + glVertexAttribPointer(GLShader::ATTRIBUTE_TEXCOORD1, 2, GL_FLOAT, GL_FALSE, + sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, tex_coord1)); + glVertexAttribPointer(GLShader::ATTRIBUTE_TEXCOORD2, 2, GL_FLOAT, GL_FALSE, + sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, tex_coord2)); glEnableVertexAttribArray(GLShader::ATTRIBUTE_TEXCOORD0); glEnableVertexAttribArray(GLShader::ATTRIBUTE_TEXCOORD1); glEnableVertexAttribArray(GLShader::ATTRIBUTE_TEXCOORD2); - glVertexAttribPointer(GLShader::ATTRIBUTE_TEXCOORD0_W, 1, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, tex_coord0_w)); + glVertexAttribPointer(GLShader::ATTRIBUTE_TEXCOORD0_W, 1, GL_FLOAT, GL_FALSE, + sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, tex_coord0_w)); glEnableVertexAttribArray(GLShader::ATTRIBUTE_TEXCOORD0_W); - glVertexAttribPointer(GLShader::ATTRIBUTE_NORMQUAT, 4, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, normquat)); + glVertexAttribPointer(GLShader::ATTRIBUTE_NORMQUAT, 4, GL_FLOAT, GL_FALSE, + sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, normquat)); glEnableVertexAttribArray(GLShader::ATTRIBUTE_NORMQUAT); - glVertexAttribPointer(GLShader::ATTRIBUTE_VIEW, 3, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, view)); + glVertexAttribPointer(GLShader::ATTRIBUTE_VIEW, 3, GL_FLOAT, GL_FALSE, sizeof(HardwareVertex), + (GLvoid*)offsetof(HardwareVertex, view)); glEnableVertexAttribArray(GLShader::ATTRIBUTE_VIEW); // Create render framebuffer @@ -129,9 +132,7 @@ RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) { SyncDepthWriteMask(); } -RasterizerOpenGL::~RasterizerOpenGL() { - -} +RasterizerOpenGL::~RasterizerOpenGL() {} /** * This is a helper function to resolve an issue with opposite quaternions being interpolated by @@ -149,8 +150,8 @@ RasterizerOpenGL::~RasterizerOpenGL() { * manually using two Lerps, and doing this correction before each Lerp. */ static bool AreQuaternionsOpposite(Math::Vec4<Pica::float24> qa, Math::Vec4<Pica::float24> qb) { - Math::Vec4f a{ qa.x.ToFloat32(), qa.y.ToFloat32(), qa.z.ToFloat32(), qa.w.ToFloat32() }; - Math::Vec4f b{ qb.x.ToFloat32(), qb.y.ToFloat32(), qb.z.ToFloat32(), qb.w.ToFloat32() }; + Math::Vec4f a{qa.x.ToFloat32(), qa.y.ToFloat32(), qa.z.ToFloat32(), qa.w.ToFloat32()}; + Math::Vec4f b{qb.x.ToFloat32(), qb.y.ToFloat32(), qb.z.ToFloat32(), qb.w.ToFloat32()}; return (Math::Dot(a, b) < 0.f); } @@ -173,15 +174,20 @@ void RasterizerOpenGL::DrawTriangles() { CachedSurface* color_surface; CachedSurface* depth_surface; MathUtil::Rectangle<int> rect; - std::tie(color_surface, depth_surface, rect) = res_cache.GetFramebufferSurfaces(regs.framebuffer); + std::tie(color_surface, depth_surface, rect) = + res_cache.GetFramebufferSurfaces(regs.framebuffer); state.draw.draw_framebuffer = framebuffer.handle; state.Apply(); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_surface != nullptr ? color_surface->texture.handle : 0, 0); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_surface != nullptr ? depth_surface->texture.handle : 0, 0); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + color_surface != nullptr ? color_surface->texture.handle : 0, 0); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, + depth_surface != nullptr ? depth_surface->texture.handle : 0, 0); bool has_stencil = regs.framebuffer.depth_format == Pica::Regs::DepthFormat::D24S8; - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, (has_stencil && depth_surface != nullptr) ? depth_surface->texture.handle : 0, 0); + glFramebufferTexture2D( + GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, + (has_stencil && depth_surface != nullptr) ? depth_surface->texture.handle : 0, 0); if (OpenGLState::CheckFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { return; @@ -194,7 +200,8 @@ void RasterizerOpenGL::DrawTriangles() { glViewport((GLint)(rect.left + regs.viewport_corner.x * color_surface->res_scale_width), (GLint)(rect.bottom + regs.viewport_corner.y * color_surface->res_scale_height), - (GLsizei)(viewport_width * color_surface->res_scale_width), (GLsizei)(viewport_height * color_surface->res_scale_height)); + (GLsizei)(viewport_width * color_surface->res_scale_width), + (GLsizei)(viewport_height * color_surface->res_scale_height)); if (uniform_block_data.data.framebuffer_scale[0] != color_surface->res_scale_width || uniform_block_data.data.framebuffer_scale[1] != color_surface->res_scale_height) { @@ -245,14 +252,16 @@ void RasterizerOpenGL::DrawTriangles() { // Sync the uniform data if (uniform_block_data.dirty) { - glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformData), &uniform_block_data.data, GL_STATIC_DRAW); + glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformData), &uniform_block_data.data, + GL_STATIC_DRAW); uniform_block_data.dirty = false; } state.Apply(); // Draw the vertex batch - glBufferData(GL_ARRAY_BUFFER, vertex_batch.size() * sizeof(HardwareVertex), vertex_batch.data(), GL_STREAM_DRAW); + glBufferData(GL_ARRAY_BUFFER, vertex_batch.size() * sizeof(HardwareVertex), vertex_batch.data(), + GL_STREAM_DRAW); glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vertex_batch.size()); // Mark framebuffer surfaces as dirty @@ -278,7 +287,7 @@ void RasterizerOpenGL::DrawTriangles() { void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { const auto& regs = Pica::g_state.regs; - switch(id) { + switch (id) { // Culling case PICA_REG_INDEX(cull_mode): SyncCullMode(); @@ -548,7 +557,7 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { SyncLightAmbient(7); break; - // Fragment lighting position + // Fragment lighting position case PICA_REG_INDEX_WORKAROUND(lighting.light[0].x, 0x144 + 0 * 0x10): case PICA_REG_INDEX_WORKAROUND(lighting.light[0].z, 0x145 + 0 * 0x10): SyncLightPosition(0); @@ -659,13 +668,11 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[4], 0x1cc): case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[5], 0x1cd): case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[6], 0x1ce): - case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[7], 0x1cf): - { + case PICA_REG_INDEX_WORKAROUND(lighting.lut_data[7], 0x1cf): { auto& lut_config = regs.lighting.lut_config; uniform_block_data.lut_dirty[lut_config.type / 4] = true; break; } - } } @@ -699,8 +706,10 @@ bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransfe CachedSurface dst_params; dst_params.addr = config.GetPhysicalOutputAddress(); - dst_params.width = config.scaling != config.NoScale ? config.output_width / 2 : config.output_width.Value(); - dst_params.height = config.scaling == config.ScaleXY ? config.output_height / 2 : config.output_height.Value(); + dst_params.width = + config.scaling != config.NoScale ? config.output_width / 2 : config.output_width.Value(); + dst_params.height = + config.scaling == config.ScaleXY ? config.output_height / 2 : config.output_height.Value(); dst_params.is_tiled = config.input_linear != config.dont_swizzle; dst_params.pixel_format = CachedSurface::PixelFormatFromGPUPixelFormat(config.output_format); @@ -735,7 +744,8 @@ bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransfe return false; } - u32 dst_size = dst_params.width * dst_params.height * CachedSurface::GetFormatBpp(dst_params.pixel_format) / 8; + u32 dst_size = dst_params.width * dst_params.height * + CachedSurface::GetFormatBpp(dst_params.pixel_format) / 8; dst_surface->dirty = true; res_cache.FlushRegion(config.GetPhysicalOutputAddress(), dst_size, dst_surface, true); return true; @@ -757,12 +767,15 @@ bool RasterizerOpenGL::AccelerateFill(const GPU::Regs::MemoryFillConfig& config) GLuint old_fb = cur_state.draw.draw_framebuffer; cur_state.draw.draw_framebuffer = framebuffer.handle; - // TODO: When scissor test is implemented, need to disable scissor test in cur_state here so Clear call isn't affected + // TODO: When scissor test is implemented, need to disable scissor test in cur_state here so + // Clear call isn't affected cur_state.Apply(); if (dst_type == SurfaceType::Color || dst_type == SurfaceType::Texture) { - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_surface->texture.handle, 0); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + dst_surface->texture.handle, 0); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, + 0); if (OpenGLState::CheckFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { return false; @@ -770,8 +783,10 @@ bool RasterizerOpenGL::AccelerateFill(const GPU::Regs::MemoryFillConfig& config) GLfloat color_values[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - // TODO: Handle additional pixel format and fill value size combinations to accelerate more cases - // For instance, checking if fill value's bytes/bits repeat to allow filling I8/A8/I4/A4/... + // TODO: Handle additional pixel format and fill value size combinations to accelerate more + // cases + // For instance, checking if fill value's bytes/bits repeat to allow filling + // I8/A8/I4/A4/... // Currently only handles formats that are multiples of the fill value size if (config.fill_24bit) { @@ -846,7 +861,8 @@ bool RasterizerOpenGL::AccelerateFill(const GPU::Regs::MemoryFillConfig& config) glClearBufferfv(GL_COLOR, 0, color_values); } else if (dst_type == SurfaceType::Depth) { glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, dst_surface->texture.handle, 0); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, + dst_surface->texture.handle, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); if (OpenGLState::CheckFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { @@ -865,7 +881,8 @@ bool RasterizerOpenGL::AccelerateFill(const GPU::Regs::MemoryFillConfig& config) glClearBufferfv(GL_DEPTH, 0, &value_float); } else if (dst_type == SurfaceType::DepthStencil) { glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, dst_surface->texture.handle, 0); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, + dst_surface->texture.handle, 0); if (OpenGLState::CheckFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { return false; @@ -889,7 +906,9 @@ bool RasterizerOpenGL::AccelerateFill(const GPU::Regs::MemoryFillConfig& config) return true; } -bool RasterizerOpenGL::AccelerateDisplay(const GPU::Regs::FramebufferConfig& config, PAddr framebuffer_addr, u32 pixel_stride, ScreenInfo& screen_info) { +bool RasterizerOpenGL::AccelerateDisplay(const GPU::Regs::FramebufferConfig& config, + PAddr framebuffer_addr, u32 pixel_stride, + ScreenInfo& screen_info) { if (framebuffer_addr == 0) { return false; } @@ -912,10 +931,9 @@ bool RasterizerOpenGL::AccelerateDisplay(const GPU::Regs::FramebufferConfig& con u32 scaled_width = src_surface->GetScaledWidth(); u32 scaled_height = src_surface->GetScaledHeight(); - screen_info.display_texcoords = MathUtil::Rectangle<float>((float)src_rect.top / (float)scaled_height, - (float)src_rect.left / (float)scaled_width, - (float)src_rect.bottom / (float)scaled_height, - (float)src_rect.right / (float)scaled_width); + screen_info.display_texcoords = MathUtil::Rectangle<float>( + (float)src_rect.top / (float)scaled_height, (float)src_rect.left / (float)scaled_width, + (float)src_rect.bottom / (float)scaled_height, (float)src_rect.right / (float)scaled_width); screen_info.display_texture = src_surface->texture.handle; @@ -928,7 +946,8 @@ void RasterizerOpenGL::SamplerInfo::Create() { wrap_s = wrap_t = TextureConfig::Repeat; border_color = 0; - glSamplerParameteri(sampler.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // default is GL_LINEAR_MIPMAP_LINEAR + glSamplerParameteri(sampler.handle, GL_TEXTURE_MIN_FILTER, + GL_LINEAR); // default is GL_LINEAR_MIPMAP_LINEAR // Other attributes have correct defaults } @@ -976,41 +995,64 @@ void RasterizerOpenGL::SetShader() { } else { LOG_DEBUG(Render_OpenGL, "Creating new shader"); - shader->shader.Create(GLShader::GenerateVertexShader().c_str(), GLShader::GenerateFragmentShader(config).c_str()); + shader->shader.Create(GLShader::GenerateVertexShader().c_str(), + GLShader::GenerateFragmentShader(config).c_str()); state.draw.shader_program = shader->shader.handle; state.Apply(); // Set the texture samplers to correspond to different texture units GLuint uniform_tex = glGetUniformLocation(shader->shader.handle, "tex[0]"); - if (uniform_tex != -1) { glUniform1i(uniform_tex, 0); } + if (uniform_tex != -1) { + glUniform1i(uniform_tex, 0); + } uniform_tex = glGetUniformLocation(shader->shader.handle, "tex[1]"); - if (uniform_tex != -1) { glUniform1i(uniform_tex, 1); } + if (uniform_tex != -1) { + glUniform1i(uniform_tex, 1); + } uniform_tex = glGetUniformLocation(shader->shader.handle, "tex[2]"); - if (uniform_tex != -1) { glUniform1i(uniform_tex, 2); } + if (uniform_tex != -1) { + glUniform1i(uniform_tex, 2); + } // Set the texture samplers to correspond to different lookup table texture units GLuint uniform_lut = glGetUniformLocation(shader->shader.handle, "lut[0]"); - if (uniform_lut != -1) { glUniform1i(uniform_lut, 3); } + if (uniform_lut != -1) { + glUniform1i(uniform_lut, 3); + } uniform_lut = glGetUniformLocation(shader->shader.handle, "lut[1]"); - if (uniform_lut != -1) { glUniform1i(uniform_lut, 4); } + if (uniform_lut != -1) { + glUniform1i(uniform_lut, 4); + } uniform_lut = glGetUniformLocation(shader->shader.handle, "lut[2]"); - if (uniform_lut != -1) { glUniform1i(uniform_lut, 5); } + if (uniform_lut != -1) { + glUniform1i(uniform_lut, 5); + } uniform_lut = glGetUniformLocation(shader->shader.handle, "lut[3]"); - if (uniform_lut != -1) { glUniform1i(uniform_lut, 6); } + if (uniform_lut != -1) { + glUniform1i(uniform_lut, 6); + } uniform_lut = glGetUniformLocation(shader->shader.handle, "lut[4]"); - if (uniform_lut != -1) { glUniform1i(uniform_lut, 7); } + if (uniform_lut != -1) { + glUniform1i(uniform_lut, 7); + } uniform_lut = glGetUniformLocation(shader->shader.handle, "lut[5]"); - if (uniform_lut != -1) { glUniform1i(uniform_lut, 8); } + if (uniform_lut != -1) { + glUniform1i(uniform_lut, 8); + } GLuint uniform_fog_lut = glGetUniformLocation(shader->shader.handle, "fog_lut"); - if (uniform_fog_lut != -1) { glUniform1i(uniform_fog_lut, 9); } + if (uniform_fog_lut != -1) { + glUniform1i(uniform_fog_lut, 9); + } current_shader = shader_cache.emplace(config, std::move(shader)).first->second.get(); - unsigned int block_index = glGetUniformBlockIndex(current_shader->shader.handle, "shader_data"); + unsigned int block_index = + glGetUniformBlockIndex(current_shader->shader.handle, "shader_data"); GLint block_size; - glGetActiveUniformBlockiv(current_shader->shader.handle, block_index, GL_UNIFORM_BLOCK_DATA_SIZE, &block_size); + glGetActiveUniformBlockiv(current_shader->shader.handle, block_index, + GL_UNIFORM_BLOCK_DATA_SIZE, &block_size); ASSERT_MSG(block_size == sizeof(UniformData), "Uniform block size did not match!"); glUniformBlockBinding(current_shader->shader.handle, block_index, 0); @@ -1073,7 +1115,8 @@ void RasterizerOpenGL::SyncDepthScale() { } void RasterizerOpenGL::SyncDepthOffset() { - float depth_offset = Pica::float24::FromRaw(Pica::g_state.regs.viewport_depth_near_plane).ToFloat32(); + float depth_offset = + Pica::float24::FromRaw(Pica::g_state.regs.viewport_depth_near_plane).ToFloat32(); if (depth_offset != uniform_block_data.data.depth_offset) { uniform_block_data.data.depth_offset = depth_offset; uniform_block_data.dirty = true; @@ -1086,10 +1129,14 @@ void RasterizerOpenGL::SyncBlendEnabled() { void RasterizerOpenGL::SyncBlendFuncs() { const auto& regs = Pica::g_state.regs; - state.blend.rgb_equation = PicaToGL::BlendEquation(regs.output_merger.alpha_blending.blend_equation_rgb); - state.blend.a_equation = PicaToGL::BlendEquation(regs.output_merger.alpha_blending.blend_equation_a); - state.blend.src_rgb_func = PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_source_rgb); - state.blend.dst_rgb_func = PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_dest_rgb); + state.blend.rgb_equation = + PicaToGL::BlendEquation(regs.output_merger.alpha_blending.blend_equation_rgb); + state.blend.a_equation = + PicaToGL::BlendEquation(regs.output_merger.alpha_blending.blend_equation_a); + state.blend.src_rgb_func = + PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_source_rgb); + state.blend.dst_rgb_func = + PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_dest_rgb); state.blend.src_a_func = PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_source_a); state.blend.dst_a_func = PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_dest_a); } @@ -1105,9 +1152,8 @@ void RasterizerOpenGL::SyncBlendColor() { void RasterizerOpenGL::SyncFogColor() { const auto& regs = Pica::g_state.regs; uniform_block_data.data.fog_color = { - regs.fog_color.r.Value() / 255.0f, - regs.fog_color.g.Value() / 255.0f, - regs.fog_color.b.Value() / 255.0f + regs.fog_color.r.Value() / 255.0f, regs.fog_color.g.Value() / 255.0f, + regs.fog_color.b.Value() / 255.0f, }; uniform_block_data.dirty = true; } @@ -1115,14 +1161,14 @@ void RasterizerOpenGL::SyncFogColor() { void RasterizerOpenGL::SyncFogLUT() { std::array<GLuint, 128> new_data; - std::transform(Pica::g_state.fog.lut.begin(), Pica::g_state.fog.lut.end(), new_data.begin(), [](const auto& entry) { - return entry.raw; - }); + std::transform(Pica::g_state.fog.lut.begin(), Pica::g_state.fog.lut.end(), new_data.begin(), + [](const auto& entry) { return entry.raw; }); if (new_data != fog_lut_data) { fog_lut_data = new_data; glActiveTexture(GL_TEXTURE9); - glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 128, GL_RED_INTEGER, GL_UNSIGNED_INT, fog_lut_data.data()); + glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 128, GL_RED_INTEGER, GL_UNSIGNED_INT, + fog_lut_data.data()); } } @@ -1154,34 +1200,40 @@ void RasterizerOpenGL::SyncColorWriteMask() { void RasterizerOpenGL::SyncStencilWriteMask() { const auto& regs = Pica::g_state.regs; state.stencil.write_mask = (regs.framebuffer.allow_depth_stencil_write != 0) - ? static_cast<GLuint>(regs.output_merger.stencil_test.write_mask) - : 0; + ? static_cast<GLuint>(regs.output_merger.stencil_test.write_mask) + : 0; } void RasterizerOpenGL::SyncDepthWriteMask() { const auto& regs = Pica::g_state.regs; - state.depth.write_mask = (regs.framebuffer.allow_depth_stencil_write != 0 && regs.output_merger.depth_write_enable) - ? GL_TRUE - : GL_FALSE; + state.depth.write_mask = + (regs.framebuffer.allow_depth_stencil_write != 0 && regs.output_merger.depth_write_enable) + ? GL_TRUE + : GL_FALSE; } void RasterizerOpenGL::SyncStencilTest() { const auto& regs = Pica::g_state.regs; - state.stencil.test_enabled = regs.output_merger.stencil_test.enable && regs.framebuffer.depth_format == Pica::Regs::DepthFormat::D24S8; + state.stencil.test_enabled = regs.output_merger.stencil_test.enable && + regs.framebuffer.depth_format == Pica::Regs::DepthFormat::D24S8; state.stencil.test_func = PicaToGL::CompareFunc(regs.output_merger.stencil_test.func); state.stencil.test_ref = regs.output_merger.stencil_test.reference_value; state.stencil.test_mask = regs.output_merger.stencil_test.input_mask; - state.stencil.action_stencil_fail = PicaToGL::StencilOp(regs.output_merger.stencil_test.action_stencil_fail); - state.stencil.action_depth_fail = PicaToGL::StencilOp(regs.output_merger.stencil_test.action_depth_fail); - state.stencil.action_depth_pass = PicaToGL::StencilOp(regs.output_merger.stencil_test.action_depth_pass); + state.stencil.action_stencil_fail = + PicaToGL::StencilOp(regs.output_merger.stencil_test.action_stencil_fail); + state.stencil.action_depth_fail = + PicaToGL::StencilOp(regs.output_merger.stencil_test.action_depth_fail); + state.stencil.action_depth_pass = + PicaToGL::StencilOp(regs.output_merger.stencil_test.action_depth_pass); } void RasterizerOpenGL::SyncDepthTest() { const auto& regs = Pica::g_state.regs; - state.depth.test_enabled = regs.output_merger.depth_test_enable == 1 || - regs.output_merger.depth_write_enable == 1; - state.depth.test_func = regs.output_merger.depth_test_enable == 1 ? - PicaToGL::CompareFunc(regs.output_merger.depth_test_func) : GL_ALWAYS; + state.depth.test_enabled = + regs.output_merger.depth_test_enable == 1 || regs.output_merger.depth_write_enable == 1; + state.depth.test_func = regs.output_merger.depth_test_enable == 1 + ? PicaToGL::CompareFunc(regs.output_merger.depth_test_func) + : GL_ALWAYS; } void RasterizerOpenGL::SyncScissorTest() { @@ -1208,7 +1260,8 @@ void RasterizerOpenGL::SyncCombinerColor() { } } -void RasterizerOpenGL::SyncTevConstColor(int stage_index, const Pica::Regs::TevStageConfig& tev_stage) { +void RasterizerOpenGL::SyncTevConstColor(int stage_index, + const Pica::Regs::TevStageConfig& tev_stage) { auto const_color = PicaToGL::ColorRGBA8(tev_stage.const_color); if (const_color != uniform_block_data.data.const_color[stage_index]) { uniform_block_data.data.const_color[stage_index] = const_color; @@ -1237,7 +1290,8 @@ void RasterizerOpenGL::SyncLightingLUT(unsigned lut_index) { if (new_data != lighting_lut_data[lut_index]) { lighting_lut_data[lut_index] = new_data; glActiveTexture(GL_TEXTURE3 + lut_index); - glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 256, GL_RGBA, GL_FLOAT, lighting_lut_data[lut_index].data()); + glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 256, GL_RGBA, GL_FLOAT, + lighting_lut_data[lut_index].data()); } } @@ -1277,7 +1331,7 @@ void RasterizerOpenGL::SyncLightPosition(int light_index) { GLvec3 position = { Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].x).ToFloat32(), Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].y).ToFloat32(), - Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].z).ToFloat32() }; + Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].z).ToFloat32()}; if (position != uniform_block_data.data.light_src[light_index].position) { uniform_block_data.data.light_src[light_index].position = position; @@ -1286,7 +1340,9 @@ void RasterizerOpenGL::SyncLightPosition(int light_index) { } void RasterizerOpenGL::SyncLightDistanceAttenuationBias(int light_index) { - GLfloat dist_atten_bias = Pica::float20::FromRaw(Pica::g_state.regs.lighting.light[light_index].dist_atten_bias).ToFloat32(); + GLfloat dist_atten_bias = + Pica::float20::FromRaw(Pica::g_state.regs.lighting.light[light_index].dist_atten_bias) + .ToFloat32(); if (dist_atten_bias != uniform_block_data.data.light_src[light_index].dist_atten_bias) { uniform_block_data.data.light_src[light_index].dist_atten_bias = dist_atten_bias; @@ -1295,7 +1351,9 @@ void RasterizerOpenGL::SyncLightDistanceAttenuationBias(int light_index) { } void RasterizerOpenGL::SyncLightDistanceAttenuationScale(int light_index) { - GLfloat dist_atten_scale = Pica::float20::FromRaw(Pica::g_state.regs.lighting.light[light_index].dist_atten_scale).ToFloat32(); + GLfloat dist_atten_scale = + Pica::float20::FromRaw(Pica::g_state.regs.lighting.light[light_index].dist_atten_scale) + .ToFloat32(); if (dist_atten_scale != uniform_block_data.data.light_src[light_index].dist_atten_scale) { uniform_block_data.data.light_src[light_index].dist_atten_scale = dist_atten_scale; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index c5029432b..24fefed1b 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -8,18 +8,14 @@ #include <cstddef> #include <cstring> #include <memory> -#include <vector> #include <unordered_map> - +#include <vector> #include <glad/glad.h> - #include "common/bit_field.h" #include "common/common_types.h" #include "common/hash.h" #include "common/vector_math.h" - #include "core/hw/gpu.h" - #include "video_core/pica.h" #include "video_core/pica_state.h" #include "video_core/pica_types.h" @@ -40,10 +36,10 @@ struct ScreenInfo; * Pica state is not being captured in the shader cache key, thereby resulting in (what should be) * two separate shaders sharing the same key. * - * We use a union because "implicitly-defined copy/move constructor for a union X copies the object representation of X." - * and "implicitly-defined copy assignment operator for a union X copies the object representation (3.9) of X." - * = Bytewise copy instead of memberwise copy. - * This is important because the padding bytes are included in the hash and comparison between objects. + * We use a union because "implicitly-defined copy/move constructor for a union X copies the object + * representation of X." and "implicitly-defined copy assignment operator for a union X copies the + * object representation (3.9) of X." = Bytewise copy instead of memberwise copy. This is important + * because the padding bytes are included in the hash and comparison between objects. */ union PicaShaderConfig { @@ -60,8 +56,9 @@ union PicaShaderConfig { state.depthmap_enable = regs.depthmap_enable; - state.alpha_test_func = regs.output_merger.alpha_test.enable ? - regs.output_merger.alpha_test.func.Value() : Pica::Regs::CompareFunc::Always; + state.alpha_test_func = regs.output_merger.alpha_test.enable + ? regs.output_merger.alpha_test.func.Value() + : Pica::Regs::CompareFunc::Always; state.texture0_type = regs.texture0.type; @@ -81,9 +78,8 @@ union PicaShaderConfig { state.fog_mode = regs.fog_mode; state.fog_flip = regs.fog_flip; - state.combiner_buffer_input = - regs.tev_combiner_buffer_input.update_mask_rgb.Value() | - regs.tev_combiner_buffer_input.update_mask_a.Value() << 4; + state.combiner_buffer_input = regs.tev_combiner_buffer_input.update_mask_rgb.Value() | + regs.tev_combiner_buffer_input.update_mask_a.Value() << 4; // Fragment lighting @@ -95,8 +91,10 @@ union PicaShaderConfig { const auto& light = regs.lighting.light[num]; state.lighting.light[light_index].num = num; state.lighting.light[light_index].directional = light.config.directional != 0; - state.lighting.light[light_index].two_sided_diffuse = light.config.two_sided_diffuse != 0; - state.lighting.light[light_index].dist_atten_enable = !regs.lighting.IsDistAttenDisabled(num); + state.lighting.light[light_index].two_sided_diffuse = + light.config.two_sided_diffuse != 0; + state.lighting.light[light_index].dist_atten_enable = + !regs.lighting.IsDistAttenDisabled(num); } state.lighting.lut_d0.enable = regs.lighting.config1.disable_lut_d0 == 0; @@ -147,7 +145,7 @@ union PicaShaderConfig { return (stage_index < 4) && ((state.combiner_buffer_input >> 4) & (1 << stage_index)); } - bool operator ==(const PicaShaderConfig& o) const { + bool operator==(const PicaShaderConfig& o) const { return std::memcmp(&state, &o.state, sizeof(PicaShaderConfig::State)) == 0; }; @@ -212,7 +210,8 @@ union PicaShaderConfig { } state; }; #if (__GNUC__ >= 5) || defined(__clang__) || defined(_MSC_VER) -static_assert(std::is_trivially_copyable<PicaShaderConfig::State>::value, "PicaShaderConfig::State must be trivially copyable"); +static_assert(std::is_trivially_copyable<PicaShaderConfig::State>::value, + "PicaShaderConfig::State must be trivially copyable"); #endif namespace std { @@ -228,12 +227,10 @@ struct hash<PicaShaderConfig> { class RasterizerOpenGL : public VideoCore::RasterizerInterface { public: - RasterizerOpenGL(); ~RasterizerOpenGL() override; - void AddTriangle(const Pica::Shader::OutputVertex& v0, - const Pica::Shader::OutputVertex& v1, + void AddTriangle(const Pica::Shader::OutputVertex& v0, const Pica::Shader::OutputVertex& v1, const Pica::Shader::OutputVertex& v2) override; void DrawTriangles() override; void NotifyPicaRegisterChanged(u32 id) override; @@ -242,7 +239,8 @@ public: void FlushAndInvalidateRegion(PAddr addr, u32 size) override; bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) override; bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config) override; - bool AccelerateDisplay(const GPU::Regs::FramebufferConfig& config, PAddr framebuffer_addr, u32 pixel_stride, ScreenInfo& screen_info) override; + bool AccelerateDisplay(const GPU::Regs::FramebufferConfig& config, PAddr framebuffer_addr, + u32 pixel_stride, ScreenInfo& screen_info) override; /// OpenGL shader generated for a given Pica register state struct PicaShader { @@ -251,13 +249,13 @@ public: }; private: - struct SamplerInfo { using TextureConfig = Pica::Regs::TextureConfig; OGLSampler sampler; - /// Creates the sampler object, initializing its state so that it's in sync with the SamplerInfo struct. + /// Creates the sampler object, initializing its state so that it's in sync with the + /// SamplerInfo struct. void Create(); /// Syncs the sampler object with the config, updating any necessary state. void SyncWithConfig(const TextureConfig& config); @@ -343,8 +341,11 @@ private: alignas(16) GLvec4 tev_combiner_buffer_color; }; - static_assert(sizeof(UniformData) == 0x3C0, "The size of the UniformData structure has changed, update the structure in the shader"); - static_assert(sizeof(UniformData) < 16384, "UniformData structure must be less than 16kb as per the OpenGL spec"); + static_assert( + sizeof(UniformData) == 0x3C0, + "The size of the UniformData structure has changed, update the structure in the shader"); + static_assert(sizeof(UniformData) < 16384, + "UniformData structure must be less than 16kb as per the OpenGL spec"); /// Sets the OpenGL shader in accordance with the current PICA register state void SetShader(); diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 7efd0038a..5cbad9b43 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -9,18 +9,14 @@ #include <unordered_set> #include <utility> #include <vector> - #include <glad/glad.h> - #include "common/bit_field.h" #include "common/emu_window.h" #include "common/logging/log.h" #include "common/math_util.h" #include "common/microprofile.h" #include "common/vector_math.h" - #include "core/memory.h" - #include "video_core/debug_utils/debug_utils.h" #include "video_core/pica_state.h" #include "video_core/renderer_opengl/gl_rasterizer_cache.h" @@ -35,18 +31,18 @@ struct FormatTuple { }; static const std::array<FormatTuple, 5> fb_format_tuples = {{ - { GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8 }, // RGBA8 - { GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE }, // RGB8 - { GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 }, // RGB5A1 - { GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5 }, // RGB565 - { GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 }, // RGBA4 + {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8}, // RGBA8 + {GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE}, // RGB8 + {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1}, // RGB5A1 + {GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, // RGB565 + {GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4}, // RGBA4 }}; static const std::array<FormatTuple, 4> depth_format_tuples = {{ - { GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT }, // D16 + {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // D16 {}, - { GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT }, // D24 - { GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8 }, // D24S8 + {GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT}, // D24 + {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // D24S8 }}; RasterizerCacheOpenGL::RasterizerCacheOpenGL() { @@ -58,7 +54,9 @@ RasterizerCacheOpenGL::~RasterizerCacheOpenGL() { FlushAll(); } -static void MortonCopyPixels(CachedSurface::PixelFormat pixel_format, u32 width, u32 height, u32 bytes_per_pixel, u32 gl_bytes_per_pixel, u8* morton_data, u8* gl_data, bool morton_to_gl) { +static void MortonCopyPixels(CachedSurface::PixelFormat pixel_format, u32 width, u32 height, + u32 bytes_per_pixel, u32 gl_bytes_per_pixel, u8* morton_data, + u8* gl_data, bool morton_to_gl) { using PixelFormat = CachedSurface::PixelFormat; u8* data_ptrs[2]; @@ -72,7 +70,8 @@ static void MortonCopyPixels(CachedSurface::PixelFormat pixel_format, u32 width, for (unsigned y = 0; y < height; ++y) { for (unsigned x = 0; x < width; ++x) { const u32 coarse_y = y & ~7; - u32 morton_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * width * bytes_per_pixel; + u32 morton_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + + coarse_y * width * bytes_per_pixel; u32 gl_pixel_index = (x + (height - 1 - y) * width) * gl_bytes_per_pixel; data_ptrs[morton_to_gl] = morton_data + morton_offset; @@ -81,7 +80,8 @@ static void MortonCopyPixels(CachedSurface::PixelFormat pixel_format, u32 width, // Swap depth and stencil value ordering since 3DS does not match OpenGL u32 depth_stencil; memcpy(&depth_stencil, data_ptrs[1], sizeof(u32)); - depth_stencil = (depth_stencil << depth_stencil_shifts[0]) | (depth_stencil >> depth_stencil_shifts[1]); + depth_stencil = (depth_stencil << depth_stencil_shifts[0]) | + (depth_stencil >> depth_stencil_shifts[1]); memcpy(data_ptrs[0], &depth_stencil, sizeof(u32)); } @@ -90,7 +90,8 @@ static void MortonCopyPixels(CachedSurface::PixelFormat pixel_format, u32 width, for (unsigned y = 0; y < height; ++y) { for (unsigned x = 0; x < width; ++x) { const u32 coarse_y = y & ~7; - u32 morton_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + coarse_y * width * bytes_per_pixel; + u32 morton_offset = VideoCore::GetMortonOffset(x, y, bytes_per_pixel) + + coarse_y * width * bytes_per_pixel; u32 gl_pixel_index = (x + (height - 1 - y) * width) * gl_bytes_per_pixel; data_ptrs[morton_to_gl] = morton_data + morton_offset; @@ -102,17 +103,21 @@ static void MortonCopyPixels(CachedSurface::PixelFormat pixel_format, u32 width, } } -bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, CachedSurface::SurfaceType type, const MathUtil::Rectangle<int>& src_rect, const MathUtil::Rectangle<int>& dst_rect) { +bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, + CachedSurface::SurfaceType type, + const MathUtil::Rectangle<int>& src_rect, + const MathUtil::Rectangle<int>& dst_rect) { using SurfaceType = CachedSurface::SurfaceType; OpenGLState cur_state = OpenGLState::GetCurState(); - // Make sure textures aren't bound to texture units, since going to bind them to framebuffer components + // Make sure textures aren't bound to texture units, since going to bind them to framebuffer + // components OpenGLState::ResetTexture(src_tex); OpenGLState::ResetTexture(dst_tex); // Keep track of previous framebuffer bindings - GLuint old_fbs[2] = { cur_state.draw.read_framebuffer, cur_state.draw.draw_framebuffer }; + GLuint old_fbs[2] = {cur_state.draw.read_framebuffer, cur_state.draw.draw_framebuffer}; cur_state.draw.read_framebuffer = transfer_framebuffers[0].handle; cur_state.draw.draw_framebuffer = transfer_framebuffers[1].handle; cur_state.Apply(); @@ -120,11 +125,15 @@ bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, CachedS u32 buffers = 0; if (type == SurfaceType::Color || type == SurfaceType::Texture) { - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, src_tex, 0); - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, src_tex, + 0); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, + 0); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_tex, 0); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_tex, + 0); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, + 0); buffers = GL_COLOR_BUFFER_BIT; } else if (type == SurfaceType::Depth) { @@ -139,10 +148,12 @@ bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, CachedS buffers = GL_DEPTH_BUFFER_BIT; } else if (type == SurfaceType::DepthStencil) { glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, src_tex, 0); + glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, + src_tex, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, dst_tex, 0); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, + dst_tex, 0); buffers = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; } @@ -155,9 +166,9 @@ bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, CachedS return false; } - glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom, - dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom, - buffers, buffers == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST); + glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom, dst_rect.left, + dst_rect.top, dst_rect.right, dst_rect.bottom, buffers, + buffers == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST); // Restore previous framebuffer bindings cur_state.draw.read_framebuffer = old_fbs[0]; @@ -167,17 +178,24 @@ bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, CachedS return true; } -bool RasterizerCacheOpenGL::TryBlitSurfaces(CachedSurface* src_surface, const MathUtil::Rectangle<int>& src_rect, CachedSurface* dst_surface, const MathUtil::Rectangle<int>& dst_rect) { +bool RasterizerCacheOpenGL::TryBlitSurfaces(CachedSurface* src_surface, + const MathUtil::Rectangle<int>& src_rect, + CachedSurface* dst_surface, + const MathUtil::Rectangle<int>& dst_rect) { using SurfaceType = CachedSurface::SurfaceType; - if (!CachedSurface::CheckFormatsBlittable(src_surface->pixel_format, dst_surface->pixel_format)) { + if (!CachedSurface::CheckFormatsBlittable(src_surface->pixel_format, + dst_surface->pixel_format)) { return false; } - return BlitTextures(src_surface->texture.handle, dst_surface->texture.handle, CachedSurface::GetFormatType(src_surface->pixel_format), src_rect, dst_rect); + return BlitTextures(src_surface->texture.handle, dst_surface->texture.handle, + CachedSurface::GetFormatType(src_surface->pixel_format), src_rect, + dst_rect); } -static void AllocateSurfaceTexture(GLuint texture, CachedSurface::PixelFormat pixel_format, u32 width, u32 height) { +static void AllocateSurfaceTexture(GLuint texture, CachedSurface::PixelFormat pixel_format, + u32 width, u32 height) { // Allocate an uninitialized texture of appropriate size and format for the surface using SurfaceType = CachedSurface::SurfaceType; @@ -200,11 +218,11 @@ static void AllocateSurfaceTexture(GLuint texture, CachedSurface::PixelFormat pi ASSERT(tuple_idx < depth_format_tuples.size()); tuple = depth_format_tuples[tuple_idx]; } else { - tuple = { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE }; + tuple = {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE}; } - glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, width, height, 0, - tuple.format, tuple.type, nullptr); + glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, width, height, 0, tuple.format, + tuple.type, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -217,7 +235,8 @@ static void AllocateSurfaceTexture(GLuint texture, CachedSurface::PixelFormat pi } MICROPROFILE_DEFINE(OpenGL_SurfaceUpload, "OpenGL", "Surface Upload", MP_RGB(128, 64, 192)); -CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bool match_res_scale, bool load_if_create) { +CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bool match_res_scale, + bool load_if_create) { using PixelFormat = CachedSurface::PixelFormat; using SurfaceType = CachedSurface::SurfaceType; @@ -225,29 +244,31 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo return nullptr; } - u32 params_size = params.width * params.height * CachedSurface::GetFormatBpp(params.pixel_format) / 8; + u32 params_size = + params.width * params.height * CachedSurface::GetFormatBpp(params.pixel_format) / 8; // Check for an exact match in existing surfaces CachedSurface* best_exact_surface = nullptr; float exact_surface_goodness = -1.f; - auto surface_interval = boost::icl::interval<PAddr>::right_open(params.addr, params.addr + params_size); + auto surface_interval = + boost::icl::interval<PAddr>::right_open(params.addr, params.addr + params_size); auto range = surface_cache.equal_range(surface_interval); for (auto it = range.first; it != range.second; ++it) { for (auto it2 = it->second.begin(); it2 != it->second.end(); ++it2) { CachedSurface* surface = it2->get(); // Check if the request matches the surface exactly - if (params.addr == surface->addr && - params.width == surface->width && params.height == surface->height && - params.pixel_format == surface->pixel_format) - { + if (params.addr == surface->addr && params.width == surface->width && + params.height == surface->height && params.pixel_format == surface->pixel_format) { // Make sure optional param-matching criteria are fulfilled bool tiling_match = (params.is_tiled == surface->is_tiled); - bool res_scale_match = (params.res_scale_width == surface->res_scale_width && params.res_scale_height == surface->res_scale_height); + bool res_scale_match = (params.res_scale_width == surface->res_scale_width && + params.res_scale_height == surface->res_scale_height); if (!match_res_scale || res_scale_match) { // Prioritize same-tiling and highest resolution surfaces - float match_goodness = (float)tiling_match + surface->res_scale_width * surface->res_scale_height; + float match_goodness = + (float)tiling_match + surface->res_scale_width * surface->res_scale_height; if (match_goodness > exact_surface_goodness || surface->dirty) { exact_surface_goodness = match_goodness; best_exact_surface = surface; @@ -288,9 +309,11 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo if (!load_if_create) { // Don't load any data; just allocate the surface's texture - AllocateSurfaceTexture(new_surface->texture.handle, new_surface->pixel_format, new_surface->GetScaledWidth(), new_surface->GetScaledHeight()); + AllocateSurfaceTexture(new_surface->texture.handle, new_surface->pixel_format, + new_surface->GetScaledWidth(), new_surface->GetScaledHeight()); } else { - // TODO: Consider attempting subrect match in existing surfaces and direct blit here instead of memory upload below if that's a common scenario in some game + // TODO: Consider attempting subrect match in existing surfaces and direct blit here instead + // of memory upload below if that's a common scenario in some game Memory::RasterizerFlushRegion(params.addr, params_size); @@ -318,7 +341,7 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo tuple = fb_format_tuples[(unsigned int)params.pixel_format]; } else { // Texture - tuple = { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE }; + tuple = {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE}; } std::vector<Math::Vec4<u8>> tex_buffer(params.width * params.height); @@ -326,19 +349,23 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo Pica::DebugUtils::TextureInfo tex_info; tex_info.width = params.width; tex_info.height = params.height; - tex_info.stride = params.width * CachedSurface::GetFormatBpp(params.pixel_format) / 8; + tex_info.stride = + params.width * CachedSurface::GetFormatBpp(params.pixel_format) / 8; tex_info.format = (Pica::Regs::TextureFormat)params.pixel_format; tex_info.physical_address = params.addr; for (unsigned y = 0; y < params.height; ++y) { for (unsigned x = 0; x < params.width; ++x) { - tex_buffer[x + params.width * y] = Pica::DebugUtils::LookupTexture(texture_src_data, x, params.height - 1 - y, tex_info); + tex_buffer[x + params.width * y] = Pica::DebugUtils::LookupTexture( + texture_src_data, x, params.height - 1 - y, tex_info); } } - glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, params.width, params.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_buffer.data()); + glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, params.width, params.height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_buffer.data()); } else { - // Depth/Stencil formats need special treatment since they aren't sampleable using LookupTexture and can't use RGBA format + // Depth/Stencil formats need special treatment since they aren't sampleable using + // LookupTexture and can't use RGBA format size_t tuple_idx = (size_t)params.pixel_format - 14; ASSERT(tuple_idx < depth_format_tuples.size()); const FormatTuple& tuple = depth_format_tuples[tuple_idx]; @@ -350,14 +377,18 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo u32 gl_bytes_per_pixel = use_4bpp ? 4 : bytes_per_pixel; - std::vector<u8> temp_fb_depth_buffer(params.width * params.height * gl_bytes_per_pixel); + std::vector<u8> temp_fb_depth_buffer(params.width * params.height * + gl_bytes_per_pixel); - u8* temp_fb_depth_buffer_ptr = use_4bpp ? temp_fb_depth_buffer.data() + 1 : temp_fb_depth_buffer.data(); + u8* temp_fb_depth_buffer_ptr = + use_4bpp ? temp_fb_depth_buffer.data() + 1 : temp_fb_depth_buffer.data(); - MortonCopyPixels(params.pixel_format, params.width, params.height, bytes_per_pixel, gl_bytes_per_pixel, texture_src_data, temp_fb_depth_buffer_ptr, true); + MortonCopyPixels(params.pixel_format, params.width, params.height, bytes_per_pixel, + gl_bytes_per_pixel, texture_src_data, temp_fb_depth_buffer_ptr, + true); - glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, params.width, params.height, 0, - tuple.format, tuple.type, temp_fb_depth_buffer.data()); + glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, params.width, params.height, + 0, tuple.format, tuple.type, temp_fb_depth_buffer.data()); } } glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); @@ -367,10 +398,13 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo OGLTexture scaled_texture; scaled_texture.Create(); - AllocateSurfaceTexture(scaled_texture.handle, new_surface->pixel_format, new_surface->GetScaledWidth(), new_surface->GetScaledHeight()); - BlitTextures(new_surface->texture.handle, scaled_texture.handle, CachedSurface::GetFormatType(new_surface->pixel_format), - MathUtil::Rectangle<int>(0, 0, new_surface->width, new_surface->height), - MathUtil::Rectangle<int>(0, 0, new_surface->GetScaledWidth(), new_surface->GetScaledHeight())); + AllocateSurfaceTexture(scaled_texture.handle, new_surface->pixel_format, + new_surface->GetScaledWidth(), new_surface->GetScaledHeight()); + BlitTextures(new_surface->texture.handle, scaled_texture.handle, + CachedSurface::GetFormatType(new_surface->pixel_format), + MathUtil::Rectangle<int>(0, 0, new_surface->width, new_surface->height), + MathUtil::Rectangle<int>(0, 0, new_surface->GetScaledWidth(), + new_surface->GetScaledHeight())); new_surface->texture.Release(); new_surface->texture.handle = scaled_texture.handle; @@ -389,11 +423,15 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo } Memory::RasterizerMarkRegionCached(new_surface->addr, new_surface->size, 1); - surface_cache.add(std::make_pair(boost::icl::interval<PAddr>::right_open(new_surface->addr, new_surface->addr + new_surface->size), std::set<std::shared_ptr<CachedSurface>>({ new_surface }))); + surface_cache.add(std::make_pair(boost::icl::interval<PAddr>::right_open( + new_surface->addr, new_surface->addr + new_surface->size), + std::set<std::shared_ptr<CachedSurface>>({new_surface}))); return new_surface.get(); } -CachedSurface* RasterizerCacheOpenGL::GetSurfaceRect(const CachedSurface& params, bool match_res_scale, bool load_if_create, MathUtil::Rectangle<int>& out_rect) { +CachedSurface* RasterizerCacheOpenGL::GetSurfaceRect(const CachedSurface& params, + bool match_res_scale, bool load_if_create, + MathUtil::Rectangle<int>& out_rect) { if (params.addr == 0) { return nullptr; } @@ -405,7 +443,8 @@ CachedSurface* RasterizerCacheOpenGL::GetSurfaceRect(const CachedSurface& params CachedSurface* best_subrect_surface = nullptr; float subrect_surface_goodness = -1.f; - auto surface_interval = boost::icl::interval<PAddr>::right_open(params.addr, params.addr + params_size); + auto surface_interval = + boost::icl::interval<PAddr>::right_open(params.addr, params.addr + params_size); auto cache_upper_bound = surface_cache.upper_bound(surface_interval); for (auto it = surface_cache.lower_bound(surface_interval); it != cache_upper_bound; ++it) { for (auto it2 = it->second.begin(); it2 != it->second.end(); ++it2) { @@ -414,14 +453,15 @@ CachedSurface* RasterizerCacheOpenGL::GetSurfaceRect(const CachedSurface& params // Check if the request is contained in the surface if (params.addr >= surface->addr && params.addr + params_size - 1 <= surface->addr + surface->size - 1 && - params.pixel_format == surface->pixel_format) - { + params.pixel_format == surface->pixel_format) { // Make sure optional param-matching criteria are fulfilled bool tiling_match = (params.is_tiled == surface->is_tiled); - bool res_scale_match = (params.res_scale_width == surface->res_scale_width && params.res_scale_height == surface->res_scale_height); + bool res_scale_match = (params.res_scale_width == surface->res_scale_width && + params.res_scale_height == surface->res_scale_height); if (!match_res_scale || res_scale_match) { // Prioritize same-tiling and highest resolution surfaces - float match_goodness = (float)tiling_match + surface->res_scale_width * surface->res_scale_height; + float match_goodness = + (float)tiling_match + surface->res_scale_width * surface->res_scale_height; if (match_goodness > subrect_surface_goodness || surface->dirty) { subrect_surface_goodness = match_goodness; best_subrect_surface = surface; @@ -433,7 +473,8 @@ CachedSurface* RasterizerCacheOpenGL::GetSurfaceRect(const CachedSurface& params // Return the best subrect surface if found if (best_subrect_surface != nullptr) { - unsigned int bytes_per_pixel = (CachedSurface::GetFormatBpp(best_subrect_surface->pixel_format) / 8); + unsigned int bytes_per_pixel = + (CachedSurface::GetFormatBpp(best_subrect_surface->pixel_format) / 8); int x0, y0; @@ -452,7 +493,9 @@ CachedSurface* RasterizerCacheOpenGL::GetSurfaceRect(const CachedSurface& params y0 = begin_tile_index / tiles_per_row * 8; // Tiled surfaces are flipped vertically in the rasterizer vs. 3DS memory. - out_rect = MathUtil::Rectangle<int>(x0, best_subrect_surface->height - y0, x0 + params.width, best_subrect_surface->height - (y0 + params.height)); + out_rect = + MathUtil::Rectangle<int>(x0, best_subrect_surface->height - y0, x0 + params.width, + best_subrect_surface->height - (y0 + params.height)); } out_rect.left = (int)(out_rect.left * best_subrect_surface->res_scale_width); @@ -465,16 +508,20 @@ CachedSurface* RasterizerCacheOpenGL::GetSurfaceRect(const CachedSurface& params // No subrect found - create and return a new surface if (!params.is_tiled) { - out_rect = MathUtil::Rectangle<int>(0, 0, (int)(params.width * params.res_scale_width), (int)(params.height * params.res_scale_height)); + out_rect = MathUtil::Rectangle<int>(0, 0, (int)(params.width * params.res_scale_width), + (int)(params.height * params.res_scale_height)); } else { - out_rect = MathUtil::Rectangle<int>(0, (int)(params.height * params.res_scale_height), (int)(params.width * params.res_scale_width), 0); + out_rect = MathUtil::Rectangle<int>(0, (int)(params.height * params.res_scale_height), + (int)(params.width * params.res_scale_width), 0); } return GetSurface(params, match_res_scale, load_if_create); } -CachedSurface* RasterizerCacheOpenGL::GetTextureSurface(const Pica::Regs::FullTextureConfig& config) { - Pica::DebugUtils::TextureInfo info = Pica::DebugUtils::TextureInfo::FromPicaRegister(config.config, config.format); +CachedSurface* RasterizerCacheOpenGL::GetTextureSurface( + const Pica::Regs::FullTextureConfig& config) { + Pica::DebugUtils::TextureInfo info = + Pica::DebugUtils::TextureInfo::FromPicaRegister(config.config, config.format); CachedSurface params; params.addr = info.physical_address; @@ -485,20 +532,28 @@ CachedSurface* RasterizerCacheOpenGL::GetTextureSurface(const Pica::Regs::FullTe return GetSurface(params, false, true); } -std::tuple<CachedSurface*, CachedSurface*, MathUtil::Rectangle<int>> RasterizerCacheOpenGL::GetFramebufferSurfaces(const Pica::Regs::FramebufferConfig& config) { +std::tuple<CachedSurface*, CachedSurface*, MathUtil::Rectangle<int>> +RasterizerCacheOpenGL::GetFramebufferSurfaces(const Pica::Regs::FramebufferConfig& config) { const auto& regs = Pica::g_state.regs; // Make sur that framebuffers don't overlap if both color and depth are being used u32 fb_area = config.GetWidth() * config.GetHeight(); - bool framebuffers_overlap = config.GetColorBufferPhysicalAddress() != 0 && - config.GetDepthBufferPhysicalAddress() != 0 && - MathUtil::IntervalsIntersect(config.GetColorBufferPhysicalAddress(), fb_area * GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(config.color_format.Value())), - config.GetDepthBufferPhysicalAddress(), fb_area * Pica::Regs::BytesPerDepthPixel(config.depth_format)); + bool framebuffers_overlap = + config.GetColorBufferPhysicalAddress() != 0 && + config.GetDepthBufferPhysicalAddress() != 0 && + MathUtil::IntervalsIntersect( + config.GetColorBufferPhysicalAddress(), + fb_area * GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(config.color_format.Value())), + config.GetDepthBufferPhysicalAddress(), + fb_area * Pica::Regs::BytesPerDepthPixel(config.depth_format)); bool using_color_fb = config.GetColorBufferPhysicalAddress() != 0; - bool using_depth_fb = config.GetDepthBufferPhysicalAddress() != 0 && (regs.output_merger.depth_test_enable || regs.output_merger.depth_write_enable || !framebuffers_overlap); + bool using_depth_fb = config.GetDepthBufferPhysicalAddress() != 0 && + (regs.output_merger.depth_test_enable || + regs.output_merger.depth_write_enable || !framebuffers_overlap); if (framebuffers_overlap && using_color_fb && using_depth_fb) { - LOG_CRITICAL(Render_OpenGL, "Color and depth framebuffer memory regions overlap; overlapping framebuffers not supported!"); + LOG_CRITICAL(Render_OpenGL, "Color and depth framebuffer memory regions overlap; " + "overlapping framebuffers not supported!"); using_depth_fb = false; } @@ -512,8 +567,10 @@ std::tuple<CachedSurface*, CachedSurface*, MathUtil::Rectangle<int>> RasterizerC auto layout = VideoCore::g_emu_window->GetFramebufferLayout(); // Assume same scaling factor for top and bottom screens - color_params.res_scale_width = depth_params.res_scale_width = (float)layout.top_screen.GetWidth() / VideoCore::kScreenTopWidth; - color_params.res_scale_height = depth_params.res_scale_height = (float)layout.top_screen.GetHeight() / VideoCore::kScreenTopHeight; + color_params.res_scale_width = depth_params.res_scale_width = + (float)layout.top_screen.GetWidth() / VideoCore::kScreenTopWidth; + color_params.res_scale_height = depth_params.res_scale_height = + (float)layout.top_screen.GetHeight() / VideoCore::kScreenTopHeight; } color_params.addr = config.GetColorBufferPhysicalAddress(); @@ -523,22 +580,28 @@ std::tuple<CachedSurface*, CachedSurface*, MathUtil::Rectangle<int>> RasterizerC depth_params.pixel_format = CachedSurface::PixelFormatFromDepthFormat(config.depth_format); MathUtil::Rectangle<int> color_rect; - CachedSurface* color_surface = using_color_fb ? GetSurfaceRect(color_params, true, true, color_rect) : nullptr; + CachedSurface* color_surface = + using_color_fb ? GetSurfaceRect(color_params, true, true, color_rect) : nullptr; MathUtil::Rectangle<int> depth_rect; - CachedSurface* depth_surface = using_depth_fb ? GetSurfaceRect(depth_params, true, true, depth_rect) : nullptr; + CachedSurface* depth_surface = + using_depth_fb ? GetSurfaceRect(depth_params, true, true, depth_rect) : nullptr; // Sanity check to make sure found surfaces aren't the same if (using_depth_fb && using_color_fb && color_surface == depth_surface) { - LOG_CRITICAL(Render_OpenGL, "Color and depth framebuffer surfaces overlap; overlapping surfaces not supported!"); + LOG_CRITICAL( + Render_OpenGL, + "Color and depth framebuffer surfaces overlap; overlapping surfaces not supported!"); using_depth_fb = false; depth_surface = nullptr; } MathUtil::Rectangle<int> rect; - if (color_surface != nullptr && depth_surface != nullptr && (depth_rect.left != color_rect.left || depth_rect.top != color_rect.top)) { - // Can't specify separate color and depth viewport offsets in OpenGL, so re-zero both if they don't match + if (color_surface != nullptr && depth_surface != nullptr && + (depth_rect.left != color_rect.left || depth_rect.top != color_rect.top)) { + // Can't specify separate color and depth viewport offsets in OpenGL, so re-zero both if + // they don't match if (color_rect.left != 0 || color_rect.top != 0) { color_surface = GetSurface(color_params, true, true); } @@ -548,9 +611,13 @@ std::tuple<CachedSurface*, CachedSurface*, MathUtil::Rectangle<int>> RasterizerC } if (!color_surface->is_tiled) { - rect = MathUtil::Rectangle<int>(0, 0, (int)(color_params.width * color_params.res_scale_width), (int)(color_params.height * color_params.res_scale_height)); + rect = MathUtil::Rectangle<int>( + 0, 0, (int)(color_params.width * color_params.res_scale_width), + (int)(color_params.height * color_params.res_scale_height)); } else { - rect = MathUtil::Rectangle<int>(0, (int)(color_params.height * color_params.res_scale_height), (int)(color_params.width * color_params.res_scale_width), 0); + rect = MathUtil::Rectangle<int>( + 0, (int)(color_params.height * color_params.res_scale_height), + (int)(color_params.width * color_params.res_scale_width), 0); } } else if (color_surface != nullptr) { rect = color_rect; @@ -564,7 +631,8 @@ std::tuple<CachedSurface*, CachedSurface*, MathUtil::Rectangle<int>> RasterizerC } CachedSurface* RasterizerCacheOpenGL::TryGetFillSurface(const GPU::Regs::MemoryFillConfig& config) { - auto surface_interval = boost::icl::interval<PAddr>::right_open(config.GetStartAddress(), config.GetEndAddress()); + auto surface_interval = + boost::icl::interval<PAddr>::right_open(config.GetStartAddress(), config.GetEndAddress()); auto range = surface_cache.equal_range(surface_interval); for (auto it = range.first; it != range.second; ++it) { for (auto it2 = it->second.begin(); it2 != it->second.end(); ++it2) { @@ -581,8 +649,9 @@ CachedSurface* RasterizerCacheOpenGL::TryGetFillSurface(const GPU::Regs::MemoryF if (surface->addr == config.GetStartAddress() && CachedSurface::GetFormatBpp(surface->pixel_format) == bits_per_value && - (surface->width * surface->height * CachedSurface::GetFormatBpp(surface->pixel_format) / 8) == (config.GetEndAddress() - config.GetStartAddress())) - { + (surface->width * surface->height * + CachedSurface::GetFormatBpp(surface->pixel_format) / 8) == + (config.GetEndAddress() - config.GetStartAddress())) { return surface; } } @@ -617,8 +686,11 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) { if (surface->res_scale_width != 1.f || surface->res_scale_height != 1.f) { unscaled_tex.Create(); - AllocateSurfaceTexture(unscaled_tex.handle, surface->pixel_format, surface->width, surface->height); - BlitTextures(surface->texture.handle, unscaled_tex.handle, CachedSurface::GetFormatType(surface->pixel_format), + AllocateSurfaceTexture(unscaled_tex.handle, surface->pixel_format, surface->width, + surface->height); + BlitTextures( + surface->texture.handle, unscaled_tex.handle, + CachedSurface::GetFormatType(surface->pixel_format), MathUtil::Rectangle<int>(0, 0, surface->GetScaledWidth(), surface->GetScaledHeight()), MathUtil::Rectangle<int>(0, 0, surface->width, surface->height)); @@ -648,10 +720,14 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) { glGetTexImage(GL_TEXTURE_2D, 0, tuple.format, tuple.type, temp_gl_buffer.data()); - // Directly copy pixels. Internal OpenGL color formats are consistent so no conversion is necessary. - MortonCopyPixels(surface->pixel_format, surface->width, surface->height, bytes_per_pixel, bytes_per_pixel, dst_buffer, temp_gl_buffer.data(), false); + // Directly copy pixels. Internal OpenGL color formats are consistent so no conversion + // is necessary. + MortonCopyPixels(surface->pixel_format, surface->width, surface->height, + bytes_per_pixel, bytes_per_pixel, dst_buffer, temp_gl_buffer.data(), + false); } else { - // Depth/Stencil formats need special treatment since they aren't sampleable using LookupTexture and can't use RGBA format + // Depth/Stencil formats need special treatment since they aren't sampleable using + // LookupTexture and can't use RGBA format size_t tuple_idx = (size_t)surface->pixel_format - 14; ASSERT(tuple_idx < depth_format_tuples.size()); const FormatTuple& tuple = depth_format_tuples[tuple_idx]; @@ -669,7 +745,9 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) { u8* temp_gl_buffer_ptr = use_4bpp ? temp_gl_buffer.data() + 1 : temp_gl_buffer.data(); - MortonCopyPixels(surface->pixel_format, surface->width, surface->height, bytes_per_pixel, gl_bytes_per_pixel, dst_buffer, temp_gl_buffer_ptr, false); + MortonCopyPixels(surface->pixel_format, surface->width, surface->height, + bytes_per_pixel, gl_bytes_per_pixel, dst_buffer, temp_gl_buffer_ptr, + false); } } glPixelStorei(GL_PACK_ROW_LENGTH, 0); @@ -680,7 +758,8 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) { cur_state.Apply(); } -void RasterizerCacheOpenGL::FlushRegion(PAddr addr, u32 size, const CachedSurface* skip_surface, bool invalidate) { +void RasterizerCacheOpenGL::FlushRegion(PAddr addr, u32 size, const CachedSurface* skip_surface, + bool invalidate) { if (size == 0) { return; } @@ -691,8 +770,11 @@ void RasterizerCacheOpenGL::FlushRegion(PAddr addr, u32 size, const CachedSurfac auto surface_interval = boost::icl::interval<PAddr>::right_open(addr, addr + size); auto cache_upper_bound = surface_cache.upper_bound(surface_interval); for (auto it = surface_cache.lower_bound(surface_interval); it != cache_upper_bound; ++it) { - std::copy_if(it->second.begin(), it->second.end(), std::inserter(touching_surfaces, touching_surfaces.end()), - [skip_surface](std::shared_ptr<CachedSurface> surface) { return (surface.get() != skip_surface); }); + std::copy_if(it->second.begin(), it->second.end(), + std::inserter(touching_surfaces, touching_surfaces.end()), + [skip_surface](std::shared_ptr<CachedSurface> surface) { + return (surface.get() != skip_surface); + }); } // Flush and invalidate surfaces @@ -700,7 +782,10 @@ void RasterizerCacheOpenGL::FlushRegion(PAddr addr, u32 size, const CachedSurfac FlushSurface(surface.get()); if (invalidate) { Memory::RasterizerMarkRegionCached(surface->addr, surface->size, -1); - surface_cache.subtract(std::make_pair(boost::icl::interval<PAddr>::right_open(surface->addr, surface->addr + surface->size), std::set<std::shared_ptr<CachedSurface>>({ surface }))); + surface_cache.subtract( + std::make_pair(boost::icl::interval<PAddr>::right_open( + surface->addr, surface->addr + surface->size), + std::set<std::shared_ptr<CachedSurface>>({surface}))); } } } diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 225596415..849530d86 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -8,21 +8,18 @@ #include <memory> #include <set> #include <tuple> - #include <boost/icl/interval_map.hpp> #include <glad/glad.h> - #include "common/assert.h" #include "common/common_funcs.h" #include "common/common_types.h" - #include "core/hw/gpu.h" - #include "video_core/pica.h" #include "video_core/renderer_opengl/gl_resource_manager.h" namespace MathUtil { -template <class T> struct Rectangle; +template <class T> +struct Rectangle; } struct CachedSurface; @@ -32,38 +29,38 @@ using SurfaceCache = boost::icl::interval_map<PAddr, std::set<std::shared_ptr<Ca struct CachedSurface { enum class PixelFormat { // First 5 formats are shared between textures and color buffers - RGBA8 = 0, - RGB8 = 1, - RGB5A1 = 2, - RGB565 = 3, - RGBA4 = 4, + RGBA8 = 0, + RGB8 = 1, + RGB5A1 = 2, + RGB565 = 3, + RGBA4 = 4, // Texture-only formats - IA8 = 5, - RG8 = 6, - I8 = 7, - A8 = 8, - IA4 = 9, - I4 = 10, - A4 = 11, - ETC1 = 12, - ETC1A4 = 13, + IA8 = 5, + RG8 = 6, + I8 = 7, + A8 = 8, + IA4 = 9, + I4 = 10, + A4 = 11, + ETC1 = 12, + ETC1A4 = 13, // Depth buffer-only formats - D16 = 14, + D16 = 14, // gap - D24 = 16, - D24S8 = 17, + D24 = 16, + D24S8 = 17, - Invalid = 255, + Invalid = 255, }; enum class SurfaceType { - Color = 0, - Texture = 1, - Depth = 2, + Color = 0, + Texture = 1, + Depth = 2, DepthStencil = 3, - Invalid = 4, + Invalid = 4, }; static unsigned int GetFormatBpp(CachedSurface::PixelFormat format) { @@ -101,7 +98,8 @@ struct CachedSurface { } static PixelFormat PixelFormatFromDepthFormat(Pica::Regs::DepthFormat format) { - return ((unsigned int)format < 4) ? (PixelFormat)((unsigned int)format + 14) : PixelFormat::Invalid; + return ((unsigned int)format < 4) ? (PixelFormat)((unsigned int)format + 14) + : PixelFormat::Invalid; } static PixelFormat PixelFormatFromGPUPixelFormat(GPU::Regs::PixelFormat format) { @@ -120,7 +118,8 @@ struct CachedSurface { SurfaceType a_type = GetFormatType(pixel_format_a); SurfaceType b_type = GetFormatType(pixel_format_b); - if ((a_type == SurfaceType::Color || a_type == SurfaceType::Texture) && (b_type == SurfaceType::Color || b_type == SurfaceType::Texture)) { + if ((a_type == SurfaceType::Color || a_type == SurfaceType::Texture) && + (b_type == SurfaceType::Color || b_type == SurfaceType::Texture)) { return true; } @@ -187,22 +186,30 @@ public: ~RasterizerCacheOpenGL(); /// Blits one texture to another - bool BlitTextures(GLuint src_tex, GLuint dst_tex, CachedSurface::SurfaceType type, const MathUtil::Rectangle<int>& src_rect, const MathUtil::Rectangle<int>& dst_rect); + bool BlitTextures(GLuint src_tex, GLuint dst_tex, CachedSurface::SurfaceType type, + const MathUtil::Rectangle<int>& src_rect, + const MathUtil::Rectangle<int>& dst_rect); /// Attempt to blit one surface's texture to another - bool TryBlitSurfaces(CachedSurface* src_surface, const MathUtil::Rectangle<int>& src_rect, CachedSurface* dst_surface, const MathUtil::Rectangle<int>& dst_rect); + bool TryBlitSurfaces(CachedSurface* src_surface, const MathUtil::Rectangle<int>& src_rect, + CachedSurface* dst_surface, const MathUtil::Rectangle<int>& dst_rect); /// Loads a texture from 3DS memory to OpenGL and caches it (if not already cached) - CachedSurface* GetSurface(const CachedSurface& params, bool match_res_scale, bool load_if_create); + CachedSurface* GetSurface(const CachedSurface& params, bool match_res_scale, + bool load_if_create); - /// Attempt to find a subrect (resolution scaled) of a surface, otherwise loads a texture from 3DS memory to OpenGL and caches it (if not already cached) - CachedSurface* GetSurfaceRect(const CachedSurface& params, bool match_res_scale, bool load_if_create, MathUtil::Rectangle<int>& out_rect); + /// Attempt to find a subrect (resolution scaled) of a surface, otherwise loads a texture from + /// 3DS memory to OpenGL and caches it (if not already cached) + CachedSurface* GetSurfaceRect(const CachedSurface& params, bool match_res_scale, + bool load_if_create, MathUtil::Rectangle<int>& out_rect); /// Gets a surface based on the texture configuration CachedSurface* GetTextureSurface(const Pica::Regs::FullTextureConfig& config); - /// Gets the color and depth surfaces and rect (resolution scaled) based on the framebuffer configuration - std::tuple<CachedSurface*, CachedSurface*, MathUtil::Rectangle<int>> GetFramebufferSurfaces(const Pica::Regs::FramebufferConfig& config); + /// Gets the color and depth surfaces and rect (resolution scaled) based on the framebuffer + /// configuration + std::tuple<CachedSurface*, CachedSurface*, MathUtil::Rectangle<int>> GetFramebufferSurfaces( + const Pica::Regs::FramebufferConfig& config); /// Attempt to get a surface that exactly matches the fill region and format CachedSurface* TryGetFillSurface(const GPU::Regs::MemoryFillConfig& config); @@ -210,7 +217,8 @@ public: /// Write the surface back to memory void FlushSurface(CachedSurface* surface); - /// Write any cached resources overlapping the region back to memory (if dirty) and optionally invalidate them in the cache + /// Write any cached resources overlapping the region back to memory (if dirty) and optionally + /// invalidate them in the cache void FlushRegion(PAddr addr, u32 size, const CachedSurface* skip_surface, bool invalidate); /// Flush all cached resources tracked by this cache manager diff --git a/src/video_core/renderer_opengl/gl_resource_manager.h b/src/video_core/renderer_opengl/gl_resource_manager.h index eb128966c..13301ec9f 100644 --- a/src/video_core/renderer_opengl/gl_resource_manager.h +++ b/src/video_core/renderer_opengl/gl_resource_manager.h @@ -5,30 +5,36 @@ #pragma once #include <utility> - #include <glad/glad.h> - #include "common/common_types.h" - #include "video_core/renderer_opengl/gl_shader_util.h" #include "video_core/renderer_opengl/gl_state.h" class OGLTexture : private NonCopyable { public: OGLTexture() = default; - OGLTexture(OGLTexture&& o) { std::swap(handle, o.handle); } - ~OGLTexture() { Release(); } - OGLTexture& operator=(OGLTexture&& o) { std::swap(handle, o.handle); return *this; } + OGLTexture(OGLTexture&& o) { + std::swap(handle, o.handle); + } + ~OGLTexture() { + Release(); + } + OGLTexture& operator=(OGLTexture&& o) { + std::swap(handle, o.handle); + return *this; + } /// Creates a new internal OpenGL resource and stores the handle void Create() { - if (handle != 0) return; + if (handle != 0) + return; glGenTextures(1, &handle); } /// Deletes the internal OpenGL resource void Release() { - if (handle == 0) return; + if (handle == 0) + return; glDeleteTextures(1, &handle); OpenGLState::ResetTexture(handle); handle = 0; @@ -40,19 +46,28 @@ public: class OGLSampler : private NonCopyable { public: OGLSampler() = default; - OGLSampler(OGLSampler&& o) { std::swap(handle, o.handle); } - ~OGLSampler() { Release(); } - OGLSampler& operator=(OGLSampler&& o) { std::swap(handle, o.handle); return *this; } + OGLSampler(OGLSampler&& o) { + std::swap(handle, o.handle); + } + ~OGLSampler() { + Release(); + } + OGLSampler& operator=(OGLSampler&& o) { + std::swap(handle, o.handle); + return *this; + } /// Creates a new internal OpenGL resource and stores the handle void Create() { - if (handle != 0) return; + if (handle != 0) + return; glGenSamplers(1, &handle); } /// Deletes the internal OpenGL resource void Release() { - if (handle == 0) return; + if (handle == 0) + return; glDeleteSamplers(1, &handle); OpenGLState::ResetSampler(handle); handle = 0; @@ -64,19 +79,28 @@ public: class OGLShader : private NonCopyable { public: OGLShader() = default; - OGLShader(OGLShader&& o) { std::swap(handle, o.handle); } - ~OGLShader() { Release(); } - OGLShader& operator=(OGLShader&& o) { std::swap(handle, o.handle); return *this; } + OGLShader(OGLShader&& o) { + std::swap(handle, o.handle); + } + ~OGLShader() { + Release(); + } + OGLShader& operator=(OGLShader&& o) { + std::swap(handle, o.handle); + return *this; + } /// Creates a new internal OpenGL resource and stores the handle void Create(const char* vert_shader, const char* frag_shader) { - if (handle != 0) return; + if (handle != 0) + return; handle = GLShader::LoadProgram(vert_shader, frag_shader); } /// Deletes the internal OpenGL resource void Release() { - if (handle == 0) return; + if (handle == 0) + return; glDeleteProgram(handle); OpenGLState::ResetProgram(handle); handle = 0; @@ -88,19 +112,28 @@ public: class OGLBuffer : private NonCopyable { public: OGLBuffer() = default; - OGLBuffer(OGLBuffer&& o) { std::swap(handle, o.handle); } - ~OGLBuffer() { Release(); } - OGLBuffer& operator=(OGLBuffer&& o) { std::swap(handle, o.handle); return *this; } + OGLBuffer(OGLBuffer&& o) { + std::swap(handle, o.handle); + } + ~OGLBuffer() { + Release(); + } + OGLBuffer& operator=(OGLBuffer&& o) { + std::swap(handle, o.handle); + return *this; + } /// Creates a new internal OpenGL resource and stores the handle void Create() { - if (handle != 0) return; + if (handle != 0) + return; glGenBuffers(1, &handle); } /// Deletes the internal OpenGL resource void Release() { - if (handle == 0) return; + if (handle == 0) + return; glDeleteBuffers(1, &handle); OpenGLState::ResetBuffer(handle); handle = 0; @@ -112,19 +145,28 @@ public: class OGLVertexArray : private NonCopyable { public: OGLVertexArray() = default; - OGLVertexArray(OGLVertexArray&& o) { std::swap(handle, o.handle); } - ~OGLVertexArray() { Release(); } - OGLVertexArray& operator=(OGLVertexArray&& o) { std::swap(handle, o.handle); return *this; } + OGLVertexArray(OGLVertexArray&& o) { + std::swap(handle, o.handle); + } + ~OGLVertexArray() { + Release(); + } + OGLVertexArray& operator=(OGLVertexArray&& o) { + std::swap(handle, o.handle); + return *this; + } /// Creates a new internal OpenGL resource and stores the handle void Create() { - if (handle != 0) return; + if (handle != 0) + return; glGenVertexArrays(1, &handle); } /// Deletes the internal OpenGL resource void Release() { - if (handle == 0) return; + if (handle == 0) + return; glDeleteVertexArrays(1, &handle); OpenGLState::ResetVertexArray(handle); handle = 0; @@ -136,19 +178,28 @@ public: class OGLFramebuffer : private NonCopyable { public: OGLFramebuffer() = default; - OGLFramebuffer(OGLFramebuffer&& o) { std::swap(handle, o.handle); } - ~OGLFramebuffer() { Release(); } - OGLFramebuffer& operator=(OGLFramebuffer&& o) { std::swap(handle, o.handle); return *this; } + OGLFramebuffer(OGLFramebuffer&& o) { + std::swap(handle, o.handle); + } + ~OGLFramebuffer() { + Release(); + } + OGLFramebuffer& operator=(OGLFramebuffer&& o) { + std::swap(handle, o.handle); + return *this; + } /// Creates a new internal OpenGL resource and stores the handle void Create() { - if (handle != 0) return; + if (handle != 0) + return; glGenFramebuffers(1, &handle); } /// Deletes the internal OpenGL resource void Release() { - if (handle == 0) return; + if (handle == 0) + return; glDeleteFramebuffers(1, &handle); OpenGLState::ResetFramebuffer(handle); handle = 0; diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 3de372f67..1808ee0a9 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -4,11 +4,9 @@ #include <array> #include <cstddef> - #include "common/assert.h" #include "common/bit_field.h" #include "common/logging/log.h" - #include "video_core/pica.h" #include "video_core/renderer_opengl/gl_rasterizer.h" #include "video_core/renderer_opengl/gl_shader_gen.h" @@ -21,19 +19,18 @@ namespace GLShader { /// Detects if a TEV stage is configured to be skipped (to avoid generating unnecessary code) static bool IsPassThroughTevStage(const TevStageConfig& stage) { - return (stage.color_op == TevStageConfig::Operation::Replace && - stage.alpha_op == TevStageConfig::Operation::Replace && - stage.color_source1 == TevStageConfig::Source::Previous && - stage.alpha_source1 == TevStageConfig::Source::Previous && - stage.color_modifier1 == TevStageConfig::ColorModifier::SourceColor && - stage.alpha_modifier1 == TevStageConfig::AlphaModifier::SourceAlpha && - stage.GetColorMultiplier() == 1 && - stage.GetAlphaMultiplier() == 1); + return (stage.color_op == TevStageConfig::Operation::Replace && + stage.alpha_op == TevStageConfig::Operation::Replace && + stage.color_source1 == TevStageConfig::Source::Previous && + stage.alpha_source1 == TevStageConfig::Source::Previous && + stage.color_modifier1 == TevStageConfig::ColorModifier::SourceColor && + stage.alpha_modifier1 == TevStageConfig::AlphaModifier::SourceAlpha && + stage.GetColorMultiplier() == 1 && stage.GetAlphaMultiplier() == 1); } /// Writes the specified TEV stage source component(s) -static void AppendSource(std::string& out, const PicaShaderConfig& config, TevStageConfig::Source source, - const std::string& index_name) { +static void AppendSource(std::string& out, const PicaShaderConfig& config, + TevStageConfig::Source source, const std::string& index_name) { const auto& state = config.state; using Source = TevStageConfig::Source; switch (source) { @@ -48,7 +45,7 @@ static void AppendSource(std::string& out, const PicaShaderConfig& config, TevSt break; case Source::Texture0: // Only unit 0 respects the texturing type (according to 3DBrew) - switch(state.texture0_type) { + switch (state.texture0_type) { case Pica::Regs::TextureConfig::Texture2D: out += "texture(tex[0], texcoord[0])"; break; @@ -57,7 +54,8 @@ static void AppendSource(std::string& out, const PicaShaderConfig& config, TevSt break; default: out += "texture(tex[0], texcoord[0])"; - LOG_CRITICAL(HW_GPU, "Unhandled texture type %x", static_cast<int>(state.texture0_type)); + LOG_CRITICAL(HW_GPU, "Unhandled texture type %x", + static_cast<int>(state.texture0_type)); UNIMPLEMENTED(); break; } @@ -85,8 +83,9 @@ static void AppendSource(std::string& out, const PicaShaderConfig& config, TevSt } /// Writes the color components to use for the specified TEV stage color modifier -static void AppendColorModifier(std::string& out, const PicaShaderConfig& config, TevStageConfig::ColorModifier modifier, - TevStageConfig::Source source, const std::string& index_name) { +static void AppendColorModifier(std::string& out, const PicaShaderConfig& config, + TevStageConfig::ColorModifier modifier, + TevStageConfig::Source source, const std::string& index_name) { using ColorModifier = TevStageConfig::ColorModifier; switch (modifier) { case ColorModifier::SourceColor: @@ -142,8 +141,9 @@ static void AppendColorModifier(std::string& out, const PicaShaderConfig& config } /// Writes the alpha component to use for the specified TEV stage alpha modifier -static void AppendAlphaModifier(std::string& out, const PicaShaderConfig& config, TevStageConfig::AlphaModifier modifier, - TevStageConfig::Source source, const std::string& index_name) { +static void AppendAlphaModifier(std::string& out, const PicaShaderConfig& config, + TevStageConfig::AlphaModifier modifier, + TevStageConfig::Source source, const std::string& index_name) { using AlphaModifier = TevStageConfig::AlphaModifier; switch (modifier) { case AlphaModifier::SourceAlpha: @@ -191,7 +191,7 @@ static void AppendAlphaModifier(std::string& out, const PicaShaderConfig& config /// Writes the combiner function for the color components for the specified TEV stage operation static void AppendColorCombiner(std::string& out, TevStageConfig::Operation operation, - const std::string& variable_name) { + const std::string& variable_name) { out += "clamp("; using Operation = TevStageConfig::Operation; switch (operation) { @@ -208,8 +208,10 @@ static void AppendColorCombiner(std::string& out, TevStageConfig::Operation oper out += variable_name + "[0] + " + variable_name + "[1] - vec3(0.5)"; break; case Operation::Lerp: - // TODO(bunnei): Verify if HW actually does this per-component, otherwise we can just use builtin lerp - out += variable_name + "[0] * " + variable_name + "[2] + " + variable_name + "[1] * (vec3(1.0) - " + variable_name + "[2])"; + // TODO(bunnei): Verify if HW actually does this per-component, otherwise we can just use + // builtin lerp + out += variable_name + "[0] * " + variable_name + "[2] + " + variable_name + + "[1] * (vec3(1.0) - " + variable_name + "[2])"; break; case Operation::Subtract: out += variable_name + "[0] - " + variable_name + "[1]"; @@ -218,10 +220,12 @@ static void AppendColorCombiner(std::string& out, TevStageConfig::Operation oper out += variable_name + "[0] * " + variable_name + "[1] + " + variable_name + "[2]"; break; case Operation::AddThenMultiply: - out += "min(" + variable_name + "[0] + " + variable_name + "[1], vec3(1.0)) * " + variable_name + "[2]"; + out += "min(" + variable_name + "[0] + " + variable_name + "[1], vec3(1.0)) * " + + variable_name + "[2]"; break; case Operation::Dot3_RGB: - out += "vec3(dot(" + variable_name + "[0] - vec3(0.5), " + variable_name + "[1] - vec3(0.5)) * 4.0)"; + out += "vec3(dot(" + variable_name + "[0] - vec3(0.5), " + variable_name + + "[1] - vec3(0.5)) * 4.0)"; break; default: out += "vec3(0.0)"; @@ -233,7 +237,7 @@ static void AppendColorCombiner(std::string& out, TevStageConfig::Operation oper /// Writes the combiner function for the alpha component for the specified TEV stage operation static void AppendAlphaCombiner(std::string& out, TevStageConfig::Operation operation, - const std::string& variable_name) { + const std::string& variable_name) { out += "clamp("; using Operation = TevStageConfig::Operation; switch (operation) { @@ -250,7 +254,8 @@ static void AppendAlphaCombiner(std::string& out, TevStageConfig::Operation oper out += variable_name + "[0] + " + variable_name + "[1] - 0.5"; break; case Operation::Lerp: - out += variable_name + "[0] * " + variable_name + "[2] + " + variable_name + "[1] * (1.0 - " + variable_name + "[2])"; + out += variable_name + "[0] * " + variable_name + "[2] + " + variable_name + + "[1] * (1.0 - " + variable_name + "[2])"; break; case Operation::Subtract: out += variable_name + "[0] - " + variable_name + "[1]"; @@ -259,7 +264,8 @@ static void AppendAlphaCombiner(std::string& out, TevStageConfig::Operation oper out += variable_name + "[0] * " + variable_name + "[1] + " + variable_name + "[2]"; break; case Operation::AddThenMultiply: - out += "min(" + variable_name + "[0] + " + variable_name + "[1], 1.0) * " + variable_name + "[2]"; + out += "min(" + variable_name + "[0] + " + variable_name + "[1], 1.0) * " + variable_name + + "[2]"; break; default: out += "0.0"; @@ -284,9 +290,8 @@ static void AppendAlphaTestCondition(std::string& out, Regs::CompareFunc func) { case CompareFunc::LessThan: case CompareFunc::LessThanOrEqual: case CompareFunc::GreaterThan: - case CompareFunc::GreaterThanOrEqual: - { - static const char* op[] = { "!=", "==", ">=", ">", "<=", "<", }; + case CompareFunc::GreaterThanOrEqual: { + static const char* op[] = {"!=", "==", ">=", ">", "<=", "<"}; unsigned index = (unsigned)func - (unsigned)CompareFunc::Equal; out += "int(last_tex_env_out.a * 255.0f) " + std::string(op[index]) + " alphatest_ref"; break; @@ -301,7 +306,8 @@ static void AppendAlphaTestCondition(std::string& out, Regs::CompareFunc func) { /// Writes the code to emulate the specified TEV stage static void WriteTevStage(std::string& out, const PicaShaderConfig& config, unsigned index) { - const auto stage = static_cast<const Pica::Regs::TevStageConfig>(config.state.tev_stages[index]); + const auto stage = + static_cast<const Pica::Regs::TevStageConfig>(config.state.tev_stages[index]); if (!IsPassThroughTevStage(stage)) { std::string index_name = std::to_string(index); @@ -330,8 +336,12 @@ static void WriteTevStage(std::string& out, const PicaShaderConfig& config, unsi out += ";\n"; out += "last_tex_env_out = vec4(" - "clamp(color_output_" + index_name + " * " + std::to_string(stage.GetColorMultiplier()) + ".0, vec3(0.0), vec3(1.0))," - "clamp(alpha_output_" + index_name + " * " + std::to_string(stage.GetAlphaMultiplier()) + ".0, 0.0, 1.0));\n"; + "clamp(color_output_" + + index_name + " * " + std::to_string(stage.GetColorMultiplier()) + + ".0, vec3(0.0), vec3(1.0))," + "clamp(alpha_output_" + + index_name + " * " + std::to_string(stage.GetAlphaMultiplier()) + + ".0, 0.0, 1.0));\n"; } out += "combiner_buffer = next_combiner_buffer;\n"; @@ -355,13 +365,17 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { // Compute fragment normals if (lighting.bump_mode == Pica::Regs::LightingBumpMode::NormalMap) { - // Bump mapping is enabled using a normal map, read perturbation vector from the selected texture + // Bump mapping is enabled using a normal map, read perturbation vector from the selected + // texture std::string bump_selector = std::to_string(lighting.bump_selector); - out += "vec3 surface_normal = 2.0 * texture(tex[" + bump_selector + "], texcoord[" + bump_selector + "]).rgb - 1.0;\n"; + out += "vec3 surface_normal = 2.0 * texture(tex[" + bump_selector + "], texcoord[" + + bump_selector + "]).rgb - 1.0;\n"; - // Recompute Z-component of perturbation if 'renorm' is enabled, this provides a higher precision result + // Recompute Z-component of perturbation if 'renorm' is enabled, this provides a higher + // precision result if (lighting.bump_renorm) { - std::string val = "(1.0 - (surface_normal.x*surface_normal.x + surface_normal.y*surface_normal.y))"; + std::string val = + "(1.0 - (surface_normal.x*surface_normal.x + surface_normal.y*surface_normal.y))"; out += "surface_normal.z = sqrt(max(" + val + ", 0.0));\n"; } } else if (lighting.bump_mode == Pica::Regs::LightingBumpMode::TangentMap) { @@ -373,7 +387,8 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { out += "vec3 surface_normal = vec3(0.0, 0.0, 1.0);\n"; } - // Rotate the surface-local normal by the interpolated normal quaternion to convert it to eyespace + // Rotate the surface-local normal by the interpolated normal quaternion to convert it to + // eyespace out += "vec3 normal = normalize(quaternion_rotate(normquat, surface_normal));\n"; // Gets the index into the specified lookup table for specular lighting @@ -406,12 +421,14 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { if (abs) { // LUT index is in the range of (0.0, 1.0) - index = lighting.light[light_num].two_sided_diffuse ? "abs(" + index + ")" : "max(" + index + ", 0.f)"; + index = lighting.light[light_num].two_sided_diffuse ? "abs(" + index + ")" + : "max(" + index + ", 0.f)"; return "(FLOAT_255 * clamp(" + index + ", 0.0, 1.0))"; } else { // LUT index is in the range of (-1.0, 1.0) index = "clamp(" + index + ", -1.0, 1.0)"; - return "(FLOAT_255 * ((" + index + " < 0) ? " + index + " + 2.0 : " + index + ") / 2.0)"; + return "(FLOAT_255 * ((" + index + " < 0) ? " + index + " + 2.0 : " + index + + ") / 2.0)"; } return std::string(); @@ -434,52 +451,74 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { else out += "light_vector = normalize(" + light_src + ".position + view);\n"; - // Compute dot product of light_vector and normal, adjust if lighting is one-sided or two-sided - std::string dot_product = light_config.two_sided_diffuse ? "abs(dot(light_vector, normal))" : "max(dot(light_vector, normal), 0.0)"; + // Compute dot product of light_vector and normal, adjust if lighting is one-sided or + // two-sided + std::string dot_product = light_config.two_sided_diffuse + ? "abs(dot(light_vector, normal))" + : "max(dot(light_vector, normal), 0.0)"; // If enabled, compute distance attenuation value std::string dist_atten = "1.0"; if (light_config.dist_atten_enable) { - std::string index = "(" + light_src + ".dist_atten_scale * length(-view - " + light_src + ".position) + " + light_src + ".dist_atten_bias)"; + std::string index = "(" + light_src + ".dist_atten_scale * length(-view - " + + light_src + ".position) + " + light_src + ".dist_atten_bias)"; index = "((clamp(" + index + ", 0.0, FLOAT_255)))"; - const unsigned lut_num = ((unsigned)Regs::LightingSampler::DistanceAttenuation + light_config.num); + const unsigned lut_num = + ((unsigned)Regs::LightingSampler::DistanceAttenuation + light_config.num); dist_atten = GetLutValue((Regs::LightingSampler)lut_num, index); } // If enabled, clamp specular component if lighting result is negative - std::string clamp_highlights = lighting.clamp_highlights ? "(dot(light_vector, normal) <= 0.0 ? 0.0 : 1.0)" : "1.0"; + std::string clamp_highlights = + lighting.clamp_highlights ? "(dot(light_vector, normal) <= 0.0 ? 0.0 : 1.0)" : "1.0"; // Specular 0 component std::string d0_lut_value = "1.0"; - if (lighting.lut_d0.enable && Pica::Regs::IsLightingSamplerSupported(lighting.config, Pica::Regs::LightingSampler::Distribution0)) { + if (lighting.lut_d0.enable && + Pica::Regs::IsLightingSamplerSupported(lighting.config, + Pica::Regs::LightingSampler::Distribution0)) { // Lookup specular "distribution 0" LUT value - std::string index = GetLutIndex(light_config.num, lighting.lut_d0.type, lighting.lut_d0.abs_input); - d0_lut_value = "(" + std::to_string(lighting.lut_d0.scale) + " * " + GetLutValue(Regs::LightingSampler::Distribution0, index) + ")"; + std::string index = + GetLutIndex(light_config.num, lighting.lut_d0.type, lighting.lut_d0.abs_input); + d0_lut_value = "(" + std::to_string(lighting.lut_d0.scale) + " * " + + GetLutValue(Regs::LightingSampler::Distribution0, index) + ")"; } std::string specular_0 = "(" + d0_lut_value + " * " + light_src + ".specular_0)"; // If enabled, lookup ReflectRed value, otherwise, 1.0 is used - if (lighting.lut_rr.enable && Pica::Regs::IsLightingSamplerSupported(lighting.config, Pica::Regs::LightingSampler::ReflectRed)) { - std::string index = GetLutIndex(light_config.num, lighting.lut_rr.type, lighting.lut_rr.abs_input); - std::string value = "(" + std::to_string(lighting.lut_rr.scale) + " * " + GetLutValue(Regs::LightingSampler::ReflectRed, index) + ")"; + if (lighting.lut_rr.enable && + Pica::Regs::IsLightingSamplerSupported(lighting.config, + Pica::Regs::LightingSampler::ReflectRed)) { + std::string index = + GetLutIndex(light_config.num, lighting.lut_rr.type, lighting.lut_rr.abs_input); + std::string value = "(" + std::to_string(lighting.lut_rr.scale) + " * " + + GetLutValue(Regs::LightingSampler::ReflectRed, index) + ")"; out += "refl_value.r = " + value + ";\n"; } else { out += "refl_value.r = 1.0;\n"; } // If enabled, lookup ReflectGreen value, otherwise, ReflectRed value is used - if (lighting.lut_rg.enable && Pica::Regs::IsLightingSamplerSupported(lighting.config, Pica::Regs::LightingSampler::ReflectGreen)) { - std::string index = GetLutIndex(light_config.num, lighting.lut_rg.type, lighting.lut_rg.abs_input); - std::string value = "(" + std::to_string(lighting.lut_rg.scale) + " * " + GetLutValue(Regs::LightingSampler::ReflectGreen, index) + ")"; + if (lighting.lut_rg.enable && + Pica::Regs::IsLightingSamplerSupported(lighting.config, + Pica::Regs::LightingSampler::ReflectGreen)) { + std::string index = + GetLutIndex(light_config.num, lighting.lut_rg.type, lighting.lut_rg.abs_input); + std::string value = "(" + std::to_string(lighting.lut_rg.scale) + " * " + + GetLutValue(Regs::LightingSampler::ReflectGreen, index) + ")"; out += "refl_value.g = " + value + ";\n"; } else { out += "refl_value.g = refl_value.r;\n"; } // If enabled, lookup ReflectBlue value, otherwise, ReflectRed value is used - if (lighting.lut_rb.enable && Pica::Regs::IsLightingSamplerSupported(lighting.config, Pica::Regs::LightingSampler::ReflectBlue)) { - std::string index = GetLutIndex(light_config.num, lighting.lut_rb.type, lighting.lut_rb.abs_input); - std::string value = "(" + std::to_string(lighting.lut_rb.scale) + " * " + GetLutValue(Regs::LightingSampler::ReflectBlue, index) + ")"; + if (lighting.lut_rb.enable && + Pica::Regs::IsLightingSamplerSupported(lighting.config, + Pica::Regs::LightingSampler::ReflectBlue)) { + std::string index = + GetLutIndex(light_config.num, lighting.lut_rb.type, lighting.lut_rb.abs_input); + std::string value = "(" + std::to_string(lighting.lut_rb.scale) + " * " + + GetLutValue(Regs::LightingSampler::ReflectBlue, index) + ")"; out += "refl_value.b = " + value + ";\n"; } else { out += "refl_value.b = refl_value.r;\n"; @@ -487,18 +526,26 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { // Specular 1 component std::string d1_lut_value = "1.0"; - if (lighting.lut_d1.enable && Pica::Regs::IsLightingSamplerSupported(lighting.config, Pica::Regs::LightingSampler::Distribution1)) { + if (lighting.lut_d1.enable && + Pica::Regs::IsLightingSamplerSupported(lighting.config, + Pica::Regs::LightingSampler::Distribution1)) { // Lookup specular "distribution 1" LUT value - std::string index = GetLutIndex(light_config.num, lighting.lut_d1.type, lighting.lut_d1.abs_input); - d1_lut_value = "(" + std::to_string(lighting.lut_d1.scale) + " * " + GetLutValue(Regs::LightingSampler::Distribution1, index) + ")"; + std::string index = + GetLutIndex(light_config.num, lighting.lut_d1.type, lighting.lut_d1.abs_input); + d1_lut_value = "(" + std::to_string(lighting.lut_d1.scale) + " * " + + GetLutValue(Regs::LightingSampler::Distribution1, index) + ")"; } - std::string specular_1 = "(" + d1_lut_value + " * refl_value * " + light_src + ".specular_1)"; + std::string specular_1 = + "(" + d1_lut_value + " * refl_value * " + light_src + ".specular_1)"; // Fresnel - if (lighting.lut_fr.enable && Pica::Regs::IsLightingSamplerSupported(lighting.config, Pica::Regs::LightingSampler::Fresnel)) { + if (lighting.lut_fr.enable && Pica::Regs::IsLightingSamplerSupported( + lighting.config, Pica::Regs::LightingSampler::Fresnel)) { // Lookup fresnel LUT value - std::string index = GetLutIndex(light_config.num, lighting.lut_fr.type, lighting.lut_fr.abs_input); - std::string value = "(" + std::to_string(lighting.lut_fr.scale) + " * " + GetLutValue(Regs::LightingSampler::Fresnel, index) + ")"; + std::string index = + GetLutIndex(light_config.num, lighting.lut_fr.type, lighting.lut_fr.abs_input); + std::string value = "(" + std::to_string(lighting.lut_fr.scale) + " * " + + GetLutValue(Regs::LightingSampler::Fresnel, index) + ")"; // Enabled for difffuse lighting alpha component if (lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::PrimaryAlpha || @@ -512,10 +559,12 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { } // Compute primary fragment color (diffuse lighting) function - out += "diffuse_sum.rgb += ((" + light_src + ".diffuse * " + dot_product + ") + " + light_src + ".ambient) * " + dist_atten + ";\n"; + out += "diffuse_sum.rgb += ((" + light_src + ".diffuse * " + dot_product + ") + " + + light_src + ".ambient) * " + dist_atten + ";\n"; // Compute secondary fragment color (specular lighting) function - out += "specular_sum.rgb += (" + specular_0 + " + " + specular_1 + ") * " + clamp_highlights + " * " + dist_atten + ";\n"; + out += "specular_sum.rgb += (" + specular_0 + " + " + specular_1 + ") * " + + clamp_highlights + " * " + dist_atten + ";\n"; } // Sum final lighting result @@ -598,9 +647,9 @@ vec4 secondary_fragment_color = vec4(0.0); out += "!"; // x2,y2 have +1 added to cover the entire pixel area out += "(gl_FragCoord.x >= scissor_x1 * framebuffer_scale.x && " - "gl_FragCoord.y >= scissor_y1 * framebuffer_scale.y && " - "gl_FragCoord.x < (scissor_x2 + 1) * framebuffer_scale.x && " - "gl_FragCoord.y < (scissor_y2 + 1) * framebuffer_scale.y)) discard;\n"; + "gl_FragCoord.y >= scissor_y1 * framebuffer_scale.y && " + "gl_FragCoord.x < (scissor_x2 + 1) * framebuffer_scale.x && " + "gl_FragCoord.y < (scissor_y2 + 1) * framebuffer_scale.y)) discard;\n"; } out += "float z_over_w = 1.0 - gl_FragCoord.z * 2.0;\n"; @@ -638,9 +687,11 @@ vec4 secondary_fragment_color = vec4(0.0); out += "float fog_i = clamp(floor(fog_index), 0.0, 127.0);\n"; out += "float fog_f = fog_index - fog_i;\n"; out += "uint fog_lut_entry = texelFetch(fog_lut, int(fog_i), 0).r;\n"; - out += "float fog_lut_entry_difference = float(int((fog_lut_entry & 0x1FFFU) << 19U) >> 19);\n"; // Extract signed difference + out += "float fog_lut_entry_difference = float(int((fog_lut_entry & 0x1FFFU) << 19U) >> " + "19);\n"; // Extract signed difference out += "float fog_lut_entry_value = float((fog_lut_entry >> 13U) & 0x7FFU);\n"; - out += "float fog_factor = (fog_lut_entry_value + fog_lut_entry_difference * fog_f) / 2047.0;\n"; + out += "float fog_factor = (fog_lut_entry_value + fog_lut_entry_difference * fog_f) / " + "2047.0;\n"; out += "fog_factor = clamp(fog_factor, 0.0, 1.0);\n"; // Blend the fog @@ -658,14 +709,20 @@ vec4 secondary_fragment_color = vec4(0.0); std::string GenerateVertexShader() { std::string out = "#version 330 core\n"; - out += "layout(location = " + std::to_string((int)ATTRIBUTE_POSITION) + ") in vec4 vert_position;\n"; - out += "layout(location = " + std::to_string((int)ATTRIBUTE_COLOR) + ") in vec4 vert_color;\n"; - out += "layout(location = " + std::to_string((int)ATTRIBUTE_TEXCOORD0) + ") in vec2 vert_texcoord0;\n"; - out += "layout(location = " + std::to_string((int)ATTRIBUTE_TEXCOORD1) + ") in vec2 vert_texcoord1;\n"; - out += "layout(location = " + std::to_string((int)ATTRIBUTE_TEXCOORD2) + ") in vec2 vert_texcoord2;\n"; - out += "layout(location = " + std::to_string((int)ATTRIBUTE_TEXCOORD0_W) + ") in float vert_texcoord0_w;\n"; - out += "layout(location = " + std::to_string((int)ATTRIBUTE_NORMQUAT) + ") in vec4 vert_normquat;\n"; - out += "layout(location = " + std::to_string((int)ATTRIBUTE_VIEW) + ") in vec3 vert_view;\n"; + out += "layout(location = " + std::to_string((int)ATTRIBUTE_POSITION) + + ") in vec4 vert_position;\n"; + out += "layout(location = " + std::to_string((int)ATTRIBUTE_COLOR) + ") in vec4 vert_color;\n"; + out += "layout(location = " + std::to_string((int)ATTRIBUTE_TEXCOORD0) + + ") in vec2 vert_texcoord0;\n"; + out += "layout(location = " + std::to_string((int)ATTRIBUTE_TEXCOORD1) + + ") in vec2 vert_texcoord1;\n"; + out += "layout(location = " + std::to_string((int)ATTRIBUTE_TEXCOORD2) + + ") in vec2 vert_texcoord2;\n"; + out += "layout(location = " + std::to_string((int)ATTRIBUTE_TEXCOORD0_W) + + ") in float vert_texcoord0_w;\n"; + out += "layout(location = " + std::to_string((int)ATTRIBUTE_NORMQUAT) + + ") in vec4 vert_normquat;\n"; + out += "layout(location = " + std::to_string((int)ATTRIBUTE_VIEW) + ") in vec3 vert_view;\n"; out += R"( out vec4 primary_color; diff --git a/src/video_core/renderer_opengl/gl_shader_util.cpp b/src/video_core/renderer_opengl/gl_shader_util.cpp index dded3db46..fe07aa6eb 100644 --- a/src/video_core/renderer_opengl/gl_shader_util.cpp +++ b/src/video_core/renderer_opengl/gl_shader_util.cpp @@ -3,9 +3,7 @@ // Refer to the license.txt file included. #include <vector> - #include <glad/glad.h> - #include "common/logging/log.h" #include "video_core/renderer_opengl/gl_shader_util.h" @@ -56,7 +54,8 @@ GLuint LoadProgram(const char* vertex_shader, const char* fragment_shader) { if (result) { LOG_DEBUG(Render_OpenGL, "%s", &fragment_shader_error[0]); } else { - LOG_ERROR(Render_OpenGL, "Error compiling fragment shader:\n%s", &fragment_shader_error[0]); + LOG_ERROR(Render_OpenGL, "Error compiling fragment shader:\n%s", + &fragment_shader_error[0]); } } diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index 13ee986b9..ed84cadea 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp @@ -3,10 +3,8 @@ // Refer to the license.txt file included. #include <glad/glad.h> - #include "common/common_funcs.h" #include "common/logging/log.h" - #include "video_core/renderer_opengl/gl_state.h" OpenGLState OpenGLState::cur_state; @@ -106,11 +104,11 @@ void OpenGLState::Apply() const { // Color mask if (color_mask.red_enabled != cur_state.color_mask.red_enabled || - color_mask.green_enabled != cur_state.color_mask.green_enabled || - color_mask.blue_enabled != cur_state.color_mask.blue_enabled || - color_mask.alpha_enabled != cur_state.color_mask.alpha_enabled) { - glColorMask(color_mask.red_enabled, color_mask.green_enabled, - color_mask.blue_enabled, color_mask.alpha_enabled); + color_mask.green_enabled != cur_state.color_mask.green_enabled || + color_mask.blue_enabled != cur_state.color_mask.blue_enabled || + color_mask.alpha_enabled != cur_state.color_mask.alpha_enabled) { + glColorMask(color_mask.red_enabled, color_mask.green_enabled, color_mask.blue_enabled, + color_mask.alpha_enabled); } // Stencil test @@ -123,15 +121,16 @@ void OpenGLState::Apply() const { } if (stencil.test_func != cur_state.stencil.test_func || - stencil.test_ref != cur_state.stencil.test_ref || - stencil.test_mask != cur_state.stencil.test_mask) { + stencil.test_ref != cur_state.stencil.test_ref || + stencil.test_mask != cur_state.stencil.test_mask) { glStencilFunc(stencil.test_func, stencil.test_ref, stencil.test_mask); } if (stencil.action_depth_fail != cur_state.stencil.action_depth_fail || - stencil.action_depth_pass != cur_state.stencil.action_depth_pass || - stencil.action_stencil_fail != cur_state.stencil.action_stencil_fail) { - glStencilOp(stencil.action_stencil_fail, stencil.action_depth_fail, stencil.action_depth_pass); + stencil.action_depth_pass != cur_state.stencil.action_depth_pass || + stencil.action_stencil_fail != cur_state.stencil.action_stencil_fail) { + glStencilOp(stencil.action_stencil_fail, stencil.action_depth_fail, + stencil.action_depth_pass); } // Stencil mask @@ -154,23 +153,22 @@ void OpenGLState::Apply() const { } if (blend.color.red != cur_state.blend.color.red || - blend.color.green != cur_state.blend.color.green || - blend.color.blue != cur_state.blend.color.blue || - blend.color.alpha != cur_state.blend.color.alpha) { - glBlendColor(blend.color.red, blend.color.green, - blend.color.blue, blend.color.alpha); + blend.color.green != cur_state.blend.color.green || + blend.color.blue != cur_state.blend.color.blue || + blend.color.alpha != cur_state.blend.color.alpha) { + glBlendColor(blend.color.red, blend.color.green, blend.color.blue, blend.color.alpha); } if (blend.src_rgb_func != cur_state.blend.src_rgb_func || - blend.dst_rgb_func != cur_state.blend.dst_rgb_func || - blend.src_a_func != cur_state.blend.src_a_func || - blend.dst_a_func != cur_state.blend.dst_a_func) { - glBlendFuncSeparate(blend.src_rgb_func, blend.dst_rgb_func, - blend.src_a_func, blend.dst_a_func); + blend.dst_rgb_func != cur_state.blend.dst_rgb_func || + blend.src_a_func != cur_state.blend.src_a_func || + blend.dst_a_func != cur_state.blend.dst_a_func) { + glBlendFuncSeparate(blend.src_rgb_func, blend.dst_rgb_func, blend.src_a_func, + blend.dst_a_func); } if (blend.rgb_equation != cur_state.blend.rgb_equation || - blend.a_equation != cur_state.blend.a_equation) { + blend.a_equation != cur_state.blend.a_equation) { glBlendEquationSeparate(blend.rgb_equation, blend.a_equation); } @@ -237,8 +235,11 @@ void OpenGLState::Apply() const { GLenum OpenGLState::CheckFBStatus(GLenum target) { GLenum fb_status = glCheckFramebufferStatus(target); if (fb_status != GL_FRAMEBUFFER_COMPLETE) { - const char* fb_description = (target == GL_READ_FRAMEBUFFER ? "READ" : (target == GL_DRAW_FRAMEBUFFER ? "DRAW" : "UNK")); - LOG_CRITICAL(Render_OpenGL, "OpenGL %s framebuffer check failed, status %X", fb_description, fb_status); + const char* fb_description = + (target == GL_READ_FRAMEBUFFER ? "READ" + : (target == GL_DRAW_FRAMEBUFFER ? "DRAW" : "UNK")); + LOG_CRITICAL(Render_OpenGL, "OpenGL %s framebuffer check failed, status %X", fb_description, + fb_status); } return fb_status; diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index 13c71b0a6..01dead883 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h @@ -9,14 +9,14 @@ class OpenGLState { public: struct { - bool enabled; // GL_CULL_FACE - GLenum mode; // GL_CULL_FACE_MODE + bool enabled; // GL_CULL_FACE + GLenum mode; // GL_CULL_FACE_MODE GLenum front_face; // GL_FRONT_FACE } cull; struct { - bool test_enabled; // GL_DEPTH_TEST - GLenum test_func; // GL_DEPTH_FUNC + bool test_enabled; // GL_DEPTH_TEST + GLenum test_func; // GL_DEPTH_FUNC GLboolean write_mask; // GL_DEPTH_WRITEMASK } depth; @@ -28,24 +28,24 @@ public: } color_mask; // GL_COLOR_WRITEMASK struct { - bool test_enabled; // GL_STENCIL_TEST - GLenum test_func; // GL_STENCIL_FUNC - GLint test_ref; // GL_STENCIL_REF - GLuint test_mask; // GL_STENCIL_VALUE_MASK - GLuint write_mask; // GL_STENCIL_WRITEMASK + bool test_enabled; // GL_STENCIL_TEST + GLenum test_func; // GL_STENCIL_FUNC + GLint test_ref; // GL_STENCIL_REF + GLuint test_mask; // GL_STENCIL_VALUE_MASK + GLuint write_mask; // GL_STENCIL_WRITEMASK GLenum action_stencil_fail; // GL_STENCIL_FAIL - GLenum action_depth_fail; // GL_STENCIL_PASS_DEPTH_FAIL - GLenum action_depth_pass; // GL_STENCIL_PASS_DEPTH_PASS + GLenum action_depth_fail; // GL_STENCIL_PASS_DEPTH_FAIL + GLenum action_depth_pass; // GL_STENCIL_PASS_DEPTH_PASS } stencil; struct { - bool enabled; // GL_BLEND + bool enabled; // GL_BLEND GLenum rgb_equation; // GL_BLEND_EQUATION_RGB - GLenum a_equation; // GL_BLEND_EQUATION_ALPHA + GLenum a_equation; // GL_BLEND_EQUATION_ALPHA GLenum src_rgb_func; // GL_BLEND_SRC_RGB GLenum dst_rgb_func; // GL_BLEND_DST_RGB - GLenum src_a_func; // GL_BLEND_SRC_ALPHA - GLenum dst_a_func; // GL_BLEND_DST_ALPHA + GLenum src_a_func; // GL_BLEND_SRC_ALPHA + GLenum dst_a_func; // GL_BLEND_DST_ALPHA struct { GLclampf red; @@ -60,7 +60,7 @@ public: // 3 texture units - one for each that is used in PICA fragment shader emulation struct { GLuint texture_2d; // GL_TEXTURE_BINDING_2D - GLuint sampler; // GL_SAMPLER_BINDING + GLuint sampler; // GL_SAMPLER_BINDING } texture_units[3]; struct { @@ -74,10 +74,10 @@ public: struct { GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING GLuint draw_framebuffer; // GL_DRAW_FRAMEBUFFER_BINDING - GLuint vertex_array; // GL_VERTEX_ARRAY_BINDING - GLuint vertex_buffer; // GL_ARRAY_BUFFER_BINDING - GLuint uniform_buffer; // GL_UNIFORM_BUFFER_BINDING - GLuint shader_program; // GL_CURRENT_PROGRAM + GLuint vertex_array; // GL_VERTEX_ARRAY_BINDING + GLuint vertex_buffer; // GL_ARRAY_BUFFER_BINDING + GLuint uniform_buffer; // GL_UNIFORM_BUFFER_BINDING + GLuint shader_program; // GL_CURRENT_PROGRAM } draw; OpenGLState(); diff --git a/src/video_core/renderer_opengl/pica_to_gl.h b/src/video_core/renderer_opengl/pica_to_gl.h index d9b9c9cc2..cc49867c8 100644 --- a/src/video_core/renderer_opengl/pica_to_gl.h +++ b/src/video_core/renderer_opengl/pica_to_gl.h @@ -6,15 +6,12 @@ #include <array> #include <cstddef> - #include <glad/glad.h> - #include "common/assert.h" #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" #include "common/logging/log.h" - #include "video_core/pica.h" using GLvec2 = std::array<GLfloat, 2>; @@ -25,8 +22,8 @@ namespace PicaToGL { inline GLenum TextureFilterMode(Pica::Regs::TextureConfig::TextureFilter mode) { static const GLenum filter_mode_table[] = { - GL_NEAREST, // TextureFilter::Nearest - GL_LINEAR // TextureFilter::Linear + GL_NEAREST, // TextureFilter::Nearest + GL_LINEAR, // TextureFilter::Linear }; // Range check table for input @@ -52,10 +49,10 @@ inline GLenum TextureFilterMode(Pica::Regs::TextureConfig::TextureFilter mode) { inline GLenum WrapMode(Pica::Regs::TextureConfig::WrapMode mode) { static const GLenum wrap_mode_table[] = { - GL_CLAMP_TO_EDGE, // WrapMode::ClampToEdge - GL_CLAMP_TO_BORDER,// WrapMode::ClampToBorder - GL_REPEAT, // WrapMode::Repeat - GL_MIRRORED_REPEAT // WrapMode::MirroredRepeat + GL_CLAMP_TO_EDGE, // WrapMode::ClampToEdge + GL_CLAMP_TO_BORDER, // WrapMode::ClampToBorder + GL_REPEAT, // WrapMode::Repeat + GL_MIRRORED_REPEAT, // WrapMode::MirroredRepeat }; // Range check table for input @@ -131,22 +128,22 @@ inline GLenum BlendFunc(Pica::Regs::BlendFactor factor) { inline GLenum LogicOp(Pica::Regs::LogicOp op) { static const GLenum logic_op_table[] = { - GL_CLEAR, // Clear - GL_AND, // And - GL_AND_REVERSE, // AndReverse - GL_COPY, // Copy - GL_SET, // Set - GL_COPY_INVERTED, // CopyInverted - GL_NOOP, // NoOp - GL_INVERT, // Invert - GL_NAND, // Nand - GL_OR, // Or - GL_NOR, // Nor - GL_XOR, // Xor - GL_EQUIV, // Equiv - GL_AND_INVERTED, // AndInverted - GL_OR_REVERSE, // OrReverse - GL_OR_INVERTED, // OrInverted + GL_CLEAR, // Clear + GL_AND, // And + GL_AND_REVERSE, // AndReverse + GL_COPY, // Copy + GL_SET, // Set + GL_COPY_INVERTED, // CopyInverted + GL_NOOP, // NoOp + GL_INVERT, // Invert + GL_NAND, // Nand + GL_OR, // Or + GL_NOR, // Nor + GL_XOR, // Xor + GL_EQUIV, // Equiv + GL_AND_INVERTED, // AndInverted + GL_OR_REVERSE, // OrReverse + GL_OR_INVERTED, // OrInverted }; // Range check table for input @@ -185,14 +182,14 @@ inline GLenum CompareFunc(Pica::Regs::CompareFunc func) { inline GLenum StencilOp(Pica::Regs::StencilAction action) { static const GLenum stencil_op_table[] = { - GL_KEEP, // StencilAction::Keep - GL_ZERO, // StencilAction::Zero - GL_REPLACE, // StencilAction::Replace - GL_INCR, // StencilAction::Increment - GL_DECR, // StencilAction::Decrement - GL_INVERT, // StencilAction::Invert - GL_INCR_WRAP, // StencilAction::IncrementWrap - GL_DECR_WRAP // StencilAction::DecrementWrap + GL_KEEP, // StencilAction::Keep + GL_ZERO, // StencilAction::Zero + GL_REPLACE, // StencilAction::Replace + GL_INCR, // StencilAction::Increment + GL_DECR, // StencilAction::Decrement + GL_INVERT, // StencilAction::Invert + GL_INCR_WRAP, // StencilAction::IncrementWrap + GL_DECR_WRAP, // StencilAction::DecrementWrap }; // Range check table for input @@ -207,18 +204,16 @@ inline GLenum StencilOp(Pica::Regs::StencilAction action) { } inline GLvec4 ColorRGBA8(const u32 color) { - return { { (color >> 0 & 0xFF) / 255.0f, - (color >> 8 & 0xFF) / 255.0f, - (color >> 16 & 0xFF) / 255.0f, - (color >> 24 & 0xFF) / 255.0f - } }; + return {{ + (color >> 0 & 0xFF) / 255.0f, (color >> 8 & 0xFF) / 255.0f, (color >> 16 & 0xFF) / 255.0f, + (color >> 24 & 0xFF) / 255.0f, + }}; } inline std::array<GLfloat, 3> LightColor(const Pica::Regs::LightColor& color) { - return { { color.r / 255.0f, - color.g / 255.0f, - color.b / 255.0f - } }; + return {{ + color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, + }}; } } // namespace diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 8410e0a64..03a588364 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -6,23 +6,19 @@ #include <cstddef> #include <cstdlib> #include <memory> - #include <glad/glad.h> - #include "common/assert.h" #include "common/bit_field.h" #include "common/emu_window.h" #include "common/logging/log.h" #include "common/profiler_reporting.h" #include "common/synchronized_wrapper.h" - #include "core/hw/gpu.h" #include "core/hw/hw.h" #include "core/hw/lcd.h" #include "core/memory.h" #include "core/settings.h" #include "core/tracer/recorder.h" - #include "video_core/debug_utils/debug_utils.h" #include "video_core/rasterizer_interface.h" #include "video_core/renderer_opengl/renderer_opengl.h" @@ -87,24 +83,25 @@ struct ScreenRectVertex { * by a 3x2 matrix. */ static std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(const float width, const float height) { - std::array<GLfloat, 3 * 2> matrix; + std::array<GLfloat, 3 * 2> matrix; // Laid out in column-major order + // clang-format off matrix[0] = 2.f / width; matrix[2] = 0.f; matrix[4] = -1.f; matrix[1] = 0.f; matrix[3] = -2.f / height; matrix[5] = 1.f; // Last matrix row is implicitly assumed to be [0, 0, 1]. + // clang-format on return matrix; } /// RendererOpenGL constructor RendererOpenGL::RendererOpenGL() { - resolution_width = std::max(VideoCore::kScreenTopWidth, VideoCore::kScreenBottomWidth); + resolution_width = std::max(VideoCore::kScreenTopWidth, VideoCore::kScreenBottomWidth); resolution_height = VideoCore::kScreenTopHeight + VideoCore::kScreenBottomHeight; } /// RendererOpenGL destructor -RendererOpenGL::~RendererOpenGL() { -} +RendererOpenGL::~RendererOpenGL() {} /// Swap buffers (render frame) void RendererOpenGL::SwapBuffers() { @@ -116,13 +113,15 @@ void RendererOpenGL::SwapBuffers() { const auto& framebuffer = GPU::g_regs.framebuffer_config[i]; // Main LCD (0): 0x1ED02204, Sub LCD (1): 0x1ED02A04 - u32 lcd_color_addr = (i == 0) ? LCD_REG_INDEX(color_fill_top) : LCD_REG_INDEX(color_fill_bottom); + u32 lcd_color_addr = + (i == 0) ? LCD_REG_INDEX(color_fill_top) : LCD_REG_INDEX(color_fill_bottom); lcd_color_addr = HW::VADDR_LCD + 4 * lcd_color_addr; LCD::Regs::ColorFill color_fill = {0}; LCD::Read(color_fill.raw, lcd_color_addr); if (color_fill.is_enabled) { - LoadColorToActiveGLTexture(color_fill.color_r, color_fill.color_g, color_fill.color_b, screen_infos[i].texture); + LoadColorToActiveGLTexture(color_fill.color_r, color_fill.color_g, color_fill.color_b, + screen_infos[i].texture); // Resize the texture in case the framebuffer size has changed screen_infos[i].texture.width = 1; @@ -172,15 +171,14 @@ void RendererOpenGL::SwapBuffers() { * Loads framebuffer from emulated memory into the active OpenGL texture. */ void RendererOpenGL::LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& framebuffer, - ScreenInfo& screen_info) { + ScreenInfo& screen_info) { - const PAddr framebuffer_addr = framebuffer.active_fb == 0 ? - framebuffer.address_left1 : framebuffer.address_left2; + const PAddr framebuffer_addr = + framebuffer.active_fb == 0 ? framebuffer.address_left1 : framebuffer.address_left2; LOG_TRACE(Render_OpenGL, "0x%08x bytes from 0x%08x(%dx%d), fmt %x", - framebuffer.stride * framebuffer.height, - framebuffer_addr, (int)framebuffer.width, - (int)framebuffer.height, (int)framebuffer.format); + framebuffer.stride * framebuffer.height, framebuffer_addr, (int)framebuffer.width, + (int)framebuffer.height, (int)framebuffer.format); int bpp = GPU::Regs::BytesPerPixel(framebuffer.color_format); size_t pixel_stride = framebuffer.stride / bpp; @@ -192,7 +190,8 @@ void RendererOpenGL::LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& fram // only allows rows to have a memory alignement of 4. ASSERT(pixel_stride % 4 == 0); - if (!Rasterizer()->AccelerateDisplay(framebuffer, framebuffer_addr, static_cast<u32>(pixel_stride), screen_info)) { + if (!Rasterizer()->AccelerateDisplay(framebuffer, framebuffer_addr, + static_cast<u32>(pixel_stride), screen_info)) { // Reset the screen info's display texture to its own permanent texture screen_info.display_texture = screen_info.texture.resource.handle; screen_info.display_texcoords = MathUtil::Rectangle<float>(0.f, 0.f, 1.f, 1.f); @@ -208,12 +207,13 @@ void RendererOpenGL::LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& fram glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)pixel_stride); // Update existing texture - // TODO: Test what happens on hardware when you change the framebuffer dimensions so that they - // differ from the LCD resolution. + // TODO: Test what happens on hardware when you change the framebuffer dimensions so that + // they differ from the LCD resolution. // TODO: Applications could theoretically crash Citra here by specifying too large // framebuffer sizes. We should make sure that this cannot happen. glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, framebuffer.width, framebuffer.height, - screen_info.texture.gl_format, screen_info.texture.gl_type, framebuffer_data); + screen_info.texture.gl_format, screen_info.texture.gl_type, + framebuffer_data); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); @@ -223,9 +223,8 @@ void RendererOpenGL::LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& fram } /** - * Fills active OpenGL texture with the given RGB color. - * Since the color is solid, the texture can be 1x1 but will stretch across whatever it's rendered on. - * This has the added benefit of being *really fast*. + * Fills active OpenGL texture with the given RGB color. Since the color is solid, the texture can + * be 1x1 but will stretch across whatever it's rendered on. */ void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, const TextureInfo& texture) { @@ -233,7 +232,7 @@ void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color state.Apply(); glActiveTexture(GL_TEXTURE0); - u8 framebuffer_data[3] = { color_r, color_g, color_b }; + u8 framebuffer_data[3] = {color_r, color_g, color_b}; // Update existing texture glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, framebuffer_data); @@ -246,7 +245,8 @@ void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color * Initializes the OpenGL state and creates persistent objects. */ void RendererOpenGL::InitOpenGLObjects() { - glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue, 0.0f); + glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue, + 0.0f); // Link shaders and get variable locations shader.Create(vertex_shader, fragment_shader); @@ -270,8 +270,10 @@ void RendererOpenGL::InitOpenGLObjects() { // Attach vertex data to VAO glBufferData(GL_ARRAY_BUFFER, sizeof(ScreenRectVertex) * 4, nullptr, GL_STREAM_DRAW); - glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, sizeof(ScreenRectVertex), (GLvoid*)offsetof(ScreenRectVertex, position)); - glVertexAttribPointer(attrib_tex_coord, 2, GL_FLOAT, GL_FALSE, sizeof(ScreenRectVertex), (GLvoid*)offsetof(ScreenRectVertex, tex_coord)); + glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, sizeof(ScreenRectVertex), + (GLvoid*)offsetof(ScreenRectVertex, position)); + glVertexAttribPointer(attrib_tex_coord, 2, GL_FLOAT, GL_FALSE, sizeof(ScreenRectVertex), + (GLvoid*)offsetof(ScreenRectVertex, tex_coord)); glEnableVertexAttribArray(attrib_position); glEnableVertexAttribArray(attrib_tex_coord); @@ -352,23 +354,25 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, glActiveTexture(GL_TEXTURE0); glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0, - texture.gl_format, texture.gl_type, nullptr); + texture.gl_format, texture.gl_type, nullptr); state.texture_units[0].texture_2d = 0; state.Apply(); } /** - * Draws a single texture to the emulator window, rotating the texture to correct for the 3DS's LCD rotation. + * Draws a single texture to the emulator window, rotating the texture to correct for the 3DS's LCD + * rotation. */ -void RendererOpenGL::DrawSingleScreenRotated(const ScreenInfo& screen_info, float x, float y, float w, float h) { +void RendererOpenGL::DrawSingleScreenRotated(const ScreenInfo& screen_info, float x, float y, + float w, float h) { auto& texcoords = screen_info.display_texcoords; std::array<ScreenRectVertex, 4> vertices = {{ - ScreenRectVertex(x, y, texcoords.bottom, texcoords.left), - ScreenRectVertex(x+w, y, texcoords.bottom, texcoords.right), - ScreenRectVertex(x, y+h, texcoords.top, texcoords.left), - ScreenRectVertex(x+w, y+h, texcoords.top, texcoords.right), + ScreenRectVertex(x, y, texcoords.bottom, texcoords.left), + ScreenRectVertex(x + w, y, texcoords.bottom, texcoords.right), + ScreenRectVertex(x, y + h, texcoords.top, texcoords.left), + ScreenRectVertex(x + w, y + h, texcoords.top, texcoords.right), }}; state.texture_units[0].texture_2d = screen_info.display_texture; @@ -391,25 +395,26 @@ void RendererOpenGL::DrawScreens() { glClear(GL_COLOR_BUFFER_BIT); // Set projection matrix - std::array<GLfloat, 3 * 2> ortho_matrix = MakeOrthographicMatrix((float)layout.width, - (float)layout.height); + std::array<GLfloat, 3 * 2> ortho_matrix = + MakeOrthographicMatrix((float)layout.width, (float)layout.height); glUniformMatrix3x2fv(uniform_modelview_matrix, 1, GL_FALSE, ortho_matrix.data()); // Bind texture in Texture Unit 0 glActiveTexture(GL_TEXTURE0); glUniform1i(uniform_color_texture, 0); - DrawSingleScreenRotated(screen_infos[0], (float)layout.top_screen.left, (float)layout.top_screen.top, - (float)layout.top_screen.GetWidth(), (float)layout.top_screen.GetHeight()); - DrawSingleScreenRotated(screen_infos[1], (float)layout.bottom_screen.left,(float)layout.bottom_screen.top, - (float)layout.bottom_screen.GetWidth(), (float)layout.bottom_screen.GetHeight()); + DrawSingleScreenRotated(screen_infos[0], (float)layout.top_screen.left, + (float)layout.top_screen.top, (float)layout.top_screen.GetWidth(), + (float)layout.top_screen.GetHeight()); + DrawSingleScreenRotated(screen_infos[1], (float)layout.bottom_screen.left, + (float)layout.bottom_screen.top, (float)layout.bottom_screen.GetWidth(), + (float)layout.bottom_screen.GetHeight()); m_current_frame++; } /// Updates the framerate -void RendererOpenGL::UpdateFramerate() { -} +void RendererOpenGL::UpdateFramerate() {} /** * Set the emulator window to use for renderer @@ -420,14 +425,16 @@ void RendererOpenGL::SetWindow(EmuWindow* window) { } static const char* GetSource(GLenum source) { -#define RET(s) case GL_DEBUG_SOURCE_##s: return #s +#define RET(s) \ + case GL_DEBUG_SOURCE_##s: \ + return #s switch (source) { - RET(API); - RET(WINDOW_SYSTEM); - RET(SHADER_COMPILER); - RET(THIRD_PARTY); - RET(APPLICATION); - RET(OTHER); + RET(API); + RET(WINDOW_SYSTEM); + RET(SHADER_COMPILER); + RET(THIRD_PARTY); + RET(APPLICATION); + RET(OTHER); default: UNREACHABLE(); } @@ -435,23 +442,25 @@ static const char* GetSource(GLenum source) { } static const char* GetType(GLenum type) { -#define RET(t) case GL_DEBUG_TYPE_##t: return #t +#define RET(t) \ + case GL_DEBUG_TYPE_##t: \ + return #t switch (type) { - RET(ERROR); - RET(DEPRECATED_BEHAVIOR); - RET(UNDEFINED_BEHAVIOR); - RET(PORTABILITY); - RET(PERFORMANCE); - RET(OTHER); - RET(MARKER); + RET(ERROR); + RET(DEPRECATED_BEHAVIOR); + RET(UNDEFINED_BEHAVIOR); + RET(PORTABILITY); + RET(PERFORMANCE); + RET(OTHER); + RET(MARKER); default: UNREACHABLE(); } #undef RET } -static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, - const GLchar* message, const void* user_param) { +static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum severity, + GLsizei length, const GLchar* message, const void* user_param) { Log::Level level; switch (severity) { case GL_DEBUG_SEVERITY_HIGH: @@ -465,8 +474,8 @@ static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum level = Log::Level::Debug; break; } - LOG_GENERIC(Log::Class::Render_OpenGL, level, "%s %s %d: %s", - GetSource(source), GetType(type), id, message); + LOG_GENERIC(Log::Class::Render_OpenGL, level, "%s %s %d: %s", GetSource(source), GetType(type), + id, message); } /// Initialize the renderer @@ -493,5 +502,4 @@ bool RendererOpenGL::Init() { } /// Shutdown the renderer -void RendererOpenGL::ShutDown() { -} +void RendererOpenGL::ShutDown() {} diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index 00e1044ab..87c556cff 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h @@ -5,14 +5,10 @@ #pragma once #include <array> - #include <glad/glad.h> - #include "common/common_types.h" #include "common/math_util.h" - #include "core/hw/gpu.h" - #include "video_core/renderer_base.h" #include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_state.h" @@ -38,7 +34,6 @@ struct ScreenInfo { class RendererOpenGL : public RendererBase { public: - RendererOpenGL(); ~RendererOpenGL() override; @@ -67,15 +62,14 @@ private: // Loads framebuffer from emulated memory into the display information structure void LoadFBToScreenInfo(const GPU::Regs::FramebufferConfig& framebuffer, - ScreenInfo& screen_info); + ScreenInfo& screen_info); // Fills active OpenGL texture with the given RGB color. - void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, - const TextureInfo& texture); + void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, const TextureInfo& texture); - EmuWindow* render_window; ///< Handle to render window + EmuWindow* render_window; ///< Handle to render window - int resolution_width; ///< Current resolution width - int resolution_height; ///< Current resolution height + int resolution_width; ///< Current resolution width + int resolution_height; ///< Current resolution height OpenGLState state; @@ -83,10 +77,14 @@ private: OGLVertexArray vertex_array; OGLBuffer vertex_buffer; OGLShader shader; - std::array<ScreenInfo, 2> screen_infos; ///< Display information for top and bottom screens respectively + + /// Display information for top and bottom screens respectively + std::array<ScreenInfo, 2> screen_infos; + // Shader uniform location indices GLuint uniform_modelview_matrix; GLuint uniform_color_texture; + // Shader attribute input indices GLuint attrib_position; GLuint attrib_tex_coord; diff --git a/src/video_core/shader/shader.cpp b/src/video_core/shader/shader.cpp index f565e2c91..272f3ffe1 100644 --- a/src/video_core/shader/shader.cpp +++ b/src/video_core/shader/shader.cpp @@ -7,23 +7,18 @@ #include <cstring> #include <unordered_map> #include <utility> - #include <boost/range/algorithm/fill.hpp> - #include "common/bit_field.h" #include "common/hash.h" #include "common/logging/log.h" #include "common/microprofile.h" - #include "video_core/pica.h" #include "video_core/pica_state.h" #include "video_core/shader/shader.h" #include "video_core/shader/shader_interpreter.h" - #ifdef ARCHITECTURE_x86_64 #include "video_core/shader/shader_jit_x64.h" #endif // ARCHITECTURE_x86_64 - #include "video_core/video_core.h" namespace Pica { @@ -46,10 +41,8 @@ OutputVertex OutputRegisters::ToVertex(const Regs::ShaderConfig& config) { const auto& output_register_map = g_state.regs.vs_output_attributes[index]; - u32 semantics[4] = { - output_register_map.map_x, output_register_map.map_y, - output_register_map.map_z, output_register_map.map_w - }; + u32 semantics[4] = {output_register_map.map_x, output_register_map.map_y, + output_register_map.map_z, output_register_map.map_w}; for (unsigned comp = 0; comp < 4; ++comp) { float24* out = ((float24*)&ret) + semantics[comp]; @@ -65,19 +58,20 @@ OutputVertex OutputRegisters::ToVertex(const Regs::ShaderConfig& config) { index++; } - // The hardware takes the absolute and saturates vertex colors like this, *before* doing interpolation + // The hardware takes the absolute and saturates vertex colors like this, *before* doing + // interpolation for (unsigned i = 0; i < 4; ++i) { - ret.color[i] = float24::FromFloat32( - std::fmin(std::fabs(ret.color[i].ToFloat32()), 1.0f)); + ret.color[i] = float24::FromFloat32(std::fmin(std::fabs(ret.color[i].ToFloat32()), 1.0f)); } LOG_TRACE(HW_GPU, "Output vertex: pos(%.2f, %.2f, %.2f, %.2f), quat(%.2f, %.2f, %.2f, %.2f), " - "col(%.2f, %.2f, %.2f, %.2f), tc0(%.2f, %.2f), view(%.2f, %.2f, %.2f)", - ret.pos.x.ToFloat32(), ret.pos.y.ToFloat32(), ret.pos.z.ToFloat32(), ret.pos.w.ToFloat32(), - ret.quat.x.ToFloat32(), ret.quat.y.ToFloat32(), ret.quat.z.ToFloat32(), ret.quat.w.ToFloat32(), - ret.color.x.ToFloat32(), ret.color.y.ToFloat32(), ret.color.z.ToFloat32(), ret.color.w.ToFloat32(), - ret.tc0.u().ToFloat32(), ret.tc0.v().ToFloat32(), - ret.view.x.ToFloat32(), ret.view.y.ToFloat32(), ret.view.z.ToFloat32()); + "col(%.2f, %.2f, %.2f, %.2f), tc0(%.2f, %.2f), view(%.2f, %.2f, %.2f)", + ret.pos.x.ToFloat32(), ret.pos.y.ToFloat32(), ret.pos.z.ToFloat32(), + ret.pos.w.ToFloat32(), ret.quat.x.ToFloat32(), ret.quat.y.ToFloat32(), + ret.quat.z.ToFloat32(), ret.quat.w.ToFloat32(), ret.color.x.ToFloat32(), + ret.color.y.ToFloat32(), ret.color.z.ToFloat32(), ret.color.w.ToFloat32(), + ret.tc0.u().ToFloat32(), ret.tc0.v().ToFloat32(), ret.view.x.ToFloat32(), + ret.view.y.ToFloat32(), ret.view.z.ToFloat32()); return ret; } @@ -96,8 +90,9 @@ void ClearCache() { void ShaderSetup::Setup() { #ifdef ARCHITECTURE_x86_64 if (VideoCore::g_shader_jit_enabled) { - u64 cache_key = (Common::ComputeHash64(&g_state.vs.program_code, sizeof(g_state.vs.program_code)) ^ - Common::ComputeHash64(&g_state.vs.swizzle_data, sizeof(g_state.vs.swizzle_data))); + u64 cache_key = + Common::ComputeHash64(&g_state.vs.program_code, sizeof(g_state.vs.program_code)) ^ + Common::ComputeHash64(&g_state.vs.swizzle_data, sizeof(g_state.vs.swizzle_data)); auto iter = shader_map.find(cache_key); if (iter != shader_map.end()) { @@ -127,7 +122,7 @@ void ShaderSetup::Run(UnitState<false>& state, const InputVertex& input, int num const auto& attribute_register_map = config.input_register_map; for (unsigned i = 0; i < num_attributes; i++) - state.registers.input[attribute_register_map.GetRegisterForAttribute(i)] = input.attr[i]; + state.registers.input[attribute_register_map.GetRegisterForAttribute(i)] = input.attr[i]; state.conditional_code[0] = false; state.conditional_code[1] = false; @@ -140,10 +135,11 @@ void ShaderSetup::Run(UnitState<false>& state, const InputVertex& input, int num #else RunInterpreter(setup, state, config.main_offset); #endif // ARCHITECTURE_x86_64 - } -DebugData<true> ShaderSetup::ProduceDebugInfo(const InputVertex& input, int num_attributes, const Regs::ShaderConfig& config, const ShaderSetup& setup) { +DebugData<true> ShaderSetup::ProduceDebugInfo(const InputVertex& input, int num_attributes, + const Regs::ShaderConfig& config, + const ShaderSetup& setup) { UnitState<true> state; state.debug.max_offset = 0; @@ -155,7 +151,7 @@ DebugData<true> ShaderSetup::ProduceDebugInfo(const InputVertex& input, int num_ boost::fill(state.registers.input, &dummy_register); for (unsigned i = 0; i < num_attributes; i++) - state.registers.input[attribute_register_map.GetRegisterForAttribute(i)] = input.attr[i]; + state.registers.input[attribute_register_map.GetRegisterForAttribute(i)] = input.attr[i]; state.conditional_code[0] = false; state.conditional_code[1] = false; diff --git a/src/video_core/shader/shader.h b/src/video_core/shader/shader.h index fee16df62..8858d67f8 100644 --- a/src/video_core/shader/shader.h +++ b/src/video_core/shader/shader.h @@ -9,16 +9,12 @@ #include <memory> #include <type_traits> #include <vector> - #include <boost/container/static_vector.hpp> - #include <nihstro/shader_bytecode.h> - #include "common/assert.h" #include "common/common_funcs.h" #include "common/common_types.h" #include "common/vector_math.h" - #include "video_core/pica.h" #include "video_core/pica_types.h" @@ -94,46 +90,46 @@ struct OutputRegisters { static_assert(std::is_pod<OutputRegisters>::value, "Structure is not POD"); // Helper structure used to keep track of data useful for inspection of shader emulation -template<bool full_debugging> +template <bool full_debugging> struct DebugData; -template<> +template <> struct DebugData<false> { // TODO: Hide these behind and interface and move them to DebugData<true> - u32 max_offset; // maximum program counter ever reached + u32 max_offset; // maximum program counter ever reached u32 max_opdesc_id; // maximum swizzle pattern index ever used }; -template<> +template <> struct DebugData<true> { // Records store the input and output operands of a particular instruction. struct Record { enum Type { // Floating point arithmetic operands - SRC1 = 0x1, - SRC2 = 0x2, - SRC3 = 0x4, + SRC1 = 0x1, + SRC2 = 0x2, + SRC3 = 0x4, // Initial and final output operand value - DEST_IN = 0x8, - DEST_OUT = 0x10, + DEST_IN = 0x8, + DEST_OUT = 0x10, // Current and next instruction offset (in words) - CUR_INSTR = 0x20, - NEXT_INSTR = 0x40, + CUR_INSTR = 0x20, + NEXT_INSTR = 0x40, // Output address register value ADDR_REG_OUT = 0x80, // Result of a comparison instruction - CMP_RESULT = 0x100, + CMP_RESULT = 0x100, // Input values for conditional flow control instructions COND_BOOL_IN = 0x200, - COND_CMP_IN = 0x400, + COND_CMP_IN = 0x400, // Input values for a loop - LOOP_INT_IN = 0x800, + LOOP_INT_IN = 0x800, }; Math::Vec4<float24> src1; @@ -156,7 +152,7 @@ struct DebugData<true> { unsigned mask = 0; }; - u32 max_offset; // maximum program counter ever reached + u32 max_offset; // maximum program counter ever reached u32 max_opdesc_id; // maximum swizzle pattern index ever used // List of records for each executed shader instruction @@ -167,10 +163,10 @@ struct DebugData<true> { using DebugDataRecord = DebugData<true>::Record; // Helper function to set a DebugData<true>::Record field based on the template enum parameter. -template<DebugDataRecord::Type type, typename ValueType> +template <DebugDataRecord::Type type, typename ValueType> inline void SetField(DebugDataRecord& record, ValueType value); -template<> +template <> inline void SetField<DebugDataRecord::SRC1>(DebugDataRecord& record, float24* value) { record.src1.x = value[0]; record.src1.y = value[1]; @@ -178,7 +174,7 @@ inline void SetField<DebugDataRecord::SRC1>(DebugDataRecord& record, float24* va record.src1.w = value[3]; } -template<> +template <> inline void SetField<DebugDataRecord::SRC2>(DebugDataRecord& record, float24* value) { record.src2.x = value[0]; record.src2.y = value[1]; @@ -186,7 +182,7 @@ inline void SetField<DebugDataRecord::SRC2>(DebugDataRecord& record, float24* va record.src2.w = value[3]; } -template<> +template <> inline void SetField<DebugDataRecord::SRC3>(DebugDataRecord& record, float24* value) { record.src3.x = value[0]; record.src3.y = value[1]; @@ -194,7 +190,7 @@ inline void SetField<DebugDataRecord::SRC3>(DebugDataRecord& record, float24* va record.src3.w = value[3]; } -template<> +template <> inline void SetField<DebugDataRecord::DEST_IN>(DebugDataRecord& record, float24* value) { record.dest_in.x = value[0]; record.dest_in.y = value[1]; @@ -202,7 +198,7 @@ inline void SetField<DebugDataRecord::DEST_IN>(DebugDataRecord& record, float24* record.dest_in.w = value[3]; } -template<> +template <> inline void SetField<DebugDataRecord::DEST_OUT>(DebugDataRecord& record, float24* value) { record.dest_out.x = value[0]; record.dest_out.y = value[1]; @@ -210,67 +206,66 @@ inline void SetField<DebugDataRecord::DEST_OUT>(DebugDataRecord& record, float24 record.dest_out.w = value[3]; } -template<> +template <> inline void SetField<DebugDataRecord::ADDR_REG_OUT>(DebugDataRecord& record, s32* value) { record.address_registers[0] = value[0]; record.address_registers[1] = value[1]; } -template<> +template <> inline void SetField<DebugDataRecord::CMP_RESULT>(DebugDataRecord& record, bool* value) { record.conditional_code[0] = value[0]; record.conditional_code[1] = value[1]; } -template<> +template <> inline void SetField<DebugDataRecord::COND_BOOL_IN>(DebugDataRecord& record, bool value) { record.cond_bool = value; } -template<> +template <> inline void SetField<DebugDataRecord::COND_CMP_IN>(DebugDataRecord& record, bool* value) { record.cond_cmp[0] = value[0]; record.cond_cmp[1] = value[1]; } -template<> +template <> inline void SetField<DebugDataRecord::LOOP_INT_IN>(DebugDataRecord& record, Math::Vec4<u8> value) { record.loop_int = value; } -template<> +template <> inline void SetField<DebugDataRecord::CUR_INSTR>(DebugDataRecord& record, u32 value) { record.instruction_offset = value; } -template<> +template <> inline void SetField<DebugDataRecord::NEXT_INSTR>(DebugDataRecord& record, u32 value) { record.next_instruction = value; } // Helper function to set debug information on the current shader iteration. -template<DebugDataRecord::Type type, typename ValueType> +template <DebugDataRecord::Type type, typename ValueType> inline void Record(DebugData<false>& debug_data, u32 offset, ValueType value) { // Debugging disabled => nothing to do } -template<DebugDataRecord::Type type, typename ValueType> +template <DebugDataRecord::Type type, typename ValueType> inline void Record(DebugData<true>& debug_data, u32 offset, ValueType value) { if (offset >= debug_data.records.size()) debug_data.records.resize(offset + 1); - SetField<type, ValueType>(debug_data.records[offset], value); - debug_data.records[offset].mask |= type; + SetField<type, ValueType>(debug_data.records[offset], value); + debug_data.records[offset].mask |= type; } - /** * This structure contains the state information that needs to be unique for a shader unit. The 3DS * has four shader units that process shaders in parallel. At the present, Citra only implements a * single shader unit that processes all shaders serially. Putting the state information in a struct * here will make it easier for us to parallelize the shader processing later. */ -template<bool Debug> +template <bool Debug> struct UnitState { struct Registers { // The registers are accessed by the shader JIT using SSE instructions, and are therefore @@ -293,10 +288,12 @@ struct UnitState { static size_t InputOffset(const SourceRegister& reg) { switch (reg.GetRegisterType()) { case RegisterType::Input: - return offsetof(UnitState, registers.input) + reg.GetIndex()*sizeof(Math::Vec4<float24>); + return offsetof(UnitState, registers.input) + + reg.GetIndex() * sizeof(Math::Vec4<float24>); case RegisterType::Temporary: - return offsetof(UnitState, registers.temporary) + reg.GetIndex()*sizeof(Math::Vec4<float24>); + return offsetof(UnitState, registers.temporary) + + reg.GetIndex() * sizeof(Math::Vec4<float24>); default: UNREACHABLE(); @@ -307,10 +304,12 @@ struct UnitState { static size_t OutputOffset(const DestRegister& reg) { switch (reg.GetRegisterType()) { case RegisterType::Output: - return offsetof(UnitState, output_registers.value) + reg.GetIndex()*sizeof(Math::Vec4<float24>); + return offsetof(UnitState, output_registers.value) + + reg.GetIndex() * sizeof(Math::Vec4<float24>); case RegisterType::Temporary: - return offsetof(UnitState, registers.temporary) + reg.GetIndex()*sizeof(Math::Vec4<float24>); + return offsetof(UnitState, registers.temporary) + + reg.GetIndex() * sizeof(Math::Vec4<float24>); default: UNREACHABLE(); @@ -336,13 +335,13 @@ struct ShaderSetup { static size_t UniformOffset(RegisterType type, unsigned index) { switch (type) { case RegisterType::FloatUniform: - return offsetof(ShaderSetup, uniforms.f) + index*sizeof(Math::Vec4<float24>); + return offsetof(ShaderSetup, uniforms.f) + index * sizeof(Math::Vec4<float24>); case RegisterType::BoolUniform: - return offsetof(ShaderSetup, uniforms.b) + index*sizeof(bool); + return offsetof(ShaderSetup, uniforms.b) + index * sizeof(bool); case RegisterType::IntUniform: - return offsetof(ShaderSetup, uniforms.i) + index*sizeof(Math::Vec4<u8>); + return offsetof(ShaderSetup, uniforms.i) + index * sizeof(Math::Vec4<u8>); default: UNREACHABLE(); @@ -354,8 +353,8 @@ struct ShaderSetup { std::array<u32, 1024> swizzle_data; /** - * Performs any shader unit setup that only needs to happen once per shader (as opposed to once per - * vertex, which would happen within the `Run` function). + * Performs any shader unit setup that only needs to happen once per shader (as opposed to once + * per vertex, which would happen within the `Run` function). */ void Setup(); @@ -375,8 +374,8 @@ struct ShaderSetup { * @param setup Setup object for the shader pipeline * @return Debug information for this shader with regards to the given vertex */ - DebugData<true> ProduceDebugInfo(const InputVertex& input, int num_attributes, const Regs::ShaderConfig& config, const ShaderSetup& setup); - + DebugData<true> ProduceDebugInfo(const InputVertex& input, int num_attributes, + const Regs::ShaderConfig& config, const ShaderSetup& setup); }; } // namespace Shader diff --git a/src/video_core/shader/shader_interpreter.cpp b/src/video_core/shader/shader_interpreter.cpp index f6c86a759..501d00b6b 100644 --- a/src/video_core/shader/shader_interpreter.cpp +++ b/src/video_core/shader/shader_interpreter.cpp @@ -6,14 +6,11 @@ #include <array> #include <cmath> #include <numeric> - #include <nihstro/shader_bytecode.h> - #include "common/assert.h" #include "common/common_types.h" #include "common/logging/log.h" #include "common/vector_math.h" - #include "video_core/pica_state.h" #include "video_core/pica_types.h" #include "video_core/shader/shader.h" @@ -40,7 +37,7 @@ struct CallStackElement { u32 loop_address; // The address where we'll return to after each loop iteration }; -template<bool Debug> +template <bool Debug> void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned offset) { // TODO: Is there a maximal size for this? boost::container::static_vector<CallStackElement, 16> call_stack; @@ -74,14 +71,17 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned } } - const Instruction instr = { program_code[program_counter] }; - const SwizzlePattern swizzle = { swizzle_data[instr.common.operand_desc_id] }; + const Instruction instr = {program_code[program_counter]}; + const SwizzlePattern swizzle = {swizzle_data[instr.common.operand_desc_id]}; - auto call = [&program_counter, &call_stack](UnitState<Debug>& state, u32 offset, u32 num_instructions, - u32 return_offset, u8 repeat_count, u8 loop_increment) { - program_counter = offset - 1; // -1 to make sure when incrementing the PC we end up at the correct offset + auto call = [&program_counter, &call_stack](UnitState<Debug>& state, u32 offset, + u32 num_instructions, u32 return_offset, + u8 repeat_count, u8 loop_increment) { + // -1 to make sure when incrementing the PC we end up at the correct offset + program_counter = offset - 1; ASSERT(call_stack.size() < call_stack.capacity()); - call_stack.push_back({ offset + num_instructions, return_offset, repeat_count, loop_increment, offset }); + call_stack.push_back( + {offset + num_instructions, return_offset, repeat_count, loop_increment, offset}); }; Record<DebugDataRecord::CUR_INSTR>(state.debug, iteration, program_counter); if (iteration > 0) @@ -106,24 +106,26 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned }; switch (instr.opcode.Value().GetInfo().type) { - case OpCode::Type::Arithmetic: - { - const bool is_inverted = (0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed)); + case OpCode::Type::Arithmetic: { + const bool is_inverted = + (0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed)); - const int address_offset = (instr.common.address_register_index == 0) - ? 0 : state.address_registers[instr.common.address_register_index - 1]; + const int address_offset = + (instr.common.address_register_index == 0) + ? 0 + : state.address_registers[instr.common.address_register_index - 1]; - const float24* src1_ = LookupSourceRegister(instr.common.GetSrc1(is_inverted) + (!is_inverted * address_offset)); - const float24* src2_ = LookupSourceRegister(instr.common.GetSrc2(is_inverted) + ( is_inverted * address_offset)); + const float24* src1_ = LookupSourceRegister(instr.common.GetSrc1(is_inverted) + + (!is_inverted * address_offset)); + const float24* src2_ = LookupSourceRegister(instr.common.GetSrc2(is_inverted) + + (is_inverted * address_offset)); const bool negate_src1 = ((bool)swizzle.negate_src1 != false); const bool negate_src2 = ((bool)swizzle.negate_src2 != false); float24 src1[4] = { - src1_[(int)swizzle.GetSelectorSrc1(0)], - src1_[(int)swizzle.GetSelectorSrc1(1)], - src1_[(int)swizzle.GetSelectorSrc1(2)], - src1_[(int)swizzle.GetSelectorSrc1(3)], + src1_[(int)swizzle.GetSelectorSrc1(0)], src1_[(int)swizzle.GetSelectorSrc1(1)], + src1_[(int)swizzle.GetSelectorSrc1(2)], src1_[(int)swizzle.GetSelectorSrc1(3)], }; if (negate_src1) { src1[0] = src1[0] * float24::FromFloat32(-1); @@ -132,10 +134,8 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned src1[3] = src1[3] * float24::FromFloat32(-1); } float24 src2[4] = { - src2_[(int)swizzle.GetSelectorSrc2(0)], - src2_[(int)swizzle.GetSelectorSrc2(1)], - src2_[(int)swizzle.GetSelectorSrc2(2)], - src2_[(int)swizzle.GetSelectorSrc2(3)], + src2_[(int)swizzle.GetSelectorSrc2(0)], src2_[(int)swizzle.GetSelectorSrc2(1)], + src2_[(int)swizzle.GetSelectorSrc2(2)], src2_[(int)swizzle.GetSelectorSrc2(3)], }; if (negate_src2) { src2[0] = src2[0] * float24::FromFloat32(-1); @@ -144,15 +144,18 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned src2[3] = src2[3] * float24::FromFloat32(-1); } - float24* dest = (instr.common.dest.Value() < 0x10) ? &state.output_registers.value[instr.common.dest.Value().GetIndex()][0] - : (instr.common.dest.Value() < 0x20) ? &state.registers.temporary[instr.common.dest.Value().GetIndex()][0] - : dummy_vec4_float24; + float24* dest = + (instr.common.dest.Value() < 0x10) + ? &state.output_registers.value[instr.common.dest.Value().GetIndex()][0] + : (instr.common.dest.Value() < 0x20) + ? &state.registers.temporary[instr.common.dest.Value().GetIndex()][0] + : dummy_vec4_float24; - state.debug.max_opdesc_id = std::max<u32>(state.debug.max_opdesc_id, 1+instr.common.operand_desc_id); + state.debug.max_opdesc_id = + std::max<u32>(state.debug.max_opdesc_id, 1 + instr.common.operand_desc_id); switch (instr.opcode.Value().EffectiveOpCode()) { - case OpCode::Id::ADD: - { + case OpCode::Id::ADD: { Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); Record<DebugDataRecord::SRC2>(state.debug, iteration, src2); Record<DebugDataRecord::DEST_IN>(state.debug, iteration, dest); @@ -166,8 +169,7 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned break; } - case OpCode::Id::MUL: - { + case OpCode::Id::MUL: { Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); Record<DebugDataRecord::SRC2>(state.debug, iteration, src2); Record<DebugDataRecord::DEST_IN>(state.debug, iteration, dest); @@ -228,8 +230,7 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned case OpCode::Id::DP3: case OpCode::Id::DP4: case OpCode::Id::DPH: - case OpCode::Id::DPHI: - { + case OpCode::Id::DPHI: { Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); Record<DebugDataRecord::SRC2>(state.debug, iteration, src2); Record<DebugDataRecord::DEST_IN>(state.debug, iteration, dest); @@ -239,7 +240,8 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned src1[3] = float24::FromFloat32(1.0f); int num_components = (opcode == OpCode::Id::DP3) ? 3 : 4; - float24 dot = std::inner_product(src1, src1 + num_components, src2, float24::FromFloat32(0.f)); + float24 dot = std::inner_product(src1, src1 + num_components, src2, + float24::FromFloat32(0.f)); for (int i = 0; i < 4; ++i) { if (!swizzle.DestComponentEnabled(i)) @@ -252,8 +254,7 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned } // Reciprocal - case OpCode::Id::RCP: - { + case OpCode::Id::RCP: { Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); Record<DebugDataRecord::DEST_IN>(state.debug, iteration, dest); float24 rcp_res = float24::FromFloat32(1.0f / src1[0].ToFloat32()); @@ -268,8 +269,7 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned } // Reciprocal Square Root - case OpCode::Id::RSQ: - { + case OpCode::Id::RSQ: { Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); Record<DebugDataRecord::DEST_IN>(state.debug, iteration, dest); float24 rsq_res = float24::FromFloat32(1.0f / std::sqrt(src1[0].ToFloat32())); @@ -283,8 +283,7 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned break; } - case OpCode::Id::MOVA: - { + case OpCode::Id::MOVA: { Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); for (int i = 0; i < 2; ++i) { if (!swizzle.DestComponentEnabled(i)) @@ -293,12 +292,12 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned // TODO: Figure out how the rounding is done on hardware state.address_registers[i] = static_cast<s32>(src1[i].ToFloat32()); } - Record<DebugDataRecord::ADDR_REG_OUT>(state.debug, iteration, state.address_registers); + Record<DebugDataRecord::ADDR_REG_OUT>(state.debug, iteration, + state.address_registers); break; } - case OpCode::Id::MOV: - { + case OpCode::Id::MOV: { Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); Record<DebugDataRecord::DEST_IN>(state.debug, iteration, dest); for (int i = 0; i < 4; ++i) { @@ -320,7 +319,8 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned if (!swizzle.DestComponentEnabled(i)) continue; - dest[i] = (src1[i] >= src2[i]) ? float24::FromFloat32(1.0f) : float24::FromFloat32(0.0f); + dest[i] = (src1[i] >= src2[i]) ? float24::FromFloat32(1.0f) + : float24::FromFloat32(0.0f); } Record<DebugDataRecord::DEST_OUT>(state.debug, iteration, dest); break; @@ -334,7 +334,8 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned if (!swizzle.DestComponentEnabled(i)) continue; - dest[i] = (src1[i] < src2[i]) ? float24::FromFloat32(1.0f) : float24::FromFloat32(0.0f); + dest[i] = (src1[i] < src2[i]) ? float24::FromFloat32(1.0f) + : float24::FromFloat32(0.0f); } Record<DebugDataRecord::DEST_OUT>(state.debug, iteration, dest); break; @@ -349,40 +350,39 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned auto op = (i == 0) ? compare_op.x.Value() : compare_op.y.Value(); switch (op) { - case Instruction::Common::CompareOpType::Equal: - state.conditional_code[i] = (src1[i] == src2[i]); - break; + case Instruction::Common::CompareOpType::Equal: + state.conditional_code[i] = (src1[i] == src2[i]); + break; - case Instruction::Common::CompareOpType::NotEqual: - state.conditional_code[i] = (src1[i] != src2[i]); - break; + case Instruction::Common::CompareOpType::NotEqual: + state.conditional_code[i] = (src1[i] != src2[i]); + break; - case Instruction::Common::CompareOpType::LessThan: - state.conditional_code[i] = (src1[i] < src2[i]); - break; + case Instruction::Common::CompareOpType::LessThan: + state.conditional_code[i] = (src1[i] < src2[i]); + break; - case Instruction::Common::CompareOpType::LessEqual: - state.conditional_code[i] = (src1[i] <= src2[i]); - break; + case Instruction::Common::CompareOpType::LessEqual: + state.conditional_code[i] = (src1[i] <= src2[i]); + break; - case Instruction::Common::CompareOpType::GreaterThan: - state.conditional_code[i] = (src1[i] > src2[i]); - break; + case Instruction::Common::CompareOpType::GreaterThan: + state.conditional_code[i] = (src1[i] > src2[i]); + break; - case Instruction::Common::CompareOpType::GreaterEqual: - state.conditional_code[i] = (src1[i] >= src2[i]); - break; + case Instruction::Common::CompareOpType::GreaterEqual: + state.conditional_code[i] = (src1[i] >= src2[i]); + break; - default: - LOG_ERROR(HW_GPU, "Unknown compare mode %x", static_cast<int>(op)); - break; + default: + LOG_ERROR(HW_GPU, "Unknown compare mode %x", static_cast<int>(op)); + break; } } Record<DebugDataRecord::CMP_RESULT>(state.debug, iteration, state.conditional_code); break; - case OpCode::Id::EX2: - { + case OpCode::Id::EX2: { Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); Record<DebugDataRecord::DEST_IN>(state.debug, iteration, dest); @@ -399,8 +399,7 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned break; } - case OpCode::Id::LG2: - { + case OpCode::Id::LG2: { Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); Record<DebugDataRecord::DEST_IN>(state.debug, iteration, dest); @@ -419,7 +418,8 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned default: LOG_ERROR(HW_GPU, "Unhandled arithmetic instruction: 0x%02x (%s): 0x%08x", - (int)instr.opcode.Value().EffectiveOpCode(), instr.opcode.Value().GetInfo().name, instr.hex); + (int)instr.opcode.Value().EffectiveOpCode(), + instr.opcode.Value().GetInfo().name, instr.hex); DEBUG_ASSERT(false); break; } @@ -427,30 +427,32 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned break; } - case OpCode::Type::MultiplyAdd: - { + case OpCode::Type::MultiplyAdd: { if ((instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD) || (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI)) { - const SwizzlePattern& swizzle = *reinterpret_cast<const SwizzlePattern*>(&swizzle_data[instr.mad.operand_desc_id]); + const SwizzlePattern& swizzle = *reinterpret_cast<const SwizzlePattern*>( + &swizzle_data[instr.mad.operand_desc_id]); bool is_inverted = (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MADI); - const int address_offset = (instr.mad.address_register_index == 0) - ? 0 : state.address_registers[instr.mad.address_register_index - 1]; + const int address_offset = + (instr.mad.address_register_index == 0) + ? 0 + : state.address_registers[instr.mad.address_register_index - 1]; const float24* src1_ = LookupSourceRegister(instr.mad.GetSrc1(is_inverted)); - const float24* src2_ = LookupSourceRegister(instr.mad.GetSrc2(is_inverted) + (!is_inverted * address_offset)); - const float24* src3_ = LookupSourceRegister(instr.mad.GetSrc3(is_inverted) + ( is_inverted * address_offset)); + const float24* src2_ = LookupSourceRegister(instr.mad.GetSrc2(is_inverted) + + (!is_inverted * address_offset)); + const float24* src3_ = LookupSourceRegister(instr.mad.GetSrc3(is_inverted) + + (is_inverted * address_offset)); const bool negate_src1 = ((bool)swizzle.negate_src1 != false); const bool negate_src2 = ((bool)swizzle.negate_src2 != false); const bool negate_src3 = ((bool)swizzle.negate_src3 != false); float24 src1[4] = { - src1_[(int)swizzle.GetSelectorSrc1(0)], - src1_[(int)swizzle.GetSelectorSrc1(1)], - src1_[(int)swizzle.GetSelectorSrc1(2)], - src1_[(int)swizzle.GetSelectorSrc1(3)], + src1_[(int)swizzle.GetSelectorSrc1(0)], src1_[(int)swizzle.GetSelectorSrc1(1)], + src1_[(int)swizzle.GetSelectorSrc1(2)], src1_[(int)swizzle.GetSelectorSrc1(3)], }; if (negate_src1) { src1[0] = src1[0] * float24::FromFloat32(-1); @@ -459,10 +461,8 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned src1[3] = src1[3] * float24::FromFloat32(-1); } float24 src2[4] = { - src2_[(int)swizzle.GetSelectorSrc2(0)], - src2_[(int)swizzle.GetSelectorSrc2(1)], - src2_[(int)swizzle.GetSelectorSrc2(2)], - src2_[(int)swizzle.GetSelectorSrc2(3)], + src2_[(int)swizzle.GetSelectorSrc2(0)], src2_[(int)swizzle.GetSelectorSrc2(1)], + src2_[(int)swizzle.GetSelectorSrc2(2)], src2_[(int)swizzle.GetSelectorSrc2(3)], }; if (negate_src2) { src2[0] = src2[0] * float24::FromFloat32(-1); @@ -471,10 +471,8 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned src2[3] = src2[3] * float24::FromFloat32(-1); } float24 src3[4] = { - src3_[(int)swizzle.GetSelectorSrc3(0)], - src3_[(int)swizzle.GetSelectorSrc3(1)], - src3_[(int)swizzle.GetSelectorSrc3(2)], - src3_[(int)swizzle.GetSelectorSrc3(3)], + src3_[(int)swizzle.GetSelectorSrc3(0)], src3_[(int)swizzle.GetSelectorSrc3(1)], + src3_[(int)swizzle.GetSelectorSrc3(2)], src3_[(int)swizzle.GetSelectorSrc3(3)], }; if (negate_src3) { src3[0] = src3[0] * float24::FromFloat32(-1); @@ -483,9 +481,12 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned src3[3] = src3[3] * float24::FromFloat32(-1); } - float24* dest = (instr.mad.dest.Value() < 0x10) ? &state.output_registers.value[instr.mad.dest.Value().GetIndex()][0] - : (instr.mad.dest.Value() < 0x20) ? &state.registers.temporary[instr.mad.dest.Value().GetIndex()][0] - : dummy_vec4_float24; + float24* dest = + (instr.mad.dest.Value() < 0x10) + ? &state.output_registers.value[instr.mad.dest.Value().GetIndex()][0] + : (instr.mad.dest.Value() < 0x20) + ? &state.registers.temporary[instr.mad.dest.Value().GetIndex()][0] + : dummy_vec4_float24; Record<DebugDataRecord::SRC1>(state.debug, iteration, src1); Record<DebugDataRecord::SRC2>(state.debug, iteration, src2); @@ -500,16 +501,17 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned Record<DebugDataRecord::DEST_OUT>(state.debug, iteration, dest); } else { LOG_ERROR(HW_GPU, "Unhandled multiply-add instruction: 0x%02x (%s): 0x%08x", - (int)instr.opcode.Value().EffectiveOpCode(), instr.opcode.Value().GetInfo().name, instr.hex); + (int)instr.opcode.Value().EffectiveOpCode(), + instr.opcode.Value().GetInfo().name, instr.hex); } break; } - default: - { - static auto evaluate_condition = [](const UnitState<Debug>& state, bool refx, bool refy, Instruction::FlowControlType flow_control) { - bool results[2] = { refx == state.conditional_code[0], - refy == state.conditional_code[1] }; + default: { + static auto evaluate_condition = [](const UnitState<Debug>& state, bool refx, bool refy, + Instruction::FlowControlType flow_control) { + bool results[2] = {refx == state.conditional_code[0], + refy == state.conditional_code[1]}; switch (flow_control.op) { case flow_control.Or: @@ -533,44 +535,45 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned break; case OpCode::Id::JMPC: - Record<DebugDataRecord::COND_CMP_IN>(state.debug, iteration, state.conditional_code); - if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) { + Record<DebugDataRecord::COND_CMP_IN>(state.debug, iteration, + state.conditional_code); + if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, + instr.flow_control)) { program_counter = instr.flow_control.dest_offset - 1; } break; case OpCode::Id::JMPU: - Record<DebugDataRecord::COND_BOOL_IN>(state.debug, iteration, uniforms.b[instr.flow_control.bool_uniform_id]); + Record<DebugDataRecord::COND_BOOL_IN>( + state.debug, iteration, uniforms.b[instr.flow_control.bool_uniform_id]); - if (uniforms.b[instr.flow_control.bool_uniform_id] == !(instr.flow_control.num_instructions & 1)) { + if (uniforms.b[instr.flow_control.bool_uniform_id] == + !(instr.flow_control.num_instructions & 1)) { program_counter = instr.flow_control.dest_offset - 1; } break; case OpCode::Id::CALL: - call(state, - instr.flow_control.dest_offset, - instr.flow_control.num_instructions, + call(state, instr.flow_control.dest_offset, instr.flow_control.num_instructions, program_counter + 1, 0, 0); break; case OpCode::Id::CALLU: - Record<DebugDataRecord::COND_BOOL_IN>(state.debug, iteration, uniforms.b[instr.flow_control.bool_uniform_id]); + Record<DebugDataRecord::COND_BOOL_IN>( + state.debug, iteration, uniforms.b[instr.flow_control.bool_uniform_id]); if (uniforms.b[instr.flow_control.bool_uniform_id]) { - call(state, - instr.flow_control.dest_offset, - instr.flow_control.num_instructions, - program_counter + 1, 0, 0); + call(state, instr.flow_control.dest_offset, instr.flow_control.num_instructions, + program_counter + 1, 0, 0); } break; case OpCode::Id::CALLC: - Record<DebugDataRecord::COND_CMP_IN>(state.debug, iteration, state.conditional_code); - if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) { - call(state, - instr.flow_control.dest_offset, - instr.flow_control.num_instructions, - program_counter + 1, 0, 0); + Record<DebugDataRecord::COND_CMP_IN>(state.debug, iteration, + state.conditional_code); + if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, + instr.flow_control)) { + call(state, instr.flow_control.dest_offset, instr.flow_control.num_instructions, + program_counter + 1, 0, 0); } break; @@ -578,43 +581,42 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned break; case OpCode::Id::IFU: - Record<DebugDataRecord::COND_BOOL_IN>(state.debug, iteration, uniforms.b[instr.flow_control.bool_uniform_id]); + Record<DebugDataRecord::COND_BOOL_IN>( + state.debug, iteration, uniforms.b[instr.flow_control.bool_uniform_id]); if (uniforms.b[instr.flow_control.bool_uniform_id]) { - call(state, - program_counter + 1, + call(state, program_counter + 1, instr.flow_control.dest_offset - program_counter - 1, - instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, 0); + instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, + 0); } else { - call(state, - instr.flow_control.dest_offset, - instr.flow_control.num_instructions, - instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, 0); + call(state, instr.flow_control.dest_offset, instr.flow_control.num_instructions, + instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, + 0); } break; - case OpCode::Id::IFC: - { + case OpCode::Id::IFC: { // TODO: Do we need to consider swizzlers here? - Record<DebugDataRecord::COND_CMP_IN>(state.debug, iteration, state.conditional_code); - if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, instr.flow_control)) { - call(state, - program_counter + 1, + Record<DebugDataRecord::COND_CMP_IN>(state.debug, iteration, + state.conditional_code); + if (evaluate_condition(state, instr.flow_control.refx, instr.flow_control.refy, + instr.flow_control)) { + call(state, program_counter + 1, instr.flow_control.dest_offset - program_counter - 1, - instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, 0); + instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, + 0); } else { - call(state, - instr.flow_control.dest_offset, - instr.flow_control.num_instructions, - instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, 0); + call(state, instr.flow_control.dest_offset, instr.flow_control.num_instructions, + instr.flow_control.dest_offset + instr.flow_control.num_instructions, 0, + 0); } break; } - case OpCode::Id::LOOP: - { + case OpCode::Id::LOOP: { Math::Vec4<u8> loop_param(uniforms.i[instr.flow_control.int_uniform_id].x, uniforms.i[instr.flow_control.int_uniform_id].y, uniforms.i[instr.flow_control.int_uniform_id].z, @@ -622,18 +624,16 @@ void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned state.address_registers[2] = loop_param.y; Record<DebugDataRecord::LOOP_INT_IN>(state.debug, iteration, loop_param); - call(state, - program_counter + 1, + call(state, program_counter + 1, instr.flow_control.dest_offset - program_counter + 1, - instr.flow_control.dest_offset + 1, - loop_param.x, - loop_param.z); + instr.flow_control.dest_offset + 1, loop_param.x, loop_param.z); break; } default: LOG_ERROR(HW_GPU, "Unhandled instruction: 0x%02x (%s): 0x%08x", - (int)instr.opcode.Value().EffectiveOpCode(), instr.opcode.Value().GetInfo().name, instr.hex); + (int)instr.opcode.Value().EffectiveOpCode(), + instr.opcode.Value().GetInfo().name, instr.hex); break; } diff --git a/src/video_core/shader/shader_interpreter.h b/src/video_core/shader/shader_interpreter.h index bb3ce1c6e..48ede0a2e 100644 --- a/src/video_core/shader/shader_interpreter.h +++ b/src/video_core/shader/shader_interpreter.h @@ -8,9 +8,10 @@ namespace Pica { namespace Shader { -template <bool Debug> struct UnitState; +template <bool Debug> +struct UnitState; -template<bool Debug> +template <bool Debug> void RunInterpreter(const ShaderSetup& setup, UnitState<Debug>& state, unsigned offset); } // namespace diff --git a/src/video_core/shader/shader_jit_x64.cpp b/src/video_core/shader/shader_jit_x64.cpp index 43e7e6b4c..211c703ab 100644 --- a/src/video_core/shader/shader_jit_x64.cpp +++ b/src/video_core/shader/shader_jit_x64.cpp @@ -5,20 +5,16 @@ #include <algorithm> #include <cmath> #include <cstdint> -#include <xmmintrin.h> - #include <nihstro/shader_bytecode.h> - +#include <xmmintrin.h> #include "common/assert.h" #include "common/logging/log.h" #include "common/vector_math.h" #include "common/x64/abi.h" #include "common/x64/cpu_detect.h" #include "common/x64/emitter.h" - #include "shader.h" #include "shader_jit_x64.h" - #include "video_core/pica_state.h" #include "video_core/pica_types.h" @@ -31,70 +27,70 @@ using namespace Gen; typedef void (JitShader::*JitFunction)(Instruction instr); const JitFunction instr_table[64] = { - &JitShader::Compile_ADD, // add - &JitShader::Compile_DP3, // dp3 - &JitShader::Compile_DP4, // dp4 - &JitShader::Compile_DPH, // dph - nullptr, // unknown - &JitShader::Compile_EX2, // ex2 - &JitShader::Compile_LG2, // lg2 - nullptr, // unknown - &JitShader::Compile_MUL, // mul - &JitShader::Compile_SGE, // sge - &JitShader::Compile_SLT, // slt - &JitShader::Compile_FLR, // flr - &JitShader::Compile_MAX, // max - &JitShader::Compile_MIN, // min - &JitShader::Compile_RCP, // rcp - &JitShader::Compile_RSQ, // rsq - nullptr, // unknown - nullptr, // unknown - &JitShader::Compile_MOVA, // mova - &JitShader::Compile_MOV, // mov - nullptr, // unknown - nullptr, // unknown - nullptr, // unknown - nullptr, // unknown - &JitShader::Compile_DPH, // dphi - nullptr, // unknown - &JitShader::Compile_SGE, // sgei - &JitShader::Compile_SLT, // slti - nullptr, // unknown - nullptr, // unknown - nullptr, // unknown - nullptr, // unknown - nullptr, // unknown - &JitShader::Compile_NOP, // nop - &JitShader::Compile_END, // end - nullptr, // break - &JitShader::Compile_CALL, // call - &JitShader::Compile_CALLC, // callc - &JitShader::Compile_CALLU, // callu - &JitShader::Compile_IF, // ifu - &JitShader::Compile_IF, // ifc - &JitShader::Compile_LOOP, // loop - nullptr, // emit - nullptr, // sete - &JitShader::Compile_JMP, // jmpc - &JitShader::Compile_JMP, // jmpu - &JitShader::Compile_CMP, // cmp - &JitShader::Compile_CMP, // cmp - &JitShader::Compile_MAD, // madi - &JitShader::Compile_MAD, // madi - &JitShader::Compile_MAD, // madi - &JitShader::Compile_MAD, // madi - &JitShader::Compile_MAD, // madi - &JitShader::Compile_MAD, // madi - &JitShader::Compile_MAD, // madi - &JitShader::Compile_MAD, // madi - &JitShader::Compile_MAD, // mad - &JitShader::Compile_MAD, // mad - &JitShader::Compile_MAD, // mad - &JitShader::Compile_MAD, // mad - &JitShader::Compile_MAD, // mad - &JitShader::Compile_MAD, // mad - &JitShader::Compile_MAD, // mad - &JitShader::Compile_MAD, // mad + &JitShader::Compile_ADD, // add + &JitShader::Compile_DP3, // dp3 + &JitShader::Compile_DP4, // dp4 + &JitShader::Compile_DPH, // dph + nullptr, // unknown + &JitShader::Compile_EX2, // ex2 + &JitShader::Compile_LG2, // lg2 + nullptr, // unknown + &JitShader::Compile_MUL, // mul + &JitShader::Compile_SGE, // sge + &JitShader::Compile_SLT, // slt + &JitShader::Compile_FLR, // flr + &JitShader::Compile_MAX, // max + &JitShader::Compile_MIN, // min + &JitShader::Compile_RCP, // rcp + &JitShader::Compile_RSQ, // rsq + nullptr, // unknown + nullptr, // unknown + &JitShader::Compile_MOVA, // mova + &JitShader::Compile_MOV, // mov + nullptr, // unknown + nullptr, // unknown + nullptr, // unknown + nullptr, // unknown + &JitShader::Compile_DPH, // dphi + nullptr, // unknown + &JitShader::Compile_SGE, // sgei + &JitShader::Compile_SLT, // slti + nullptr, // unknown + nullptr, // unknown + nullptr, // unknown + nullptr, // unknown + nullptr, // unknown + &JitShader::Compile_NOP, // nop + &JitShader::Compile_END, // end + nullptr, // break + &JitShader::Compile_CALL, // call + &JitShader::Compile_CALLC, // callc + &JitShader::Compile_CALLU, // callu + &JitShader::Compile_IF, // ifu + &JitShader::Compile_IF, // ifc + &JitShader::Compile_LOOP, // loop + nullptr, // emit + nullptr, // sete + &JitShader::Compile_JMP, // jmpc + &JitShader::Compile_JMP, // jmpu + &JitShader::Compile_CMP, // cmp + &JitShader::Compile_CMP, // cmp + &JitShader::Compile_MAD, // madi + &JitShader::Compile_MAD, // madi + &JitShader::Compile_MAD, // madi + &JitShader::Compile_MAD, // madi + &JitShader::Compile_MAD, // madi + &JitShader::Compile_MAD, // madi + &JitShader::Compile_MAD, // madi + &JitShader::Compile_MAD, // madi + &JitShader::Compile_MAD, // mad + &JitShader::Compile_MAD, // mad + &JitShader::Compile_MAD, // mad + &JitShader::Compile_MAD, // mad + &JitShader::Compile_MAD, // mad + &JitShader::Compile_MAD, // mad + &JitShader::Compile_MAD, // mad + &JitShader::Compile_MAD, // mad }; // The following is used to alias some commonly used registers. Generally, RAX-RDX and XMM0-XMM3 can @@ -136,9 +132,9 @@ static const X64Reg NEGBIT = XMM15; // State registers that must not be modified by external functions calls // Scratch registers, e.g., SRC1 and SCRATCH, have to be saved on the side if needed static const BitSet32 persistent_regs = { - SETUP, STATE, // Pointers to register blocks + SETUP, STATE, // Pointers to register blocks ADDROFFS_REG_0, ADDROFFS_REG_1, LOOPCOUNT_REG, COND0, COND1, // Cached registers - ONE+16, NEGBIT+16, // Constants + ONE + 16, NEGBIT + 16, // Constants }; /// Raw constant for the source register selector that indicates no swizzling is performed @@ -152,7 +148,7 @@ static const u8 NO_DEST_REG_MASK = 0xf; * @return Instruction at the specified offset */ static Instruction GetVertexShaderInstruction(size_t offset) { - return { g_state.vs.program_code[offset] }; + return {g_state.vs.program_code[offset]}; } static void LogCritical(const char* msg) { @@ -172,7 +168,8 @@ void JitShader::Compile_Assert(bool condition, const char* msg) { * @param src_reg SourceRegister object corresponding to the source register to load * @param dest Destination XMM register to store the loaded, swizzled source register */ -void JitShader::Compile_SwizzleSrc(Instruction instr, unsigned src_num, SourceRegister src_reg, X64Reg dest) { +void JitShader::Compile_SwizzleSrc(Instruction instr, unsigned src_num, SourceRegister src_reg, + X64Reg dest) { X64Reg src_ptr; size_t src_offset; @@ -189,7 +186,8 @@ void JitShader::Compile_SwizzleSrc(Instruction instr, unsigned src_num, SourceRe unsigned operand_desc_id; - const bool is_inverted = (0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed)); + const bool is_inverted = + (0 != (instr.opcode.Value().GetInfo().subtype & OpCode::Info::SrcInversed)); unsigned address_register_index; unsigned offset_src; @@ -225,7 +223,7 @@ void JitShader::Compile_SwizzleSrc(Instruction instr, unsigned src_num, SourceRe MOVAPS(dest, MDisp(src_ptr, src_offset_disp)); } - SwizzlePattern swiz = { g_state.vs.swizzle_data[operand_desc_id] }; + SwizzlePattern swiz = {g_state.vs.swizzle_data[operand_desc_id]}; // Generate instructions for source register swizzling as needed u8 sel = swiz.GetRawSelector(src_num); @@ -238,13 +236,13 @@ void JitShader::Compile_SwizzleSrc(Instruction instr, unsigned src_num, SourceRe } // If the source register should be negated, flip the negative bit using XOR - const bool negate[] = { swiz.negate_src1, swiz.negate_src2, swiz.negate_src3 }; + const bool negate[] = {swiz.negate_src1, swiz.negate_src2, swiz.negate_src3}; if (negate[src_num - 1]) { XORPS(dest, R(NEGBIT)); } } -void JitShader::Compile_DestEnable(Instruction instr,X64Reg src) { +void JitShader::Compile_DestEnable(Instruction instr, X64Reg src) { DestRegister dest; unsigned operand_desc_id; if (instr.opcode.Value().EffectiveOpCode() == OpCode::Id::MAD || @@ -256,10 +254,11 @@ void JitShader::Compile_DestEnable(Instruction instr,X64Reg src) { dest = instr.common.dest.Value(); } - SwizzlePattern swiz = { g_state.vs.swizzle_data[operand_desc_id] }; + SwizzlePattern swiz = {g_state.vs.swizzle_data[operand_desc_id]}; int dest_offset_disp = (int)UnitState<false>::OutputOffset(dest); - ASSERT_MSG(dest_offset_disp == UnitState<false>::OutputOffset(dest), "Destinaton offset too large for int type"); + ASSERT_MSG(dest_offset_disp == UnitState<false>::OutputOffset(dest), + "Destinaton offset too large for int type"); // If all components are enabled, write the result to the destination register if (swiz.dest_mask == NO_DEST_REG_MASK) { @@ -267,18 +266,21 @@ void JitShader::Compile_DestEnable(Instruction instr,X64Reg src) { MOVAPS(MDisp(STATE, dest_offset_disp), src); } else { - // Not all components are enabled, so mask the result when storing to the destination register... + // Not all components are enabled, so mask the result when storing to the destination + // register... MOVAPS(SCRATCH, MDisp(STATE, dest_offset_disp)); if (Common::GetCPUCaps().sse4_1) { - u8 mask = ((swiz.dest_mask & 1) << 3) | ((swiz.dest_mask & 8) >> 3) | ((swiz.dest_mask & 2) << 1) | ((swiz.dest_mask & 4) >> 1); + u8 mask = ((swiz.dest_mask & 1) << 3) | ((swiz.dest_mask & 8) >> 3) | + ((swiz.dest_mask & 2) << 1) | ((swiz.dest_mask & 4) >> 1); BLENDPS(SCRATCH, R(src), mask); } else { MOVAPS(SCRATCH2, R(src)); UNPCKHPS(SCRATCH2, R(SCRATCH)); // Unpack X/Y components of source and destination - UNPCKLPS(SCRATCH, R(src)); // Unpack Z/W components of source and destination + UNPCKLPS(SCRATCH, R(src)); // Unpack Z/W components of source and destination - // Compute selector to selectively copy source components to destination for SHUFPS instruction + // Compute selector to selectively copy source components to destination for SHUFPS + // instruction u8 sel = ((swiz.DestComponentEnabled(0) ? 1 : 0) << 0) | ((swiz.DestComponentEnabled(1) ? 3 : 2) << 2) | ((swiz.DestComponentEnabled(2) ? 0 : 1) << 4) | @@ -336,7 +338,8 @@ void JitShader::Compile_EvaluateCondition(Instruction instr) { } void JitShader::Compile_UniformCondition(Instruction instr) { - int offset = ShaderSetup::UniformOffset(RegisterType::BoolUniform, instr.flow_control.bool_uniform_id); + int offset = + ShaderSetup::UniformOffset(RegisterType::BoolUniform, instr.flow_control.bool_uniform_id); CMP(sizeof(bool) * 8, MDisp(SETUP, offset), Imm8(0)); } @@ -512,7 +515,7 @@ void JitShader::Compile_MIN(Instruction instr) { } void JitShader::Compile_MOVA(Instruction instr) { - SwizzlePattern swiz = { g_state.vs.swizzle_data[instr.common.operand_desc_id] }; + SwizzlePattern swiz = {g_state.vs.swizzle_data[instr.common.operand_desc_id]}; if (!swiz.DestComponentEnabled(0) && !swiz.DestComponentEnabled(1)) { return; // NoOp @@ -583,8 +586,7 @@ void JitShader::Compile_RSQ(Instruction instr) { Compile_DestEnable(instr, SRC1); } -void JitShader::Compile_NOP(Instruction instr) { -} +void JitShader::Compile_NOP(Instruction instr) {} void JitShader::Compile_END(Instruction instr) { ABI_PopRegistersAndAdjustStack(ABI_ALL_CALLEE_SAVED, 8); @@ -597,7 +599,7 @@ void JitShader::Compile_CALL(Instruction instr) { // Call the subroutine FixupBranch b = CALL(); - fixup_branches.push_back({ b, instr.flow_control.dest_offset }); + fixup_branches.push_back({b, instr.flow_control.dest_offset}); // Skip over the return offset that's on the stack ADD(64, R(RSP), Imm32(8)); @@ -628,7 +630,7 @@ void JitShader::Compile_CMP(Instruction instr) { // SSE doesn't have greater-than (GT) or greater-equal (GE) comparison operators. You need to // emulate them by swapping the lhs and rhs and using LT and LE. NLT and NLE can't be used here // because they don't match when used with NaNs. - static const u8 cmp[] = { CMP_EQ, CMP_NEQ, CMP_LT, CMP_LE, CMP_LT, CMP_LE }; + static const u8 cmp[] = {CMP_EQ, CMP_NEQ, CMP_LT, CMP_LE, CMP_LT, CMP_LE}; bool invert_op_x = (op_x == Op::GreaterThan || op_x == Op::GreaterEqual); Gen::X64Reg lhs_x = invert_op_x ? SRC2 : SRC1; @@ -678,7 +680,8 @@ void JitShader::Compile_MAD(Instruction instr) { } void JitShader::Compile_IF(Instruction instr) { - Compile_Assert(instr.flow_control.dest_offset >= program_counter, "Backwards if-statements not supported"); + Compile_Assert(instr.flow_control.dest_offset >= program_counter, + "Backwards if-statements not supported"); // Evaluate the "IF" condition if (instr.opcode.Value() == OpCode::Id::IFU) { @@ -709,29 +712,31 @@ void JitShader::Compile_IF(Instruction instr) { } void JitShader::Compile_LOOP(Instruction instr) { - Compile_Assert(instr.flow_control.dest_offset >= program_counter, "Backwards loops not supported"); + Compile_Assert(instr.flow_control.dest_offset >= program_counter, + "Backwards loops not supported"); Compile_Assert(!looping, "Nested loops not supported"); looping = true; - int offset = ShaderSetup::UniformOffset(RegisterType::IntUniform, instr.flow_control.int_uniform_id); + int offset = + ShaderSetup::UniformOffset(RegisterType::IntUniform, instr.flow_control.int_uniform_id); MOV(32, R(LOOPCOUNT), MDisp(SETUP, offset)); MOV(32, R(LOOPCOUNT_REG), R(LOOPCOUNT)); SHR(32, R(LOOPCOUNT_REG), Imm8(8)); AND(32, R(LOOPCOUNT_REG), Imm32(0xff)); // Y-component is the start MOV(32, R(LOOPINC), R(LOOPCOUNT)); SHR(32, R(LOOPINC), Imm8(16)); - MOVZX(32, 8, LOOPINC, R(LOOPINC)); // Z-component is the incrementer + MOVZX(32, 8, LOOPINC, R(LOOPINC)); // Z-component is the incrementer MOVZX(32, 8, LOOPCOUNT, R(LOOPCOUNT)); // X-component is iteration count - ADD(32, R(LOOPCOUNT), Imm8(1)); // Iteration count is X-component + 1 + ADD(32, R(LOOPCOUNT), Imm8(1)); // Iteration count is X-component + 1 auto loop_start = GetCodePtr(); Compile_Block(instr.flow_control.dest_offset + 1); ADD(32, R(LOOPCOUNT_REG), R(LOOPINC)); // Increment LOOPCOUNT_REG by Z-component - SUB(32, R(LOOPCOUNT), Imm8(1)); // Increment loop count by 1 - J_CC(CC_NZ, loop_start); // Loop if not equal + SUB(32, R(LOOPCOUNT), Imm8(1)); // Increment loop count by 1 + J_CC(CC_NZ, loop_start); // Loop if not equal looping = false; } @@ -744,11 +749,11 @@ void JitShader::Compile_JMP(Instruction instr) { else UNREACHABLE(); - bool inverted_condition = (instr.opcode.Value() == OpCode::Id::JMPU) && - (instr.flow_control.num_instructions & 1); + bool inverted_condition = + (instr.opcode.Value() == OpCode::Id::JMPU) && (instr.flow_control.num_instructions & 1); FixupBranch b = J_CC(inverted_condition ? CC_Z : CC_NZ, true); - fixup_branches.push_back({ b, instr.flow_control.dest_offset }); + fixup_branches.push_back({b, instr.flow_control.dest_offset}); } void JitShader::Compile_Block(unsigned end) { @@ -773,7 +778,8 @@ void JitShader::Compile_NextInstr() { Compile_Return(); } - ASSERT_MSG(code_ptr[program_counter] == nullptr, "Tried to compile already compiled shader location!"); + ASSERT_MSG(code_ptr[program_counter] == nullptr, + "Tried to compile already compiled shader location!"); code_ptr[program_counter] = GetCodePtr(); Instruction instr = GetVertexShaderInstruction(program_counter++); @@ -787,7 +793,7 @@ void JitShader::Compile_NextInstr() { } else { // Unhandled instruction LOG_CRITICAL(HW_GPU, "Unhandled instruction: 0x%02x (0x%08x)", - instr.opcode.Value().EffectiveOpCode(), instr.hex); + instr.opcode.Value().EffectiveOpCode(), instr.hex); } } @@ -801,7 +807,8 @@ void JitShader::FindReturnOffsets() { case OpCode::Id::CALL: case OpCode::Id::CALLC: case OpCode::Id::CALLU: - return_offsets.push_back(instr.flow_control.dest_offset + instr.flow_control.num_instructions); + return_offsets.push_back(instr.flow_control.dest_offset + + instr.flow_control.num_instructions); break; default: break; @@ -835,12 +842,12 @@ void JitShader::Compile() { XOR(64, R(LOOPCOUNT_REG), R(LOOPCOUNT_REG)); // Used to set a register to one - static const __m128 one = { 1.f, 1.f, 1.f, 1.f }; + static const __m128 one = {1.f, 1.f, 1.f, 1.f}; MOV(PTRBITS, R(RAX), ImmPtr(&one)); MOVAPS(ONE, MatR(RAX)); // Used to negate registers - static const __m128 neg = { -0.f, -0.f, -0.f, -0.f }; + static const __m128 neg = {-0.f, -0.f, -0.f, -0.f}; MOV(PTRBITS, R(RAX), ImmPtr(&neg)); MOVAPS(NEGBIT, MatR(RAX)); @@ -850,7 +857,8 @@ void JitShader::Compile() { // Compile entire program Compile_Block(static_cast<unsigned>(g_state.vs.program_code.size())); - // Set the target for any incomplete branches now that the entire shader program has been emitted + // Set the target for any incomplete branches now that the entire shader program has been + // emitted for (const auto& branch : fixup_branches) { SetJumpTarget(branch.first, code_ptr[branch.second]); } @@ -861,7 +869,8 @@ void JitShader::Compile() { fixup_branches.clear(); fixup_branches.shrink_to_fit(); - uintptr_t size = reinterpret_cast<uintptr_t>(GetCodePtr()) - reinterpret_cast<uintptr_t>(program); + uintptr_t size = + reinterpret_cast<uintptr_t>(GetCodePtr()) - reinterpret_cast<uintptr_t>(program); ASSERT_MSG(size <= MAX_SHADER_SIZE, "Compiled a shader that exceeds the allocated size!"); LOG_DEBUG(HW_GPU, "Compiled shader size=%lu", size); diff --git a/src/video_core/shader/shader_jit_x64.h b/src/video_core/shader/shader_jit_x64.h index 5468459d4..98de5ecef 100644 --- a/src/video_core/shader/shader_jit_x64.h +++ b/src/video_core/shader/shader_jit_x64.h @@ -8,13 +8,10 @@ #include <cstddef> #include <utility> #include <vector> - #include <nihstro/shader_bytecode.h> - #include "common/bit_set.h" #include "common/common_types.h" #include "common/x64/emitter.h" - #include "video_core/shader/shader.h" using nihstro::Instruction; @@ -70,11 +67,11 @@ public: void Compile_MAD(Instruction instr); private: - void Compile_Block(unsigned end); void Compile_NextInstr(); - void Compile_SwizzleSrc(Instruction instr, unsigned src_num, SourceRegister src_reg, Gen::X64Reg dest); + void Compile_SwizzleSrc(Instruction instr, unsigned src_num, SourceRegister src_reg, + Gen::X64Reg dest); void Compile_DestEnable(Instruction instr, Gen::X64Reg dest); /** @@ -111,8 +108,8 @@ private: /// Offsets in code where a return needs to be inserted std::vector<unsigned> return_offsets; - unsigned program_counter = 0; ///< Offset of the next instruction to decode - bool looping = false; ///< True if compiling a loop, used to check for nested loops + unsigned program_counter = 0; ///< Offset of the next instruction to decode + bool looping = false; ///< True if compiling a loop, used to check for nested loops /// Branches that need to be fixed up once the entire shader program is compiled std::vector<std::pair<Gen::FixupBranch, unsigned>> fixup_branches; diff --git a/src/video_core/swrasterizer.cpp b/src/video_core/swrasterizer.cpp index 03df15b01..9cd21f72b 100644 --- a/src/video_core/swrasterizer.cpp +++ b/src/video_core/swrasterizer.cpp @@ -8,9 +8,8 @@ namespace VideoCore { void SWRasterizer::AddTriangle(const Pica::Shader::OutputVertex& v0, - const Pica::Shader::OutputVertex& v1, - const Pica::Shader::OutputVertex& v2) { + const Pica::Shader::OutputVertex& v1, + const Pica::Shader::OutputVertex& v2) { Pica::Clipper::ProcessTriangle(v0, v1, v2); } - } diff --git a/src/video_core/swrasterizer.h b/src/video_core/swrasterizer.h index 0a028b774..6d42d7409 100644 --- a/src/video_core/swrasterizer.h +++ b/src/video_core/swrasterizer.h @@ -5,7 +5,6 @@ #pragma once #include "common/common_types.h" - #include "video_core/rasterizer_interface.h" namespace Pica { @@ -17,14 +16,12 @@ struct OutputVertex; namespace VideoCore { class SWRasterizer : public RasterizerInterface { - void AddTriangle(const Pica::Shader::OutputVertex& v0, - const Pica::Shader::OutputVertex& v1, - const Pica::Shader::OutputVertex& v2) override; + void AddTriangle(const Pica::Shader::OutputVertex& v0, const Pica::Shader::OutputVertex& v1, + const Pica::Shader::OutputVertex& v2) override; void DrawTriangles() override {} void NotifyPicaRegisterChanged(u32 id) override {} void FlushAll() override {} void FlushRegion(PAddr addr, u32 size) override {} void FlushAndInvalidateRegion(PAddr addr, u32 size) override {} }; - } diff --git a/src/video_core/vertex_loader.cpp b/src/video_core/vertex_loader.cpp index e40f0f1ee..2b8ef7018 100644 --- a/src/video_core/vertex_loader.cpp +++ b/src/video_core/vertex_loader.cpp @@ -1,16 +1,12 @@ #include <memory> - #include <boost/range/algorithm/fill.hpp> - #include "common/alignment.h" #include "common/assert.h" #include "common/bit_field.h" #include "common/common_types.h" #include "common/logging/log.h" #include "common/vector_math.h" - #include "core/memory.h" - #include "video_core/debug_utils/debug_utils.h" #include "video_core/pica.h" #include "video_core/pica_state.h" @@ -41,24 +37,32 @@ void VertexLoader::Setup(const Pica::Regs& regs) { // TODO: What happens if a loader overwrites a previous one's data? for (unsigned component = 0; component < loader_config.component_count; ++component) { if (component >= 12) { - LOG_ERROR(HW_GPU, "Overflow in the vertex attribute loader %u trying to load component %u", loader, component); + LOG_ERROR(HW_GPU, + "Overflow in the vertex attribute loader %u trying to load component %u", + loader, component); continue; } u32 attribute_index = loader_config.GetComponent(component); if (attribute_index < 12) { - offset = Common::AlignUp(offset, attribute_config.GetElementSizeInBytes(attribute_index)); + offset = Common::AlignUp(offset, + attribute_config.GetElementSizeInBytes(attribute_index)); vertex_attribute_sources[attribute_index] = loader_config.data_offset + offset; - vertex_attribute_strides[attribute_index] = static_cast<u32>(loader_config.byte_count); - vertex_attribute_formats[attribute_index] = attribute_config.GetFormat(attribute_index); - vertex_attribute_elements[attribute_index] = attribute_config.GetNumElements(attribute_index); + vertex_attribute_strides[attribute_index] = + static_cast<u32>(loader_config.byte_count); + vertex_attribute_formats[attribute_index] = + attribute_config.GetFormat(attribute_index); + vertex_attribute_elements[attribute_index] = + attribute_config.GetNumElements(attribute_index); offset += attribute_config.GetStride(attribute_index); } else if (attribute_index < 16) { - // Attribute ids 12, 13, 14 and 15 signify 4, 8, 12 and 16-byte paddings, respectively + // Attribute ids 12, 13, 14 and 15 signify 4, 8, 12 and 16-byte paddings, + // respectively offset = Common::AlignUp(offset, 4); offset += (attribute_index - 11) * 4; } else { - UNREACHABLE(); // This is truly unreachable due to the number of bits for each component + UNREACHABLE(); // This is truly unreachable due to the number of bits for each + // component } } } @@ -66,48 +70,55 @@ void VertexLoader::Setup(const Pica::Regs& regs) { is_setup = true; } -void VertexLoader::LoadVertex(u32 base_address, int index, int vertex, Shader::InputVertex& input, DebugUtils::MemoryAccessTracker& memory_accesses) { +void VertexLoader::LoadVertex(u32 base_address, int index, int vertex, Shader::InputVertex& input, + DebugUtils::MemoryAccessTracker& memory_accesses) { ASSERT_MSG(is_setup, "A VertexLoader needs to be setup before loading vertices."); for (int i = 0; i < num_total_attributes; ++i) { if (vertex_attribute_elements[i] != 0) { // Load per-vertex data from the loader arrays - u32 source_addr = base_address + vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex; + u32 source_addr = + base_address + vertex_attribute_sources[i] + vertex_attribute_strides[i] * vertex; if (g_debug_context && Pica::g_debug_context->recorder) { - memory_accesses.AddAccess(source_addr, vertex_attribute_elements[i] * ( - (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::FLOAT) ? 4 - : (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::SHORT) ? 2 : 1)); + memory_accesses.AddAccess( + source_addr, + vertex_attribute_elements[i] * + ((vertex_attribute_formats[i] == Regs::VertexAttributeFormat::FLOAT) + ? 4 + : (vertex_attribute_formats[i] == Regs::VertexAttributeFormat::SHORT) + ? 2 + : 1)); } switch (vertex_attribute_formats[i]) { - case Regs::VertexAttributeFormat::BYTE: - { - const s8* srcdata = reinterpret_cast<const s8*>(Memory::GetPhysicalPointer(source_addr)); + case Regs::VertexAttributeFormat::BYTE: { + const s8* srcdata = + reinterpret_cast<const s8*>(Memory::GetPhysicalPointer(source_addr)); for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) { input.attr[i][comp] = float24::FromFloat32(srcdata[comp]); } break; } - case Regs::VertexAttributeFormat::UBYTE: - { - const u8* srcdata = reinterpret_cast<const u8*>(Memory::GetPhysicalPointer(source_addr)); + case Regs::VertexAttributeFormat::UBYTE: { + const u8* srcdata = + reinterpret_cast<const u8*>(Memory::GetPhysicalPointer(source_addr)); for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) { input.attr[i][comp] = float24::FromFloat32(srcdata[comp]); } break; } - case Regs::VertexAttributeFormat::SHORT: - { - const s16* srcdata = reinterpret_cast<const s16*>(Memory::GetPhysicalPointer(source_addr)); + case Regs::VertexAttributeFormat::SHORT: { + const s16* srcdata = + reinterpret_cast<const s16*>(Memory::GetPhysicalPointer(source_addr)); for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) { input.attr[i][comp] = float24::FromFloat32(srcdata[comp]); } break; } - case Regs::VertexAttributeFormat::FLOAT: - { - const float* srcdata = reinterpret_cast<const float*>(Memory::GetPhysicalPointer(source_addr)); + case Regs::VertexAttributeFormat::FLOAT: { + const float* srcdata = + reinterpret_cast<const float*>(Memory::GetPhysicalPointer(source_addr)); for (unsigned int comp = 0; comp < vertex_attribute_elements[i]; ++comp) { input.attr[i][comp] = float24::FromFloat32(srcdata[comp]); } @@ -119,22 +130,23 @@ void VertexLoader::LoadVertex(u32 base_address, int index, int vertex, Shader::I // is *not* carried over from the default attribute settings even if they're // enabled for this attribute. for (unsigned int comp = vertex_attribute_elements[i]; comp < 4; ++comp) { - input.attr[i][comp] = comp == 3 ? float24::FromFloat32(1.0f) : float24::FromFloat32(0.0f); + input.attr[i][comp] = + comp == 3 ? float24::FromFloat32(1.0f) : float24::FromFloat32(0.0f); } - LOG_TRACE(HW_GPU, "Loaded %d components of attribute %x for vertex %x (index %x) from 0x%08x + 0x%08x + 0x%04x: %f %f %f %f", - vertex_attribute_elements[i], i, vertex, index, - base_address, - vertex_attribute_sources[i], - vertex_attribute_strides[i] * vertex, - input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(), input.attr[i][2].ToFloat32(), input.attr[i][3].ToFloat32()); + LOG_TRACE(HW_GPU, "Loaded %d components of attribute %x for vertex %x (index %x) from " + "0x%08x + 0x%08x + 0x%04x: %f %f %f %f", + vertex_attribute_elements[i], i, vertex, index, base_address, + vertex_attribute_sources[i], vertex_attribute_strides[i] * vertex, + input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(), + input.attr[i][2].ToFloat32(), input.attr[i][3].ToFloat32()); } else if (vertex_attribute_is_default[i]) { // Load the default attribute if we're configured to do so input.attr[i] = g_state.vs_default_attributes[i]; - LOG_TRACE(HW_GPU, "Loaded default attribute %x for vertex %x (index %x): (%f, %f, %f, %f)", - i, vertex, index, - input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(), - input.attr[i][2].ToFloat32(), input.attr[i][3].ToFloat32()); + LOG_TRACE(HW_GPU, + "Loaded default attribute %x for vertex %x (index %x): (%f, %f, %f, %f)", i, + vertex, index, input.attr[i][0].ToFloat32(), input.attr[i][1].ToFloat32(), + input.attr[i][2].ToFloat32(), input.attr[i][3].ToFloat32()); } else { // TODO(yuriks): In this case, no data gets loaded and the vertex // remains with the last value it had. This isn't currently maintained @@ -143,4 +155,4 @@ void VertexLoader::LoadVertex(u32 base_address, int index, int vertex, Shader::I } } -} // namespace Pica +} // namespace Pica diff --git a/src/video_core/vertex_loader.h b/src/video_core/vertex_loader.h index ac162c254..9f2098bb2 100644 --- a/src/video_core/vertex_loader.h +++ b/src/video_core/vertex_loader.h @@ -1,7 +1,6 @@ #pragma once #include <array> - #include "common/common_types.h" #include "video_core/pica.h" @@ -23,9 +22,12 @@ public: } void Setup(const Pica::Regs& regs); - void LoadVertex(u32 base_address, int index, int vertex, Shader::InputVertex& input, DebugUtils::MemoryAccessTracker& memory_accesses); + void LoadVertex(u32 base_address, int index, int vertex, Shader::InputVertex& input, + DebugUtils::MemoryAccessTracker& memory_accesses); - int GetNumTotalAttributes() const { return num_total_attributes; } + int GetNumTotalAttributes() const { + return num_total_attributes; + } private: std::array<u32, 16> vertex_attribute_sources; @@ -37,4 +39,4 @@ private: bool is_setup = false; }; -} // namespace Pica +} // namespace Pica diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index bd6e5eb6b..83e33dfc2 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp @@ -3,21 +3,19 @@ // Refer to the license.txt file included. #include <memory> - #include "common/logging/log.h" - #include "video_core/pica.h" #include "video_core/renderer_base.h" -#include "video_core/video_core.h" #include "video_core/renderer_opengl/renderer_opengl.h" +#include "video_core/video_core.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // Video Core namespace namespace VideoCore { -EmuWindow* g_emu_window = nullptr; ///< Frontend emulator window -std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin +EmuWindow* g_emu_window = nullptr; ///< Frontend emulator window +std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin std::atomic<bool> g_hw_renderer_enabled; std::atomic<bool> g_shader_jit_enabled; diff --git a/src/video_core/video_core.h b/src/video_core/video_core.h index 30267489e..e2d725ab1 100644 --- a/src/video_core/video_core.h +++ b/src/video_core/video_core.h @@ -22,18 +22,19 @@ namespace VideoCore { // framebuffers in video memory are stored in column-major order and rendered sideways, causing // the widths and heights of the framebuffers read by the LCD to be switched compared to the // heights and widths of the screens listed here. -static const int kScreenTopWidth = 400; ///< 3DS top screen width -static const int kScreenTopHeight = 240; ///< 3DS top screen height -static const int kScreenBottomWidth = 320; ///< 3DS bottom screen width -static const int kScreenBottomHeight = 240; ///< 3DS bottom screen height +static const int kScreenTopWidth = 400; ///< 3DS top screen width +static const int kScreenTopHeight = 240; ///< 3DS top screen height +static const int kScreenBottomWidth = 320; ///< 3DS bottom screen width +static const int kScreenBottomHeight = 240; ///< 3DS bottom screen height // Video core renderer // --------------------- -extern std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin -extern EmuWindow* g_emu_window; ///< Emu window +extern std::unique_ptr<RendererBase> g_renderer; ///< Renderer plugin +extern EmuWindow* g_emu_window; ///< Emu window -// TODO: Wrap these in a user settings struct along with any other graphics settings (often set from qt ui) +// TODO: Wrap these in a user settings struct along with any other graphics settings (often set from +// qt ui) extern std::atomic<bool> g_hw_renderer_enabled; extern std::atomic<bool> g_shader_jit_enabled; extern std::atomic<bool> g_scaled_resolution_enabled; |