summaryrefslogtreecommitdiffstats
path: root/src/common
diff options
context:
space:
mode:
authorEmmanuel Gil Peyrot <linkmauve@linkmauve.fr>2016-09-18 02:38:01 +0200
committerEmmanuel Gil Peyrot <linkmauve@linkmauve.fr>2016-09-18 02:38:01 +0200
commitdc8479928c5aee4c6ad6fe4f59006fb604cee701 (patch)
tree569a7f13128450bbab973236615587ff00bced5f /src/common
parentTravis: Import Dolphin’s clang-format hook. (diff)
downloadyuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.gz
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.bz2
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.lz
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.xz
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.tar.zst
yuzu-dc8479928c5aee4c6ad6fe4f59006fb604cee701.zip
Diffstat (limited to 'src/common')
-rw-r--r--src/common/assert.h26
-rw-r--r--src/common/bit_field.h26
-rw-r--r--src/common/bit_set.h203
-rw-r--r--src/common/break_points.cpp54
-rw-r--r--src/common/break_points.h18
-rw-r--r--src/common/chunk_file.h539
-rw-r--r--src/common/code_block.h42
-rw-r--r--src/common/color.h30
-rw-r--r--src/common/common_funcs.h25
-rw-r--r--src/common/common_paths.h54
-rw-r--r--src/common/common_types.h8
-rw-r--r--src/common/emu_window.cpp48
-rw-r--r--src/common/emu_window.h54
-rw-r--r--src/common/file_util.cpp515
-rw-r--r--src/common/file_util.h118
-rw-r--r--src/common/hash.cpp96
-rw-r--r--src/common/key_map.cpp30
-rw-r--r--src/common/key_map.h11
-rw-r--r--src/common/linear_disk_cache.h78
-rw-r--r--src/common/logging/backend.cpp139
-rw-r--r--src/common/logging/backend.h6
-rw-r--r--src/common/logging/filter.cpp7
-rw-r--r--src/common/logging/filter.h4
-rw-r--r--src/common/logging/log.h136
-rw-r--r--src/common/logging/text_formatter.cpp52
-rw-r--r--src/common/logging/text_formatter.h1
-rw-r--r--src/common/math_util.h33
-rw-r--r--src/common/memory_util.cpp90
-rw-r--r--src/common/memory_util.h6
-rw-r--r--src/common/microprofile.h2
-rw-r--r--src/common/misc.cpp8
-rw-r--r--src/common/platform.h4
-rw-r--r--src/common/profiler.cpp4
-rw-r--r--src/common/scope_exit.h23
-rw-r--r--src/common/string_util.cpp191
-rw-r--r--src/common/string_util.h56
-rw-r--r--src/common/swap.h331
-rw-r--r--src/common/symbols.cpp66
-rw-r--r--src/common/symbols.h25
-rw-r--r--src/common/synchronized_wrapper.h22
-rw-r--r--src/common/thread.cpp80
-rw-r--r--src/common/thread.h40
-rw-r--r--src/common/thread_queue_list.h22
-rw-r--r--src/common/timer.cpp73
-rw-r--r--src/common/timer.h11
-rw-r--r--src/common/vector_math.h707
-rw-r--r--src/common/x64/abi.cpp127
-rw-r--r--src/common/x64/abi.h15
-rw-r--r--src/common/x64/cpu_detect.cpp92
-rw-r--r--src/common/x64/emitter.cpp2612
-rw-r--r--src/common/x64/emitter.h601
51 files changed, 4172 insertions, 3389 deletions
diff --git a/src/common/assert.h b/src/common/assert.h
index cd9b819a9..70214efae 100644
--- a/src/common/assert.h
+++ b/src/common/assert.h
@@ -18,25 +18,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_MSG(_a_, ...) \
- do if (!(_a_)) { assert_noinline_call([&] { \
- LOG_CRITICAL(Debug, "Assertion Failed!\n" __VA_ARGS__); \
- }); } 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 UNREACHABLE() ASSERT_MSG(false, "Unreachable code!")
#define UNREACHABLE_MSG(...) ASSERT_MSG(false, __VA_ARGS__)
diff --git a/src/common/bit_field.h b/src/common/bit_field.h
index 4748999ed..8d45743e2 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,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 <cstddef>
@@ -111,9 +109,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 +138,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 +156,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 +179,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..b83cbbb36 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,100 +95,144 @@ 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)
- {
+ 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) {
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(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) {
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;
};
- BitSet() : m_val(0) {}
- explicit BitSet(IntTy val) : m_val(val) {}
- BitSet(std::initializer_list<int> init)
- {
+ BitSet() : m_val(0) {
+ }
+ explicit BitSet(IntTy val) : m_val(val) {
+ }
+ 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..3218db314 100644
--- a/src/common/break_points.cpp
+++ b/src/common/break_points.cpp
@@ -5,30 +5,27 @@
#include "common/break_points.h"
#include "common/logging/log.h"
-#include <sstream>
#include <algorithm>
+#include <sstream>
-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 +35,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 +47,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 +65,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..1a5b7d296 100644
--- a/src/common/break_points.h
+++ b/src/common/break_points.h
@@ -4,28 +4,28 @@
#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 +35,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 +46,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..3b36c0a9e 100644
--- a/src/common/chunk_file.h
+++ b/src/common/chunk_file.h
@@ -41,81 +41,86 @@
#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 +129,239 @@ 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 +369,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 +379,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 +430,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 +443,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 +475,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 +534,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 +607,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..58696737e 100644
--- a/src/common/code_block.h
+++ b/src/common/code_block.h
@@ -14,24 +14,28 @@
// 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(); }
+ CodeBlock() : region(nullptr), region_size(0) {
+ }
+ 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 +43,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 +59,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..ad5bdbc08 100644
--- a/src/common/common_funcs.h
+++ b/src/common/common_funcs.h
@@ -14,7 +14,7 @@
/// 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 +24,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 +46,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 +57,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 +76,18 @@ 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..c86f663a8 100644
--- a/src/common/emu_window.cpp
+++ b/src/common/emu_window.cpp
@@ -44,18 +44,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 +63,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 +91,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 +114,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 +132,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..de8badd4f 100644
--- a/src/common/emu_window.h
+++ b/src/common/emu_window.h
@@ -30,15 +30,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 +192,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;
@@ -227,7 +229,8 @@ protected:
circle_pad_y = 0;
touch_pressed = false;
}
- virtual ~EmuWindow() {}
+ virtual ~EmuWindow() {
+ }
/**
* Processes any pending configuration changes from the last SetConfig call.
@@ -258,7 +261,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 +269,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..c8723a4b3 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -2,73 +2,70 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/file_util.h"
#include "common/assert.h"
#include "common/common_funcs.h"
#include "common/common_paths.h"
-#include "common/file_util.h"
#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>
+#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,36 @@ 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 +866,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 +874,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..b15021a63 100644
--- a/src/common/file_util.h
+++ b/src/common/file_util.h
@@ -5,9 +5,9 @@
#pragma once
#include <array>
+#include <cstdio>
#include <fstream>
#include <functional>
-#include <cstdio>
#include <string>
#include <type_traits>
#include <vector>
@@ -51,75 +51,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 +128,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 +155,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 +174,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 +190,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 +211,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 +231,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 +264,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..a46c92553 100644
--- a/src/common/hash.cpp
+++ b/src/common/hash.cpp
@@ -36,7 +36,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 +47,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..e882f5f52 100644
--- a/src/common/key_map.cpp
+++ b/src/common/key_map.cpp
@@ -13,11 +13,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 +63,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 +118,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 +150,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..b3d6598e4 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -16,73 +16,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 +96,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 +116,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 +132,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..3fe88e4f6 100644
--- a/src/common/logging/backend.h
+++ b/src/common/logging/backend.h
@@ -44,10 +44,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..186e0b621 100644
--- a/src/common/logging/filter.cpp
+++ b/src/common/logging/filter.cpp
@@ -4,8 +4,8 @@
#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 +63,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 +95,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..db526fead 100644
--- a/src/common/logging/filter.h
+++ b/src/common/logging/filter.h
@@ -42,7 +42,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 +51,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..955358553 100644
--- a/src/common/logging/text_formatter.cpp
+++ b/src/common/logging/text_formatter.cpp
@@ -6,8 +6,8 @@
#include <cstdio>
#ifdef _WIN32
-# define WIN32_LEAN_AND_MEAN
-# include <Windows.h>
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
#endif
#include "common/logging/backend.h"
@@ -44,15 +44,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 +71,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 +128,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..696bd43ea 100644
--- a/src/common/math_util.h
+++ b/src/common/math_util.h
@@ -8,33 +8,38 @@
#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;
T bottom;
- 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..7d352f00f 100644
--- a/src/common/memory_util.cpp
+++ b/src/common/memory_util.cpp
@@ -2,31 +2,29 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
-
-#include "common/logging/log.h"
#include "common/memory_util.h"
+#include "common/logging/log.h"
#ifdef _WIN32
- #include <windows.h>
- #include <psapi.h>
- #include "common/common_funcs.h"
- #include "common/string_util.h"
+#include <windows.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 +37,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 +72,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 +88,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 +107,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 +118,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 +138,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 +161,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..5938e6289 100644
--- a/src/common/misc.cpp
+++ b/src/common/misc.cpp
@@ -12,23 +12,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..992ec25b2 100644
--- a/src/common/profiler.cpp
+++ b/src/common/profiler.cpp
@@ -14,7 +14,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() {
@@ -31,7 +31,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/scope_exit.h b/src/common/scope_exit.h
index 08f09a8c8..73b2a262e 100644
--- a/src/common/scope_exit.h
+++ b/src/common/scope_exit.h
@@ -4,20 +4,25 @@
#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..9ccd6f135 100644
--- a/src/common/string_util.cpp
+++ b/src/common/string_util.cpp
@@ -14,11 +14,11 @@
#include "common/string_util.h"
#ifdef _MSC_VER
- #include <Windows.h>
- #include <codecvt>
- #include "common/common_funcs.h"
+#include <Windows.h>
+#include <codecvt>
+#include "common/common_funcs.h"
#else
- #include <iconv.h>
+#include <iconv.h>
#endif
namespace Common {
@@ -36,9 +36,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 +47,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 +82,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 +118,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 +136,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 +148,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 +170,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 +178,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 +189,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 +225,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 +237,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 +247,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 +258,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 +274,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 +286,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 +298,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 +365,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 +391,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 +413,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 +439,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..6ffd735f4 100644
--- a/src/common/string_util.h
+++ b/src/common/string_util.h
@@ -25,9 +25,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 +34,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 +55,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 +96,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 +135,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..1794144fb 100644
--- a/src/common/swap.h
+++ b/src/common/swap.h
@@ -18,11 +18,11 @@
#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>
@@ -61,38 +61,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 +139,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 +150,7 @@ inline double swapd(double f) {
return f;
}
-} // Namespace Common
-
+} // Namespace Common
template <typename T, typename F>
struct swap_struct_t {
@@ -129,251 +162,272 @@ 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 +435,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 +605,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..6044c9db6 100644
--- a/src/common/symbols.h
+++ b/src/common/symbols.h
@@ -10,25 +10,22 @@
#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..8dc4ddeac 100644
--- a/src/common/synchronized_wrapper.h
+++ b/src/common/synchronized_wrapper.h
@@ -12,14 +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:
@@ -58,11 +58,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..bee607ce9 100644
--- a/src/common/thread.cpp
+++ b/src/common/thread.cpp
@@ -5,27 +5,25 @@
#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
- #include <pthread.h>
- #endif
- #include <sched.h>
+#if defined(BSD4_4) || defined(__OpenBSD__)
+#include <pthread_np.h>
+#else
+#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 +35,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 +60,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 +100,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..b189dc764 100644
--- a/src/common/thread.h
+++ b/src/common/thread.h
@@ -4,10 +4,10 @@
#pragma once
-#include <cstddef>
-#include <thread>
#include <condition_variable>
+#include <cstddef>
#include <mutex>
+#include <thread>
#include "common/common_types.h"
@@ -17,17 +17,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 {
@@ -39,7 +39,8 @@ void SetCurrentThreadAffinity(u32 mask);
class Event {
public:
- Event() : is_set(false) {}
+ Event() : is_set(false) {
+ }
void Set() {
std::lock_guard<std::mutex> lk(mutex);
@@ -51,13 +52,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;
}
@@ -69,7 +71,8 @@ private:
class Barrier {
public:
- explicit Barrier(size_t count_) : count(count_), waiting(0), generation(0) {}
+ explicit Barrier(size_t count_) : count(count_), waiting(0), generation(0) {
+ }
/// Blocks until all "count" threads have called Sync()
void Sync() {
@@ -81,7 +84,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 +98,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 +107,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..0dcf785b6 100644
--- a/src/common/thread_queue_list.h
+++ b/src/common/thread_queue_list.h
@@ -11,7 +11,7 @@
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 +39,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 +51,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 +65,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 +80,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 +96,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 +115,7 @@ struct ThreadQueueList {
}
bool empty(Priority priority) const {
- const Queue *cur = &queues[priority];
+ const Queue* cur = &queues[priority];
return cur->data.empty();
}
@@ -139,7 +139,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..27560eb0b 100644
--- a/src/common/timer.cpp
+++ b/src/common/timer.cpp
@@ -16,11 +16,9 @@
#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 +33,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 +61,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 +105,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(&ltime);
- 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 +152,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 +162,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 +176,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..b2d630829 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,178 @@
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) {}
+ 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) {}
+ 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 +215,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 +379,42 @@ 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) {}
+ 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 +427,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 +507,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 +567,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 +601,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..19f1a4030 100644
--- a/src/common/x64/cpu_detect.cpp
+++ b/src/common/x64/cpu_detect.cpp
@@ -15,8 +15,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 +26,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 +82,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 +142,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 +168,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..1a9fd6a6b 100644
--- a/src/common/x64/emitter.cpp
+++ b/src/common/x64/emitter.cpp
@@ -26,179 +26,162 @@
#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 +197,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 +206,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,31 +219,27 @@ 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;
+ _operandReg = (X64Reg) this->operandReg;
int mod = 0;
int ireg = indexReg;
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 +248,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 +302,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 +360,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 +370,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 +434,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 +465,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 +744,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 +753,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 +788,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 +797,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 +809,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 +857,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 +893,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 +943,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 +1006,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 +1134,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 +1147,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 +1170,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 +1192,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 +1204,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 +1255,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 +1341,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 +1380,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 +1392,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 +1406,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 +1417,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 +1442,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 +1494,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 +1504,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 +1515,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 +1873,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 +1923,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 +1943,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..467f7812f 100644
--- a/src/common/x64/emitter.h
+++ b/src/common/x64/emitter.h
@@ -21,8 +21,8 @@
#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 +34,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 +184,7 @@ enum NormalOp {
nrmSUB,
nrmSBB,
nrmAND,
- nrmOR ,
+ nrmOR,
nrmXOR,
nrmMOV,
nrmTEST,
@@ -157,68 +227,74 @@ 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 +310,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 +362,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 +370,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 +405,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 +425,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 +446,38 @@ protected:
void Write64(u64 value);
public:
- XEmitter() { code = nullptr; flags_locked = false; }
- XEmitter(u8 *code_ptr) { code = code_ptr; flags_locked = false; }
- virtual ~XEmitter() {}
+ 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 +496,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 +517,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 +545,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 +558,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 +586,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 +613,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 +627,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 +696,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 +755,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 +813,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 +850,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 +960,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 +1134,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 +1164,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 +1206,4 @@ public:
void PoisonMemory() override;
};
-} // namespace
+} // namespace