mirror of
https://github.com/ARMSX2/ARMSX2.git
synced 2026-08-24 16:50:16 -07:00
FAST_UNALIGNED was defined only inside the ARCH_X86 arm, where it records that AVX-and-later cores stopped punishing unaligned vector loads. On ARM64 the macro was therefore undefined, which the preprocessor reads as zero, so every arm64 build compiled the texture-upload path as though the punishment existed. It never did. LDR Q and LD1 take any address, and GSVector4i's load template ignores its own `aligned` parameter and emits the same instruction either way. So the callers were paying for a distinction with no machine behind it: WriteImage tests the source address and the pitch on every call to choose between three template instantiations of WriteImageBlock and WriteImageColumn that, for 8- and 4-bit columns, compile to identical code. For 32- and 16-bit columns the unaligned arm is not identical, but it is the worse one — eight combining 64-bit loads instead of four 128-bit loads and a swizzle. Defining it collapses all of that. GSLocalMemoryMultiISA.cpp.o goes from 80,368 to 62,184 bytes of .text and from 58 emitted functions to 32, which is what an I-cache on a handheld cares about. Only GSBlock.h and GSLocalMemoryMultiISA.cpp read the macro, so nothing else moves. The retained load strategy is not new code: whenever an upload happened to land 32-byte aligned, arm64 already ran exactly this sequence. What goes away is the arm that only ever ran when it did not.
59 lines
1.5 KiB
C
59 lines
1.5 KiB
C
// SPDX-FileCopyrightText: 2002-2026 PCSX2 Dev Team
|
|
// SPDX-License-Identifier: GPL-3.0+
|
|
|
|
// Includes appropriate intrinsic header based on platform.
|
|
|
|
#pragma once
|
|
|
|
#include "common/Pcsx2Defs.h"
|
|
|
|
#if defined(ARCH_X86)
|
|
|
|
#ifdef _MSC_VER
|
|
#include <intrin.h>
|
|
#endif
|
|
|
|
#if defined(__AVX2__)
|
|
#define _M_SSE 0x501
|
|
#elif defined(__AVX__)
|
|
#define _M_SSE 0x500
|
|
#elif defined(__SSE4_1__)
|
|
#define _M_SSE 0x401
|
|
#else
|
|
#error PCSX2 requires compiling for at least SSE 4.1
|
|
#endif
|
|
|
|
// Starting with AVX, processors have fast unaligned loads
|
|
// Reduce code duplication by not compiling multiple versions
|
|
#if _M_SSE >= 0x500
|
|
#define FAST_UNALIGNED 1
|
|
#else
|
|
#define FAST_UNALIGNED 0
|
|
#endif
|
|
|
|
#include <xmmintrin.h>
|
|
#include <emmintrin.h>
|
|
#include <tmmintrin.h>
|
|
#include <smmintrin.h>
|
|
#include <immintrin.h>
|
|
|
|
#elif defined(ARCH_ARM64)
|
|
|
|
// AArch64 has no aligned/unaligned load distinction to begin with: LDR Q and LD1
|
|
// take any address, and GSVector4i::load<aligned> ignores its own parameter and
|
|
// emits the same instruction either way. Leaving this undefined made the callers
|
|
// pay for a distinction that does not exist — a runtime address-and-pitch test
|
|
// per texture upload, dispatching into three template instantiations that
|
|
// compile to identical code, and for 32/16-bit columns a worse load strategy
|
|
// (eight combining 64-bit loads instead of four 128-bit loads and a swizzle).
|
|
#define FAST_UNALIGNED 1
|
|
|
|
#include <arm_neon.h>
|
|
#endif
|
|
|
|
#ifdef __APPLE__
|
|
#include <stdlib.h> // alloca
|
|
#else
|
|
#include <malloc.h> // alloca
|
|
#endif
|