From 6613eb5776036cb0fee81d7ead1023a7c488c7b7 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Sun, 30 Aug 2026 21:53:28 +0200 Subject: [PATCH] Optimize NEON nibble mask setup using MOVI and hoist invariant initialization --- raid/neon.c | 10 +++++----- raid/neon32.c | 21 ++++++++++----------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/raid/neon.c b/raid/neon.c index b779db41..cd12e47f 100644 --- a/raid/neon.c +++ b/raid/neon.c @@ -262,9 +262,9 @@ static __always_inline void raid_genX_neon(int nd, size_t size, void **vv, int n /* generic case with at least two data disks */ asm volatile ( "ldr q29, %0\n" - "ldr q28, %1\n" + "movi v28.16b, #0x0f\n" : - : "m" (gfconst16.poly[0]), "m" (gfconst16.low4[0]) + : "m" (gfconst16.poly[0]) ); for (i = 0; i < size; i += 32) { @@ -641,9 +641,9 @@ static __always_inline void raid_recX_neon_12(int nr, int has_p, int *id, int *i raid_neon_begin(); - for (i = 0; i < size; i += 64) { - asm volatile ("ldr q31, %0" : : "m" (gfconst16.low4[0])); + asm volatile ("movi v31.16b, #0x0f"); + for (i = 0; i < size; i += 64) { /* start all selected syndromes from the stored parity */ asm volatile ("ldr q0, %0" : : "m" (p[0][i])); asm volatile ("ldr q1, %0" : : "m" (p[0][i + 16])); @@ -991,7 +991,7 @@ static __always_inline void raid_recX_neon(int nr, int has_p, int *id, int *ip, * V31 is reused during reconstruction, so reload the nibble mask * at the beginning of every iteration. */ - asm volatile ("ldr q31, %0" : : "m" (gfconst16.low4[0])); + asm volatile ("movi v31.16b, #0x0f"); /* start all selected syndromes from the stored parity */ asm volatile ("ldr q0, %0" : : "m" (p[0][i])); diff --git a/raid/neon32.c b/raid/neon32.c index ba2c7fec..98257ba3 100644 --- a/raid/neon32.c +++ b/raid/neon32.c @@ -256,9 +256,9 @@ static __always_inline void raid_genX_neon32(int nd, size_t size, /* generic case with at least two data disks */ asm volatile ( "vld1.8 {q14}, %0\n" - "vld1.8 {q15}, %1\n" + "vmov.i8 q15, #0x0f\n" : - : "Q" (gfconst16.poly[0]), "Q" (gfconst16.low4[0]) + : "Q" (gfconst16.poly[0]) ); for (i = 0; i < size; i += 16) { @@ -587,7 +587,7 @@ static __always_inline void raid_recX_neon32_123(int nr, int has_p, int *id, int * Reconstruction later reuses q15 as the second accumulator, * therefore reload it on every iteration. */ - asm volatile ("vld1.8 {q15}, %0" : : "Q" (gfconst16.low4[0])); + asm volatile ("vmov.i8 q15, #0x0f"); /* selected stored parity */ asm volatile ("vld1.8 {q0}, %0" : : "Q" (p[0][i])); @@ -891,7 +891,7 @@ static __always_inline void raid_recX_neon32(int nr, int has_p, int *id, int *ip * Q15 is the low-nibble mask during generation/splitting. * Reconstruction later reuses q15 as a multiplication temporary. */ - asm volatile ("vld1.8 {q15}, %0" : : "Q" (gfconst16.low4[0])); + asm volatile ("vmov.i8 q15, #0x0f"); /* * Raw syndrome registers: @@ -1255,14 +1255,13 @@ static __always_inline void raid_rec2of2_neon32(int *id, int *ip, int nd, size_t /* q15 = nibble mask, q9-q12 = C0/C1 low/high tables */ asm volatile ( - "vld1.8 {q15}, %0\n" - "vld1.8 {q9}, %1\n" - "vld1.8 {q10}, %2\n" - "vld1.8 {q11}, %3\n" - "vld1.8 {q12}, %4\n" + "vmov.i8 q15, #0x0f\n" + "vld1.8 {q9}, %0\n" + "vld1.8 {q10}, %1\n" + "vld1.8 {q11}, %2\n" + "vld1.8 {q12}, %3\n" : - : "Q" (gfconst16.low4[0]), - "Q" (raid_gfmulpshufb[C[0]][0][0]), + : "Q" (raid_gfmulpshufb[C[0]][0][0]), "Q" (raid_gfmulpshufb[C[0]][1][0]), "Q" (raid_gfmulpshufb[C[1]][0][0]), "Q" (raid_gfmulpshufb[C[1]][1][0])