Skip to content

Commit b845330

Browse files
committed
[Memory Observer] Fix build outside x86, cache CPUID result for AVX2, fix styling,
1 parent a781f7e commit b845330

File tree

2 files changed

+31
-10
lines changed

2 files changed

+31
-10
lines changed

src/gui/widgets/memory_observer.cc

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,23 @@
1919

2020
#include "gui/widgets/memory_observer.h"
2121

22+
#ifdef MEMORY_OBSERVER_X86
2223
#include <xbyak_util.h>
24+
#endif
2325

2426
#include <magic_enum/include/magic_enum.hpp>
2527

2628
#include "core/psxemulator.h"
2729
#include "core/psxmem.h"
2830
#include "core/system.h"
2931

32+
PCSX::Widgets::MemoryObserver::MemoryObserver() {
33+
#ifdef MEMORY_OBSERVER_X86
34+
const auto cpu = Xbyak::util::Cpu();
35+
m_useSIMD = cpu.has(Xbyak::util::Cpu::tAVX2);
36+
#endif
37+
}
38+
3039
void PCSX::Widgets::MemoryObserver::draw(const char* title) {
3140
if (!ImGui::Begin(title, &m_show)) {
3241
ImGui::End();
@@ -204,10 +213,7 @@ void PCSX::Widgets::MemoryObserver::draw(const char* title) {
204213
}
205214

206215
if (ImGui::BeginTabItem(_("Pattern search"))) {
207-
const auto cpu = Xbyak::util::Cpu();
208-
const bool bHasAvx2 = cpu.has(Xbyak::util::Cpu::tAVX2);
209-
210-
if (bHasAvx2) {
216+
if (m_useSIMD) {
211217
ImGui::Text(_("Sequence size: "));
212218
ImGui::SameLine();
213219
ImGui::RadioButton(_("8 bytes (fast)"), &m_sequenceSize, 8);
@@ -222,10 +228,10 @@ void PCSX::Widgets::MemoryObserver::draw(const char* title) {
222228
ImGui::InputInt(_("Step"), &m_step);
223229

224230
if (ImGui::Button(_("Search"))) {
225-
if (bHasAvx2 && m_sequenceSize == 8) {
226-
avx2_populateAddressList<8>(memData, memBase, memSize);
227-
} else if (bHasAvx2 && m_sequenceSize == 16) {
228-
avx2_populateAddressList<16>(memData, memBase, memSize);
231+
if (m_useSIMD && m_sequenceSize == 8) {
232+
simd_populateAddressList<8>(memData, memBase, memSize);
233+
} else if (m_useSIMD && m_sequenceSize == 16) {
234+
simd_populateAddressList<16>(memData, memBase, memSize);
229235
} else {
230236
populateAddressList(memData, memBase, memSize);
231237
}
@@ -282,6 +288,7 @@ int PCSX::Widgets::MemoryObserver::getMemValue(uint32_t absoluteAddress, const u
282288
return memValue;
283289
}
284290

291+
#ifdef MEMORY_OBSERVER_X86
285292
bool PCSX::Widgets::MemoryObserver::all_equal(__m256i input) {
286293
const auto lane0 = _mm256_castsi256_si128(input);
287294
const auto tmp = _mm_shuffle_epi8(lane0, _mm_setzero_si128());
@@ -290,6 +297,7 @@ bool PCSX::Widgets::MemoryObserver::all_equal(__m256i input) {
290297

291298
return (static_cast<uint32_t>(_mm256_movemask_epi8(eq)) == 0xffffffff);
292299
}
300+
#endif // MEMORY_OBSERVER_X86
293301

294302
std::vector<uint8_t> PCSX::Widgets::MemoryObserver::getShuffleResultsFor(const std::vector<uint8_t>& buffer) {
295303
const size_t bufferSize = buffer.size();

src/gui/widgets/memory_observer.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,14 @@
2222
#include <stdint.h>
2323

2424
#include <array>
25+
#include <stdexcept>
2526
#include <vector>
2627

2728
#include "imgui.h"
29+
#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64) || defined(_M_AMD64)
30+
#define MEMORY_OBSERVER_X86 // Do not include immintrin/xbyak or use avx intrinsics unless we're compiling for x86
2831
#include "immintrin.h"
32+
#endif
2933

3034
namespace PCSX {
3135

@@ -35,6 +39,7 @@ class MemoryObserver {
3539
public:
3640
void draw(const char* title);
3741
bool m_show = false;
42+
MemoryObserver();
3843

3944
private:
4045
static int getMemValue(uint32_t absoluteAddress, const uint8_t* memData, uint32_t memSize, uint32_t memBase,
@@ -66,12 +71,14 @@ class MemoryObserver {
6671
ScanAlignment m_scanAlignment = ScanAlignment::OneByte;
6772
std::vector<AddressValuePair> m_addressValuePairs;
6873
bool m_hex = false;
74+
bool m_useSIMD = false;
6975
int m_value = 0;
7076

7177
/**
7278
* Pattern search.
7379
*/
7480

81+
#ifdef MEMORY_OBSERVER_X86
7582
template <int bufferSize>
7683
static __m256i avx2_getShuffleResultsFor(const std::array<uint8_t, bufferSize>& buffer,
7784
std::array<uint8_t, 32>& extendedBuffer, int mask) {
@@ -116,7 +123,7 @@ class MemoryObserver {
116123
}
117124

118125
template <int bufferSize>
119-
void avx2_populateAddressList(const uint8_t* memData, uint32_t memBase, uint32_t memSize) {
126+
void simd_populateAddressList(const uint8_t* memData, uint32_t memBase, uint32_t memSize) {
120127
static_assert(bufferSize == 8 || bufferSize == 16);
121128

122129
alignas(32) auto buffer = std::array<uint8_t, bufferSize>{};
@@ -150,8 +157,14 @@ class MemoryObserver {
150157
}
151158
}
152159
}
153-
154160
static bool all_equal(__m256i input);
161+
#else
162+
template <int bufferSize>
163+
void simd_populateAddressList(const uint8_t* memData, uint32_t memBase, uint32_t memSize) {
164+
throw std::runtime_error("SIMD pattern searching is not supported on this platform! This shouldn't have been called!");
165+
}
166+
#endif // MEMORY_OBSERVER_X86
167+
155168
static std::vector<uint8_t> getShuffleResultsFor(const std::vector<uint8_t>& buffer);
156169
static bool matchesPattern(const std::vector<uint8_t>& buffer, const std::vector<uint8_t>& patternShuffleResults);
157170
void populateAddressList(const uint8_t* memData, uint32_t memBase, uint32_t memSize);

0 commit comments

Comments
 (0)