diff options
| author | 2014-05-16 23:21:03 -0700 | |
|---|---|---|
| committer | 2014-05-16 23:21:03 -0700 | |
| commit | b8c8d0903ec9be4c7d580464480a0136277be803 (patch) | |
| tree | 9280a9f01e1312d0d8aed493282ae65d2384963c /src/common | |
| parent | Added FindGLEW to cmake-modules (diff) | |
| parent | Merge pull request #17 from bunnei/arm-vfp (diff) | |
| download | yuzu-b8c8d0903ec9be4c7d580464480a0136277be803.tar.gz yuzu-b8c8d0903ec9be4c7d580464480a0136277be803.tar.xz yuzu-b8c8d0903ec9be4c7d580464480a0136277be803.zip | |
Merge remote-tracking branch 'upstream/master' into issue-7-fix
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/bit_field.h | 172 | ||||
| -rw-r--r-- | src/common/common.vcxproj | 1 | ||||
| -rw-r--r-- | src/common/common.vcxproj.filters | 1 | ||||
| -rw-r--r-- | src/common/log.h | 4 | ||||
| -rw-r--r-- | src/common/log_manager.cpp | 6 |
5 files changed, 179 insertions, 5 deletions
diff --git a/src/common/bit_field.h b/src/common/bit_field.h new file mode 100644 index 000000000..dfd00d198 --- /dev/null +++ b/src/common/bit_field.h | |||
| @@ -0,0 +1,172 @@ | |||
| 1 | // Licensed under GPLv2 | ||
| 2 | // Refer to the license.txt file included. | ||
| 3 | |||
| 4 | |||
| 5 | // Copyright 2014 Tony Wasserka | ||
| 6 | // All rights reserved. | ||
| 7 | // | ||
| 8 | // Redistribution and use in source and binary forms, with or without | ||
| 9 | // modification, are permitted provided that the following conditions are met: | ||
| 10 | // | ||
| 11 | // * Redistributions of source code must retain the above copyright | ||
| 12 | // notice, this list of conditions and the following disclaimer. | ||
| 13 | // * Redistributions in binary form must reproduce the above copyright | ||
| 14 | // notice, this list of conditions and the following disclaimer in the | ||
| 15 | // documentation and/or other materials provided with the distribution. | ||
| 16 | // * Neither the name of the owner nor the names of its contributors may | ||
| 17 | // be used to endorse or promote products derived from this software | ||
| 18 | // without specific prior written permission. | ||
| 19 | // | ||
| 20 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 21 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 22 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| 23 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| 24 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 25 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| 26 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 27 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 28 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 29 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 31 | |||
| 32 | |||
| 33 | #pragma once | ||
| 34 | |||
| 35 | #include <limits> | ||
| 36 | #include <type_traits> | ||
| 37 | |||
| 38 | #include "common/common.h" | ||
| 39 | |||
| 40 | /* | ||
| 41 | * Abstract bitfield class | ||
| 42 | * | ||
| 43 | * Allows endianness-independent access to individual bitfields within some raw | ||
| 44 | * integer value. The assembly generated by this class is identical to the | ||
| 45 | * usage of raw bitfields, so it's a perfectly fine replacement. | ||
| 46 | * | ||
| 47 | * For BitField<X,Y,Z>, X is the distance of the bitfield to the LSB of the | ||
| 48 | * raw value, Y is the length in bits of the bitfield. Z is an integer type | ||
| 49 | * which determines the sign of the bitfield. Z must have the same size as the | ||
| 50 | * raw integer. | ||
| 51 | * | ||
| 52 | * | ||
| 53 | * General usage: | ||
| 54 | * | ||
| 55 | * Create a new union with the raw integer value as a member. | ||
| 56 | * Then for each bitfield you want to expose, add a BitField member | ||
| 57 | * in the union. The template parameters are the bit offset and the number | ||
| 58 | * of desired bits. | ||
| 59 | * | ||
| 60 | * Changes in the bitfield members will then get reflected in the raw integer | ||
| 61 | * value and vice-versa. | ||
| 62 | * | ||
| 63 | * | ||
| 64 | * Sample usage: | ||
| 65 | * | ||
| 66 | * union SomeRegister | ||
| 67 | * { | ||
| 68 | * u32 hex; | ||
| 69 | * | ||
| 70 | * BitField<0,7,u32> first_seven_bits; // unsigned | ||
| 71 | * BitField<7,8,32> next_eight_bits; // unsigned | ||
| 72 | * BitField<3,15,s32> some_signed_fields; // signed | ||
| 73 | * }; | ||
| 74 | * | ||
| 75 | * This is equivalent to the little-endian specific code: | ||
| 76 | * | ||
| 77 | * union SomeRegister | ||
| 78 | * { | ||
| 79 | * u32 hex; | ||
| 80 | * | ||
| 81 | * struct | ||
| 82 | * { | ||
| 83 | * u32 first_seven_bits : 7; | ||
| 84 | * u32 next_eight_bits : 8; | ||
| 85 | * }; | ||
| 86 | * struct | ||
| 87 | * { | ||
| 88 | * u32 : 3; // padding | ||
| 89 | * s32 some_signed_fields : 15; | ||
| 90 | * }; | ||
| 91 | * }; | ||
| 92 | * | ||
| 93 | * | ||
| 94 | * Caveats: | ||
| 95 | * | ||
| 96 | * 1) | ||
| 97 | * BitField provides automatic casting from and to the storage type where | ||
| 98 | * appropriate. However, when using non-typesafe functions like printf, an | ||
| 99 | * explicit cast must be performed on the BitField object to make sure it gets | ||
| 100 | * passed correctly, e.g.: | ||
| 101 | * printf("Value: %d", (s32)some_register.some_signed_fields); | ||
| 102 | * | ||
| 103 | * 2) | ||
| 104 | * Not really a caveat, but potentially irritating: This class is used in some | ||
| 105 | * packed structures that do not guarantee proper alignment. Therefore we have | ||
| 106 | * to use #pragma pack here not to pack the members of the class, but instead | ||
| 107 | * to break GCC's assumption that the members of the class are aligned on | ||
| 108 | * sizeof(StorageType). | ||
| 109 | * TODO(neobrain): Confirm that this is a proper fix and not just masking | ||
| 110 | * symptoms. | ||
| 111 | */ | ||
| 112 | #pragma pack(1) | ||
| 113 | template<std::size_t position, std::size_t bits, typename T> | ||
| 114 | struct BitField | ||
| 115 | { | ||
| 116 | private: | ||
| 117 | // This constructor might be considered ambiguous: | ||
| 118 | // Would it initialize the storage or just the bitfield? | ||
| 119 | // Hence, delete it. Use the assignment operator to set bitfield values! | ||
| 120 | BitField(T val) = delete; | ||
| 121 | |||
| 122 | public: | ||
| 123 | // Force default constructor to be created | ||
| 124 | // so that we can use this within unions | ||
| 125 | BitField() = default; | ||
| 126 | |||
| 127 | __forceinline BitField& operator=(T val) | ||
| 128 | { | ||
| 129 | storage = (storage & ~GetMask()) | ((val << position) & GetMask()); | ||
| 130 | return *this; | ||
| 131 | } | ||
| 132 | |||
| 133 | __forceinline operator T() const | ||
| 134 | { | ||
| 135 | if (std::numeric_limits<T>::is_signed) | ||
| 136 | { | ||
| 137 | std::size_t shift = 8 * sizeof(T)-bits; | ||
| 138 | return (T)(((storage & GetMask()) << (shift - position)) >> shift); | ||
| 139 | } | ||
| 140 | else | ||
| 141 | { | ||
| 142 | return (T)((storage & GetMask()) >> position); | ||
| 143 | } | ||
| 144 | } | ||
| 145 | |||
| 146 | private: | ||
| 147 | // StorageType is T for non-enum types and the underlying type of T if | ||
| 148 | // T is an enumeration. Note that T is wrapped within an enable_if in the | ||
| 149 | // former case to workaround compile errors which arise when using | ||
| 150 | // std::underlying_type<T>::type directly. | ||
| 151 | typedef typename std::conditional < std::is_enum<T>::value, | ||
| 152 | std::underlying_type<T>, | ||
| 153 | std::enable_if < true, T >> ::type::type StorageType; | ||
| 154 | |||
| 155 | // Unsigned version of StorageType | ||
| 156 | typedef typename std::make_unsigned<StorageType>::type StorageTypeU; | ||
| 157 | |||
| 158 | __forceinline StorageType GetMask() const | ||
| 159 | { | ||
| 160 | return ((~(StorageTypeU)0) >> (8 * sizeof(T)-bits)) << position; | ||
| 161 | } | ||
| 162 | |||
| 163 | StorageType storage; | ||
| 164 | |||
| 165 | static_assert(bits + position <= 8 * sizeof(T), "Bitfield out of range"); | ||
| 166 | |||
| 167 | // And, you know, just in case people specify something stupid like bits=position=0x80000000 | ||
| 168 | static_assert(position < 8 * sizeof(T), "Invalid position"); | ||
| 169 | static_assert(bits <= 8 * sizeof(T), "Invalid number of bits"); | ||
| 170 | static_assert(bits > 0, "Invalid number of bits"); | ||
| 171 | }; | ||
| 172 | #pragma pack() | ||
diff --git a/src/common/common.vcxproj b/src/common/common.vcxproj index 5048bebff..5dc6ff790 100644 --- a/src/common/common.vcxproj +++ b/src/common/common.vcxproj | |||
| @@ -157,6 +157,7 @@ | |||
| 157 | <ClInclude Include="atomic.h" /> | 157 | <ClInclude Include="atomic.h" /> |
| 158 | <ClInclude Include="atomic_gcc.h" /> | 158 | <ClInclude Include="atomic_gcc.h" /> |
| 159 | <ClInclude Include="atomic_win32.h" /> | 159 | <ClInclude Include="atomic_win32.h" /> |
| 160 | <ClInclude Include="bit_field.h" /> | ||
| 160 | <ClInclude Include="break_points.h" /> | 161 | <ClInclude Include="break_points.h" /> |
| 161 | <ClInclude Include="chunk_file.h" /> | 162 | <ClInclude Include="chunk_file.h" /> |
| 162 | <ClInclude Include="common.h" /> | 163 | <ClInclude Include="common.h" /> |
diff --git a/src/common/common.vcxproj.filters b/src/common/common.vcxproj.filters index e9ea40022..268730228 100644 --- a/src/common/common.vcxproj.filters +++ b/src/common/common.vcxproj.filters | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | <ClInclude Include="utf8.h" /> | 39 | <ClInclude Include="utf8.h" /> |
| 40 | <ClInclude Include="symbols.h" /> | 40 | <ClInclude Include="symbols.h" /> |
| 41 | <ClInclude Include="scm_rev.h" /> | 41 | <ClInclude Include="scm_rev.h" /> |
| 42 | <ClInclude Include="bit_field.h" /> | ||
| 42 | </ItemGroup> | 43 | </ItemGroup> |
| 43 | <ItemGroup> | 44 | <ItemGroup> |
| 44 | <ClCompile Include="break_points.cpp" /> | 45 | <ClCompile Include="break_points.cpp" /> |
diff --git a/src/common/log.h b/src/common/log.h index 02db8bd55..d95f51f56 100644 --- a/src/common/log.h +++ b/src/common/log.h | |||
| @@ -33,7 +33,7 @@ enum LOG_TYPE { | |||
| 33 | EXPANSIONINTERFACE, | 33 | EXPANSIONINTERFACE, |
| 34 | GDB_STUB, | 34 | GDB_STUB, |
| 35 | ARM11, | 35 | ARM11, |
| 36 | GPFIFO, | 36 | GSP, |
| 37 | OSHLE, | 37 | OSHLE, |
| 38 | MASTER_LOG, | 38 | MASTER_LOG, |
| 39 | MEMMAP, | 39 | MEMMAP, |
| @@ -54,7 +54,7 @@ enum LOG_TYPE { | |||
| 54 | WII_IPC_FILEIO, | 54 | WII_IPC_FILEIO, |
| 55 | WII_IPC_HID, | 55 | WII_IPC_HID, |
| 56 | WII_IPC_HLE, | 56 | WII_IPC_HLE, |
| 57 | WII_IPC_NET, | 57 | SVC, |
| 58 | NDMA, | 58 | NDMA, |
| 59 | HLE, | 59 | HLE, |
| 60 | RENDER, | 60 | RENDER, |
diff --git a/src/common/log_manager.cpp b/src/common/log_manager.cpp index 8e56deb8f..80fd473b9 100644 --- a/src/common/log_manager.cpp +++ b/src/common/log_manager.cpp | |||
| @@ -42,7 +42,7 @@ LogManager::LogManager() | |||
| 42 | m_Log[LogTypes::STREAMINGINTERFACE] = new LogContainer("Stream", "StreamingInt"); | 42 | m_Log[LogTypes::STREAMINGINTERFACE] = new LogContainer("Stream", "StreamingInt"); |
| 43 | m_Log[LogTypes::DSPINTERFACE] = new LogContainer("DSP", "DSPInterface"); | 43 | m_Log[LogTypes::DSPINTERFACE] = new LogContainer("DSP", "DSPInterface"); |
| 44 | m_Log[LogTypes::DVDINTERFACE] = new LogContainer("DVD", "DVDInterface"); | 44 | m_Log[LogTypes::DVDINTERFACE] = new LogContainer("DVD", "DVDInterface"); |
| 45 | m_Log[LogTypes::GPFIFO] = new LogContainer("GP", "GPFifo"); | 45 | m_Log[LogTypes::GSP] = new LogContainer("GSP", "GSP"); |
| 46 | m_Log[LogTypes::EXPANSIONINTERFACE] = new LogContainer("EXI", "ExpansionInt"); | 46 | m_Log[LogTypes::EXPANSIONINTERFACE] = new LogContainer("EXI", "ExpansionInt"); |
| 47 | m_Log[LogTypes::GDB_STUB] = new LogContainer("GDB_STUB", "GDB Stub"); | 47 | m_Log[LogTypes::GDB_STUB] = new LogContainer("GDB_STUB", "GDB Stub"); |
| 48 | m_Log[LogTypes::AUDIO_INTERFACE] = new LogContainer("AI", "AudioInt"); | 48 | m_Log[LogTypes::AUDIO_INTERFACE] = new LogContainer("AI", "AudioInt"); |
| @@ -66,7 +66,7 @@ LogManager::LogManager() | |||
| 66 | m_Log[LogTypes::WII_IPC_FILEIO] = new LogContainer("WII_IPC_FILEIO", "WII IPC FILEIO"); | 66 | m_Log[LogTypes::WII_IPC_FILEIO] = new LogContainer("WII_IPC_FILEIO", "WII IPC FILEIO"); |
| 67 | m_Log[LogTypes::RENDER] = new LogContainer("RENDER", "RENDER"); | 67 | m_Log[LogTypes::RENDER] = new LogContainer("RENDER", "RENDER"); |
| 68 | m_Log[LogTypes::LCD] = new LogContainer("LCD", "LCD"); | 68 | m_Log[LogTypes::LCD] = new LogContainer("LCD", "LCD"); |
| 69 | m_Log[LogTypes::WII_IPC_NET] = new LogContainer("WII_IPC_NET", "WII IPC NET"); | 69 | m_Log[LogTypes::SVC] = new LogContainer("SVC", "Supervisor Call"); |
| 70 | m_Log[LogTypes::NDMA] = new LogContainer("NDMA", "NDMA"); | 70 | m_Log[LogTypes::NDMA] = new LogContainer("NDMA", "NDMA"); |
| 71 | m_Log[LogTypes::HLE] = new LogContainer("HLE", "High Level Emulation"); | 71 | m_Log[LogTypes::HLE] = new LogContainer("HLE", "High Level Emulation"); |
| 72 | m_Log[LogTypes::HW] = new LogContainer("HW", "Hardware"); | 72 | m_Log[LogTypes::HW] = new LogContainer("HW", "Hardware"); |
| @@ -147,7 +147,7 @@ LogContainer::LogContainer(const char* shortName, const char* fullName, bool ena | |||
| 147 | { | 147 | { |
| 148 | strncpy(m_fullName, fullName, 128); | 148 | strncpy(m_fullName, fullName, 128); |
| 149 | strncpy(m_shortName, shortName, 32); | 149 | strncpy(m_shortName, shortName, 32); |
| 150 | m_level = LogTypes::LWARNING; | 150 | m_level = (LogTypes::LOG_LEVELS)MAX_LOGLEVEL; |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | // LogContainer | 153 | // LogContainer |