summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/bit_field.h44
-rw-r--r--src/common/color.h16
-rw-r--r--src/common/common_funcs.h10
-rw-r--r--src/common/emu_window.cpp4
-rw-r--r--src/common/file_util.cpp20
-rw-r--r--src/common/key_map.h14
-rw-r--r--src/common/logging/backend.cpp4
-rw-r--r--src/common/logging/backend.h20
-rw-r--r--src/common/logging/log.h4
-rw-r--r--src/common/x64/emitter.cpp4
-rw-r--r--src/common/x64/emitter.h113
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)
{