diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/bit_field.h | 44 | ||||
-rw-r--r-- | src/common/color.h | 16 | ||||
-rw-r--r-- | src/common/common_funcs.h | 10 | ||||
-rw-r--r-- | src/common/emu_window.cpp | 4 | ||||
-rw-r--r-- | src/common/file_util.cpp | 20 | ||||
-rw-r--r-- | src/common/key_map.h | 14 | ||||
-rw-r--r-- | src/common/logging/backend.cpp | 4 | ||||
-rw-r--r-- | src/common/logging/backend.h | 20 | ||||
-rw-r--r-- | src/common/logging/log.h | 4 | ||||
-rw-r--r-- | src/common/x64/emitter.cpp | 4 | ||||
-rw-r--r-- | src/common/x64/emitter.h | 113 |
11 files changed, 119 insertions, 134 deletions
diff --git a/src/common/bit_field.h b/src/common/bit_field.h index 66689f398..371eb17a1 100644 --- a/src/common/bit_field.h +++ b/src/common/bit_field.h @@ -115,29 +115,24 @@ template<std::size_t position, std::size_t bits, typename T> struct BitField { private: - // This constructor might be considered ambiguous: - // Would it initialize the storage or just the bitfield? - // Hence, delete it. Use the assignment operator to set bitfield values! - BitField(T val) = delete; + // We hide the copy assigment operator here, because the default copy + // assignment would copy the full storage value, rather than just the bits + // relevant to this particular bit field. + // We don't delete it because we want BitField to be trivially copyable. + BitField& operator=(const BitField&) = default; public: + // This constructor and assignment operator might be considered ambiguous: + // Would they initialize the storage or just the bitfield? + // Hence, delete them. Use the Assign method to set bitfield values! + BitField(T val) = delete; + BitField& operator=(T val) = delete; + // Force default constructor to be created // so that we can use this within unions BitField() = default; - // We explicitly delete the copy assigment operator here, because the - // default copy assignment would copy the full storage value, rather than - // just the bits relevant to this particular bit field. - BitField& operator=(const BitField&) = delete; - - FORCE_INLINE BitField& operator=(T val) - { - Assign(val); - return *this; - } - - FORCE_INLINE operator T() const - { + FORCE_INLINE operator T() const { return Value(); } @@ -145,8 +140,7 @@ public: storage = (storage & ~GetMask()) | (((StorageType)value << position) & GetMask()); } - FORCE_INLINE T Value() const - { + FORCE_INLINE T Value() const { if (std::numeric_limits<T>::is_signed) { std::size_t shift = 8 * sizeof(T)-bits; @@ -159,8 +153,7 @@ public: } // TODO: we may want to change this to explicit operator bool() if it's bug-free in VS2015 - FORCE_INLINE bool ToBool() const - { + FORCE_INLINE bool ToBool() const { return Value() != 0; } @@ -176,8 +169,7 @@ private: // Unsigned version of StorageType typedef typename std::make_unsigned<StorageType>::type StorageTypeU; - FORCE_INLINE StorageType GetMask() const - { + FORCE_INLINE StorageType GetMask() const { return (((StorageTypeU)~0) >> (8 * sizeof(T)-bits)) << position; } @@ -189,6 +181,10 @@ private: static_assert(position < 8 * sizeof(T), "Invalid position"); static_assert(bits <= 8 * sizeof(T), "Invalid number of bits"); static_assert(bits > 0, "Invalid number of bits"); - static_assert(std::is_standard_layout<T>::value, "Invalid base type"); + static_assert(std::is_pod<T>::value, "Invalid base type"); }; #pragma pack() + +#if (__GNUC__ >= 5) || defined(__clang__) || defined(_MSC_VER) +static_assert(std::is_trivially_copyable<BitField<0, 1, u32>>::value, "BitField must be trivially copyable"); +#endif diff --git a/src/common/color.h b/src/common/color.h index eb199e308..908879ea6 100644 --- a/src/common/color.h +++ b/src/common/color.h @@ -11,42 +11,42 @@ namespace Color { /// Convert a 1-bit color component to 8 bit -inline u8 Convert1To8(u8 value) { +constexpr u8 Convert1To8(u8 value) { return value * 255; } /// Convert a 4-bit color component to 8 bit -inline u8 Convert4To8(u8 value) { +constexpr u8 Convert4To8(u8 value) { return (value << 4) | value; } /// Convert a 5-bit color component to 8 bit -inline u8 Convert5To8(u8 value) { +constexpr u8 Convert5To8(u8 value) { return (value << 3) | (value >> 2); } /// Convert a 6-bit color component to 8 bit -inline u8 Convert6To8(u8 value) { +constexpr u8 Convert6To8(u8 value) { return (value << 2) | (value >> 4); } /// Convert a 8-bit color component to 1 bit -inline u8 Convert8To1(u8 value) { +constexpr u8 Convert8To1(u8 value) { return value >> 7; } /// Convert a 8-bit color component to 4 bit -inline u8 Convert8To4(u8 value) { +constexpr u8 Convert8To4(u8 value) { return value >> 4; } /// Convert a 8-bit color component to 5 bit -inline u8 Convert8To5(u8 value) { +constexpr u8 Convert8To5(u8 value) { return value >> 3; } /// Convert a 8-bit color component to 6 bit -inline u8 Convert8To6(u8 value) { +constexpr u8 Convert8To6(u8 value) { return value >> 2; } diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h index ed20c3629..aa6aff7b9 100644 --- a/src/common/common_funcs.h +++ b/src/common/common_funcs.h @@ -18,19 +18,11 @@ #define INSERT_PADDING_BYTES(num_bytes) u8 CONCAT2(pad, __LINE__)[(num_bytes)] #define INSERT_PADDING_WORDS(num_words) u32 CONCAT2(pad, __LINE__)[(num_words)] +// Inlining #ifdef _WIN32 - // Alignment #define FORCE_INLINE __forceinline - #define MEMORY_ALIGNED16(x) __declspec(align(16)) x - #define MEMORY_ALIGNED32(x) __declspec(align(32)) x - #define MEMORY_ALIGNED64(x) __declspec(align(64)) x - #define MEMORY_ALIGNED128(x) __declspec(align(128)) x #else #define FORCE_INLINE inline __attribute__((always_inline)) - #define MEMORY_ALIGNED16(x) __attribute__((aligned(16))) x - #define MEMORY_ALIGNED32(x) __attribute__((aligned(32))) x - #define MEMORY_ALIGNED64(x) __attribute__((aligned(64))) x - #define MEMORY_ALIGNED128(x) __attribute__((aligned(128))) x #endif #ifndef _MSC_VER diff --git a/src/common/emu_window.cpp b/src/common/emu_window.cpp index b69b05cb9..b2807354a 100644 --- a/src/common/emu_window.cpp +++ b/src/common/emu_window.cpp @@ -55,14 +55,14 @@ void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) { (framebuffer_layout.bottom_screen.bottom - framebuffer_layout.bottom_screen.top); touch_pressed = true; - pad_state.touch = 1; + pad_state.touch.Assign(1); } void EmuWindow::TouchReleased() { touch_pressed = false; touch_x = 0; touch_y = 0; - pad_state.touch = 0; + pad_state.touch.Assign(0); } void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y) { diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index 4c7113390..c3061479a 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -427,6 +427,9 @@ bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directo // How many files + directories we found unsigned found_entries = 0; + // Save the status of callback function + bool callback_error = false; + #ifdef _WIN32 // Find the first file in the directory. WIN32_FIND_DATA ffd; @@ -454,9 +457,11 @@ bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directo if (virtual_name == "." || virtual_name == "..") continue; - unsigned ret_entries; - if (!callback(&ret_entries, directory, virtual_name)) + unsigned ret_entries = 0; + if (!callback(&ret_entries, directory, virtual_name)) { + callback_error = true; break; + } found_entries += ret_entries; #ifdef _WIN32 @@ -467,9 +472,14 @@ bool ForeachDirectoryEntry(unsigned* num_entries_out, const std::string &directo closedir(dirp); #endif - // num_entries_out is allowed to be specified nullptr, in which case we shouldn't try to set it - if (num_entries_out != nullptr) - *num_entries_out = found_entries; + if (!callback_error) { + // num_entries_out is allowed to be specified nullptr, in which case we shouldn't try to set it + if (num_entries_out != nullptr) + *num_entries_out = found_entries; + return true; + } else { + return false; + } } unsigned ScanDirectoryTree(const std::string &directory, FSTEntry& parent_entry) diff --git a/src/common/key_map.h b/src/common/key_map.h index 0ecec714f..68f7e2f99 100644 --- a/src/common/key_map.h +++ b/src/common/key_map.h @@ -4,6 +4,7 @@ #pragma once +#include <tuple> #include "core/hle/service/hid/hid.h" namespace KeyMap { @@ -15,15 +16,14 @@ struct HostDeviceKey { int key_code; int device_id; ///< Uniquely identifies a host device - bool operator < (const HostDeviceKey &other) const { - if (device_id == other.device_id) { - return key_code < other.key_code; - } - return device_id < 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 device_id == other.device_id && key_code == other.key_code; + bool operator==(const HostDeviceKey &other) const { + return std::tie(key_code, device_id) == + std::tie(other.key_code, other.device_id); } }; diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 21a9ae8d0..54291429a 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -44,10 +44,12 @@ namespace Log { SUB(Service, LDR) \ SUB(Service, NIM) \ SUB(Service, NWM) \ + SUB(Service, CAM) \ SUB(Service, CFG) \ SUB(Service, DSP) \ SUB(Service, HID) \ SUB(Service, SOC) \ + SUB(Service, IR) \ SUB(Service, Y2R) \ CLS(HW) \ SUB(HW, Memory) \ @@ -57,6 +59,8 @@ namespace Log { CLS(Render) \ SUB(Render, Software) \ SUB(Render, OpenGL) \ + CLS(Audio) \ + SUB(Audio, DSP) \ CLS(Loader) // GetClassName is a macro defined by Windows.h, grrr... diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h index c1f4d08e4..795d42ebd 100644 --- a/src/common/logging/backend.h +++ b/src/common/logging/backend.h @@ -27,25 +27,9 @@ struct Entry { std::string message; Entry() = default; + Entry(Entry&& o) = default; - // TODO(yuriks) Use defaulted move constructors once MSVC supports them -#define MOVE(member) member(std::move(o.member)) - Entry(Entry&& o) - : MOVE(timestamp), MOVE(log_class), MOVE(log_level), - MOVE(location), MOVE(message) - {} -#undef MOVE - - Entry& operator=(const Entry&& o) { -#define MOVE(member) member = std::move(o.member) - MOVE(timestamp); - MOVE(log_class); - MOVE(log_level); - MOVE(location); - MOVE(message); -#undef MOVE - return *this; - } + Entry& operator=(Entry&& o) = default; }; /** diff --git a/src/common/logging/log.h b/src/common/logging/log.h index 43f0c59e4..4b01805ae 100644 --- a/src/common/logging/log.h +++ b/src/common/logging/log.h @@ -59,10 +59,12 @@ enum class Class : ClassType { Service_LDR, ///< The LDR (3ds dll loader) service Service_NIM, ///< The NIM (Network interface manager) service Service_NWM, ///< The NWM (Network wlan manager) service + Service_CAM, ///< The CAM (Camera) service Service_CFG, ///< The CFG (Configuration) service Service_DSP, ///< The DSP (DSP control) 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 @@ -72,6 +74,8 @@ enum class Class : ClassType { Render, ///< Emulator video output and hardware acceleration Render_Software, ///< Software renderer backend Render_OpenGL, ///< OpenGL backend + Audio, ///< Emulator audio output + Audio_DSP, ///< The HLE implementation of the DSP Loader, ///< ROM loader Count ///< Total number of logging classes diff --git a/src/common/x64/emitter.cpp b/src/common/x64/emitter.cpp index 939df210e..1dcf2416c 100644 --- a/src/common/x64/emitter.cpp +++ b/src/common/x64/emitter.cpp @@ -225,14 +225,14 @@ void OpArg::WriteVex(XEmitter* emit, X64Reg regOp1, X64Reg regOp2, int L, int pp // do we need any VEX fields that only appear in the three-byte form? if (X == 1 && B == 1 && W == 0 && mmmmm == 1) { - u8 RvvvvLpp = (R << 7) | (vvvv << 3) | (L << 1) | pp; + u8 RvvvvLpp = (R << 7) | (vvvv << 3) | (L << 2) | pp; emit->Write8(0xC5); emit->Write8(RvvvvLpp); } else { u8 RXBmmmmm = (R << 7) | (X << 6) | (B << 5) | mmmmm; - u8 WvvvvLpp = (W << 7) | (vvvv << 3) | (L << 1) | pp; + u8 WvvvvLpp = (W << 7) | (vvvv << 3) | (L << 2) | pp; emit->Write8(0xC4); emit->Write8(RXBmmmmm); emit->Write8(WvvvvLpp); diff --git a/src/common/x64/emitter.h b/src/common/x64/emitter.h index 2dd0dc94e..7c6548fb5 100644 --- a/src/common/x64/emitter.h +++ b/src/common/x64/emitter.h @@ -157,45 +157,37 @@ class XEmitter; // RIP addressing does not benefit from micro op fusion on Core arch struct OpArg { - OpArg() {} // dummy op arg, used for storage - OpArg(u64 _offset, int _scale, X64Reg rmReg = RAX, X64Reg scaledReg = RAX) + friend class XEmitter; + + 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_) { - operandReg = 0; - scale = (u8)_scale; - offsetOrBaseReg = (u16)rmReg; - indexReg = (u16)scaledReg; - //if scale == 0 never mind offsetting - offset = _offset; } - bool operator==(const OpArg &b) const + + constexpr bool operator==(const OpArg &b) const { - return operandReg == b.operandReg && scale == b.scale && offsetOrBaseReg == b.offsetOrBaseReg && - indexReg == b.indexReg && offset == b.offset; + 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 WriteFloatModRM(XEmitter *emit, FloatOp op); void WriteSingleByteOp(XEmitter *emit, u8 op, X64Reg operandReg, int bits); - // This one is public - must be written to - u64 offset; // use RIP-relative as much as possible - 64-bit immediates are not available. - u16 operandReg; - void WriteNormalOp(XEmitter *emit, bool toRM, NormalOp op, const OpArg &operand, int bits) const; - bool IsImm() const {return scale == SCALE_IMM8 || scale == SCALE_IMM16 || scale == SCALE_IMM32 || scale == SCALE_IMM64;} - bool IsSimpleReg() const {return scale == SCALE_NONE;} - bool IsSimpleReg(X64Reg reg) const - { - if (!IsSimpleReg()) - return false; - return GetSimpleReg() == reg; - } - bool CanDoOpWith(const OpArg &other) 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 { - if (IsSimpleReg()) return true; - if (!IsSimpleReg() && !other.IsSimpleReg() && !other.IsImm()) return false; - return true; + return IsSimpleReg() && GetSimpleReg() == reg; } int GetImmBits() const @@ -220,16 +212,15 @@ struct OpArg } } - X64Reg GetSimpleReg() const + constexpr X64Reg GetSimpleReg() const { - if (scale == SCALE_NONE) - return (X64Reg)offsetOrBaseReg; - else - return INVALID_REG; + return scale == SCALE_NONE + ? static_cast<X64Reg>(offsetOrBaseReg) + : INVALID_REG; } - u32 GetImmValue() const { - return (u32)offset; + constexpr u32 GetImmValue() const { + return static_cast<u32>(offset); } // For loops. @@ -238,56 +229,60 @@ struct OpArg } private: - u8 scale; - u16 offsetOrBaseReg; - u16 indexReg; + 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. + u16 operandReg = 0; }; -inline OpArg M(const void *ptr) {return OpArg((u64)ptr, (int)SCALE_RIP);} template <typename T> -inline OpArg M(const T *ptr) {return OpArg((u64)(const void *)ptr, (int)SCALE_RIP);} -inline OpArg R(X64Reg value) {return OpArg(0, SCALE_NONE, value);} -inline 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); } -inline OpArg MDisp(X64Reg value, int offset) +constexpr OpArg MDisp(X64Reg value, int offset) { - return OpArg((u32)offset, SCALE_ATREG, value); + return OpArg(static_cast<u32>(offset), SCALE_ATREG, value); } -inline 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); } -inline OpArg MScaled(X64Reg scaled, int scale, int offset) +constexpr OpArg MScaled(X64Reg scaled, int scale, int offset) { - if (scale == SCALE_1) - return OpArg(offset, SCALE_ATREG, scaled); - else - return OpArg(offset, scale | 0x20, RAX, scaled); + return scale == SCALE_1 + ? OpArg(offset, SCALE_ATREG, scaled) + : OpArg(offset, scale | 0x20, RAX, scaled); } -inline OpArg MRegSum(X64Reg base, X64Reg offset) +constexpr OpArg MRegSum(X64Reg base, X64Reg offset) { return MComplex(base, offset, 1, 0); } -inline OpArg Imm8 (u8 imm) {return OpArg(imm, SCALE_IMM8);} -inline OpArg Imm16(u16 imm) {return OpArg(imm, SCALE_IMM16);} //rarely used -inline OpArg Imm32(u32 imm) {return OpArg(imm, SCALE_IMM32);} -inline OpArg Imm64(u64 imm) {return OpArg(imm, SCALE_IMM64);} -inline OpArg UImmAuto(u32 imm) { +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); } -inline OpArg SImmAuto(s32 imm) { +constexpr OpArg SImmAuto(s32 imm) { return OpArg(imm, (imm >= 128 || imm < -128) ? SCALE_IMM32 : SCALE_IMM8); } +template <typename T> +OpArg ImmPtr(const T* imm) +{ #ifdef _ARCH_64 -inline OpArg ImmPtr(const void* imm) {return Imm64((u64)imm);} + return Imm64(reinterpret_cast<u64>(imm)); #else -inline OpArg ImmPtr(const void* imm) {return Imm32((u32)imm);} + return Imm32(reinterpret_cast<u32>(imm)); #endif +} inline u32 PtrOffset(const void* ptr, const void* base) { |