diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8a4f105253..c1860a2b53 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -781,7 +781,8 @@ add_library(Common STATIC
Common/Input/InputState.cpp
Common/Input/InputState.h
Common/Math/fast/fast_matrix.c
- Common/Math/CrossSIMD.h
+ Common/Math/SIMDHeaders.h
+ Common/Math/SIMDHeaders.h
Common/Math/curves.cpp
Common/Math/curves.h
Common/Math/expression_parser.cpp
diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj
index 5bd451bf9e..7dc1972107 100644
--- a/Common/Common.vcxproj
+++ b/Common/Common.vcxproj
@@ -541,6 +541,7 @@
+
diff --git a/Common/Common.vcxproj.filters b/Common/Common.vcxproj.filters
index d14b052ef5..fb0e5273ac 100644
--- a/Common/Common.vcxproj.filters
+++ b/Common/Common.vcxproj.filters
@@ -676,6 +676,9 @@
Data\Collections
+
+ Math
+
diff --git a/Common/Data/Convert/SmallDataConvert.h b/Common/Data/Convert/SmallDataConvert.h
index f0d9f1846a..cdbfc3c5b2 100644
--- a/Common/Data/Convert/SmallDataConvert.h
+++ b/Common/Data/Convert/SmallDataConvert.h
@@ -6,7 +6,7 @@
#include "Common/Common.h"
#include "ppsspp_config.h"
-#include "Common/Math/CrossSIMD.h"
+#include "Common/Math/SIMDHeaders.h"
extern const float one_over_255_x4[4];
diff --git a/Common/Math/CrossSIMD.h b/Common/Math/CrossSIMD.h
index 408f93fe48..6ad03b8322 100644
--- a/Common/Math/CrossSIMD.h
+++ b/Common/Math/CrossSIMD.h
@@ -1,67 +1,8 @@
// CrossSIMD
//
-// Compatibility wrappers for SIMD dialects.
-//
-// In the long run, might do a more general single-source-SIMD wrapper here consisting
-// of defines that translate to either NEON or SSE. It would be possible to write quite a lot of
-// our various color conversion functions and so on in a pretty generic manner.
+// This file will contain cross-instruction-set SIMD instruction wrappers.
#pragma once
-#include "ppsspp_config.h"
+#include "Common/Math/SIMDHeaders.h"
-#include "stdint.h"
-
-#ifdef __clang__
-// Weird how you can't just use #pragma in a macro.
-#define DO_NOT_VECTORIZE_LOOP _Pragma("clang loop vectorize(disable)")
-#else
-#define DO_NOT_VECTORIZE_LOOP
-#endif
-
-#if PPSSPP_ARCH(SSE2)
-#include
-#endif
-
-#if PPSSPP_ARCH(ARM_NEON)
-#if defined(_MSC_VER) && PPSSPP_ARCH(ARM64)
-#include
-#else
-#include
-#endif
-#endif
-
-// Basic types
-
-#if PPSSPP_ARCH(ARM64_NEON)
-
-// No special ones here.
-
-#elif PPSSPP_ARCH(ARM_NEON)
-
-// Compatibility wrappers making ARM64 NEON code run on ARM32
-// With optimization on, these should compile down to the optimal code.
-
-static inline float32x4_t vmulq_laneq_f32(float32x4_t a, float32x4_t b, int lane) {
- switch (lane & 3) {
- case 0: return vmulq_lane_f32(a, vget_low_f32(b), 0);
- case 1: return vmulq_lane_f32(a, vget_low_f32(b), 1);
- case 2: return vmulq_lane_f32(a, vget_high_f32(b), 0);
- default: return vmulq_lane_f32(a, vget_high_f32(b), 1);
- }
-}
-
-static inline float32x4_t vmlaq_laneq_f32(float32x4_t a, float32x4_t b, float32x4_t c, int lane) {
- switch (lane & 3) {
- case 0: return vmlaq_lane_f32(a, b, vget_low_f32(c), 0);
- case 1: return vmlaq_lane_f32(a, b, vget_low_f32(c), 1);
- case 2: return vmlaq_lane_f32(a, b, vget_high_f32(c), 0);
- default: return vmlaq_lane_f32(a, b, vget_high_f32(c), 1);
- }
-}
-
-static inline uint32x4_t vcgezq_f32(float32x4_t v) {
- return vcgeq_f32(v, vdupq_n_f32(0.0f));
-}
-
-#endif
diff --git a/Common/Math/SIMDHeaders.h b/Common/Math/SIMDHeaders.h
new file mode 100644
index 0000000000..eac20127d9
--- /dev/null
+++ b/Common/Math/SIMDHeaders.h
@@ -0,0 +1,66 @@
+#pragma once
+
+// SIMD headers
+// Let's include these in one consistent way across the code base.
+// Here we'll also add wrappers that paper over differences between different versions
+// of an instruction set, like NEON vs ASIMD (64-bit).
+
+#pragma once
+
+#include "ppsspp_config.h"
+
+#include "stdint.h"
+
+#ifdef __clang__
+// Weird how you can't just use #pragma in a macro.
+#define DO_NOT_VECTORIZE_LOOP _Pragma("clang loop vectorize(disable)")
+#else
+#define DO_NOT_VECTORIZE_LOOP
+#endif
+
+#if PPSSPP_ARCH(SSE2)
+#include
+#endif
+
+#if PPSSPP_ARCH(ARM_NEON)
+#if defined(_MSC_VER) && PPSSPP_ARCH(ARM64)
+#include
+#else
+#include
+#endif
+#endif
+
+// Basic types
+
+#if PPSSPP_ARCH(ARM64_NEON)
+
+// No special ones here.
+
+#elif PPSSPP_ARCH(ARM_NEON)
+
+// Compatibility wrappers making ARM64 NEON code run on ARM32
+// With optimization on, these should compile down to the optimal code.
+
+static inline float32x4_t vmulq_laneq_f32(float32x4_t a, float32x4_t b, int lane) {
+ switch (lane & 3) {
+ case 0: return vmulq_lane_f32(a, vget_low_f32(b), 0);
+ case 1: return vmulq_lane_f32(a, vget_low_f32(b), 1);
+ case 2: return vmulq_lane_f32(a, vget_high_f32(b), 0);
+ default: return vmulq_lane_f32(a, vget_high_f32(b), 1);
+ }
+}
+
+static inline float32x4_t vmlaq_laneq_f32(float32x4_t a, float32x4_t b, float32x4_t c, int lane) {
+ switch (lane & 3) {
+ case 0: return vmlaq_lane_f32(a, b, vget_low_f32(c), 0);
+ case 1: return vmlaq_lane_f32(a, b, vget_low_f32(c), 1);
+ case 2: return vmlaq_lane_f32(a, b, vget_high_f32(c), 0);
+ default: return vmlaq_lane_f32(a, b, vget_high_f32(c), 1);
+ }
+}
+
+static inline uint32x4_t vcgezq_f32(float32x4_t v) {
+ return vcgeq_f32(v, vdupq_n_f32(0.0f));
+}
+
+#endif
diff --git a/Common/Math/fast/fast_matrix.c b/Common/Math/fast/fast_matrix.c
index c6f24ddf13..13d202e5e7 100644
--- a/Common/Math/fast/fast_matrix.c
+++ b/Common/Math/fast/fast_matrix.c
@@ -1,6 +1,6 @@
#include "ppsspp_config.h"
-#include "Common/Math/CrossSIMD.h"
+#include "Common/Math/SIMDHeaders.h"
#include "fast_matrix.h"
diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp
index 5711374c62..778209883c 100644
--- a/Core/HLE/ReplaceTables.cpp
+++ b/Core/HLE/ReplaceTables.cpp
@@ -39,7 +39,7 @@
#include "GPU/Math3D.h"
#include "GPU/GPU.h"
#include "GPU/GPUCommon.h"
-#include "Common/Math/CrossSIMD.h"
+#include "Common/Math/SIMDHeaders.h"
enum class GPUReplacementSkip {
MEMSET = 1,
diff --git a/Core/HW/MediaEngine.cpp b/Core/HW/MediaEngine.cpp
index 81ba147e25..34dfcc8c48 100644
--- a/Core/HW/MediaEngine.cpp
+++ b/Core/HW/MediaEngine.cpp
@@ -16,7 +16,7 @@
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "Common/Serialize/SerializeFuncs.h"
-#include "Common/Math/CrossSIMD.h"
+#include "Common/Math/SIMDHeaders.h"
#include "Core/System.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/HW/MediaEngine.h"
diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp
index 58d4877a6f..818021a79b 100644
--- a/GPU/Common/DrawEngineCommon.cpp
+++ b/GPU/Common/DrawEngineCommon.cpp
@@ -21,7 +21,7 @@
#include "Common/Data/Convert/ColorConv.h"
#include "Common/Profiler/Profiler.h"
#include "Common/LogReporting.h"
-#include "Common/Math/CrossSIMD.h"
+#include "Common/Math/SIMDHeaders.h"
#include "Common/Math/lin/matrix4x4.h"
#include "Core/Config.h"
#include "GPU/Common/DrawEngineCommon.h"
diff --git a/GPU/Common/IndexGenerator.cpp b/GPU/Common/IndexGenerator.cpp
index 1094a70731..0488ab5cc9 100644
--- a/GPU/Common/IndexGenerator.cpp
+++ b/GPU/Common/IndexGenerator.cpp
@@ -20,7 +20,7 @@
#include "ppsspp_config.h"
#include "Common/Common.h"
-#include "Common/Math/CrossSIMD.h"
+#include "Common/Math/SIMDHeaders.h"
#include "GPU/Common/IndexGenerator.h"
// Points don't need indexing...
diff --git a/GPU/Common/TextureDecoder.cpp b/GPU/Common/TextureDecoder.cpp
index 63c23c11b1..985c5d6805 100644
--- a/GPU/Common/TextureDecoder.cpp
+++ b/GPU/Common/TextureDecoder.cpp
@@ -21,12 +21,12 @@
#include "Common/Common.h"
#include "Common/Log.h"
-#include "Common/Math/CrossSIMD.h"
+#include "Common/Math/SIMDHeaders.h"
#include "GPU/GPUState.h"
#include "GPU/Common/TextureDecoder.h"
-#include "Common/Math/CrossSIMD.h"
+#include "Common/Math/SIMDHeaders.h"
const u8 textureBitsPerPixel[16] = {
16, //GE_TFMT_5650,
diff --git a/GPU/Common/TextureScalerCommon.cpp b/GPU/Common/TextureScalerCommon.cpp
index 270d3a535c..4603638af9 100644
--- a/GPU/Common/TextureScalerCommon.cpp
+++ b/GPU/Common/TextureScalerCommon.cpp
@@ -28,7 +28,7 @@
#include "Common/Thread/ParallelLoop.h"
#include "ext/xbrz/xbrz.h"
-#include "Common/Math/CrossSIMD.h"
+#include "Common/Math/SIMDHeaders.h"
// Report the time and throughput for each larger scaling operation in the log
diff --git a/GPU/Common/VertexDecoderHandwritten.cpp b/GPU/Common/VertexDecoderHandwritten.cpp
index 1860bf806b..7592f49545 100644
--- a/GPU/Common/VertexDecoderHandwritten.cpp
+++ b/GPU/Common/VertexDecoderHandwritten.cpp
@@ -3,7 +3,7 @@
#include "GPU/Common/VertexDecoderCommon.h"
#include "GPU/GPUState.h"
-#include "Common/Math/CrossSIMD.h"
+#include "Common/Math/SIMDHeaders.h"
// Candidates for hand-writing
// (found using our custom Very Sleepy).
diff --git a/GPU/GPUCommon.cpp b/GPU/GPUCommon.cpp
index f75ab4db31..da5a483336 100644
--- a/GPU/GPUCommon.cpp
+++ b/GPU/GPUCommon.cpp
@@ -6,7 +6,7 @@
#include "Common/GraphicsContext.h"
#include "Common/LogReporting.h"
-#include "Common/Math/CrossSIMD.h"
+#include "Common/Math/SIMDHeaders.h"
#include "Common/Serialize/Serializer.h"
#include "Common/Serialize/SerializeFuncs.h"
#include "Common/Serialize/SerializeList.h"
diff --git a/GPU/GPUState.cpp b/GPU/GPUState.cpp
index 8c0ba853ea..03b7722730 100644
--- a/GPU/GPUState.cpp
+++ b/GPU/GPUState.cpp
@@ -23,7 +23,7 @@
#include "GPU/ge_constants.h"
#include "GPU/GPUCommon.h"
#include "GPU/GPUState.h"
-#include "Common/Math/CrossSIMD.h"
+#include "Common/Math/SIMDHeaders.h"
// This must be aligned so that the matrices within are aligned.
alignas(16) GPUgstate gstate;
diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp
index 87d0210e2e..8613a92d6b 100644
--- a/GPU/Software/Rasterizer.cpp
+++ b/GPU/Software/Rasterizer.cpp
@@ -36,7 +36,7 @@
#include "GPU/Software/SoftGpu.h"
#include "GPU/Software/TransformUnit.h"
-#include "Common/Math/CrossSIMD.h"
+#include "Common/Math/SIMDHeaders.h"
namespace Rasterizer {
diff --git a/GPU/Software/RasterizerRectangle.cpp b/GPU/Software/RasterizerRectangle.cpp
index d5d1ca6b4f..a40bb2ae87 100644
--- a/GPU/Software/RasterizerRectangle.cpp
+++ b/GPU/Software/RasterizerRectangle.cpp
@@ -17,7 +17,7 @@
#include "GPU/Software/Rasterizer.h"
#include "GPU/Software/Sampler.h"
#include "GPU/Software/SoftGpu.h"
-#include "Common/Math/CrossSIMD.h"
+#include "Common/Math/SIMDHeaders.h"
extern DSStretch g_DarkStalkerStretch;
// For Darkstalkers hack. Ugh.
diff --git a/GPU/Software/Sampler.cpp b/GPU/Software/Sampler.cpp
index 631f15edb8..284bbb747d 100644
--- a/GPU/Software/Sampler.cpp
+++ b/GPU/Software/Sampler.cpp
@@ -21,7 +21,7 @@
#include "Common/Common.h"
#include "Common/Data/Convert/ColorConv.h"
#include "Common/LogReporting.h"
-#include "Common/Math/CrossSIMD.h"
+#include "Common/Math/SIMDHeaders.h"
#include "Core/Config.h"
#include "GPU/Common/TextureDecoder.h"
#include "GPU/Software/BinManager.h"