From 0b8dd2318002db2cc089930d6e2a3ad131eabdb8 Mon Sep 17 00:00:00 2001 From: George Steed Date: Sun, 27 Sep 2026 19:03:18 +0100 Subject: [PATCH] AArch64: Avoid LD4 in ARGBToARGB4444Row_NEON The existing ARGBToARGB4444Row_NEON implementation uses half-vector LD4s to load the four channels before using the ARGBTOARGB4444 macro to re-combine them. LD4 is known to be slow on some micro-architectures so should be avoided. Use LD2 instead to deinterleave the even and odd bytes directly, then combine them with SRI. Speedup versus the existing Neon implementation (higher is better): Cortex-A510: 1.822x Cortex-A55: 1.213x Cortex-A720: 2.302x Cortex-X4: 1.092x C1-Nano: 1.505x C1-Pro: 1.714x C1-Ultra: 1.302x Change-Id: If7d90f2d34d3ef146e5f41716a60d6f6436bde1d Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/8671363 Reviewed-by: Frank Barchard Reviewed-by: Justin Green --- source/row_neon64.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/row_neon64.cc b/source/row_neon64.cc index be554ae01..9b9c039f6 100644 --- a/source/row_neon64.cc +++ b/source/row_neon64.cc @@ -2567,17 +2567,17 @@ void ARGBToARGB4444Row_NEON(const uint8_t* src_argb, int width) { asm volatile( "1: \n" - "ld4 {v16.8b,v17.8b,v18.8b,v19.8b}, [%0], #32 \n" // load 8 - // pixels + "ld2 {v16.16b, v17.16b}, [%0], #32 \n" // load 8 pixels "subs %w2, %w2, #8 \n" // 8 processed per loop. - "prfm pldl1keep, [%0, 448] \n" ARGBTOARGB4444 - "st1 {v0.16b}, [%1], #16 \n" // store 8 pixels + "sri v17.16b, v16.16b, #4 \n" + "prfm pldl1keep, [%0, 448] \n" + "st1 {v17.16b}, [%1], #16 \n" // store 8 pixels "b.gt 1b \n" : "+r"(src_argb), // %0 "+r"(dst_argb4444), // %1 "+r"(width) // %2 : - : "cc", "memory", "v0", "v1", "v16", "v17", "v18", "v19"); + : "cc", "memory", "v16", "v17"); } #if defined(LIBYUV_USE_ST2)