From 964155940536d6b994b20d29364974ff1f635f34 Mon Sep 17 00:00:00 2001 From: David Geldreich Date: Sun, 1 Nov 2026 19:18:31 +0100 Subject: [PATCH] Fix sign_min/sign_max/sign_minmax on AArch64, and generic sign_minmax also fix minmax --- .../dsp/arch/aarch64/asimd/search/minmax.h | 39 +++++++++++-------- include/private/dsp/arch/generic/search.h | 2 +- src/test/utest/search/minmax.cpp | 2 +- src/test/utest/search/sign_max.cpp | 3 +- src/test/utest/search/sign_min.cpp | 3 +- src/test/utest/search/sign_minmax.cpp | 5 ++- 6 files changed, 31 insertions(+), 23 deletions(-) diff --git a/include/private/dsp/arch/aarch64/asimd/search/minmax.h b/include/private/dsp/arch/aarch64/asimd/search/minmax.h index cc2df447..4ebc78e3 100644 --- a/include/private/dsp/arch/aarch64/asimd/search/minmax.h +++ b/include/private/dsp/arch/aarch64/asimd/search/minmax.h @@ -411,8 +411,6 @@ namespace lsp __ASM_EMIT(OP " v1.16b, v19.16b, v5.16b") /* v1 = (fabsf(res1) <=> fabsf(x1)) ? res1 : x1 */ \ __ASM_EMIT(OP " v2.16b, v6.16b, v4.16b") /* v2 = (fabsf(res0) <=> fabsf(x0)) ? fabsf(res0) : fabsf(x0) */ \ __ASM_EMIT(OP " v3.16b, v7.16b, v5.16b") /* v3 = (fabsf(res1) <=> fabsf(x1)) ? fabsf(res1) : fabsf(x1) */ \ - __ASM_EMIT("subs %[count], %[count], #32") \ - __ASM_EMIT("add %[src], %[src], #0x80") \ __ASM_EMIT("sub %[count], %[count], #16") \ __ASM_EMIT("add %[src], %[src], #0x40") \ /* 8x block */ \ @@ -511,7 +509,7 @@ namespace lsp { ARCH_AARCH64_ASM( __ASM_EMIT("eor v0.16b, v0.16b, v0.16b") - __ASM_EMIT("eor v2.16b, v1.16b, v1.16b") + __ASM_EMIT("eor v1.16b, v1.16b, v1.16b") __ASM_EMIT("cmp %[count], #0") __ASM_EMIT("b.ls 12f") __ASM_EMIT("ld1r {v0.4s}, [%[src]]") /* v0 = min */ @@ -674,20 +672,26 @@ namespace lsp __ASM_EMIT("b.ge 9b") /* end */ __ASM_EMIT("10:") - __ASM_EMIT("ext v16.16b, v0.16b, v0.16b, #8") /* v16 = x0 */ - __ASM_EMIT("ext v6.16b, v2.16b, v2.16b, #8") /* v6 = fabsf(x0) */ - __ASM_EMIT("fcmgt v4.4s, v2.4s, v6.4s") /* v4 = [fabsf(min) > fabsf(x0)] */ - __ASM_EMIT("fcmgt v5.4s, v3.4s, v6.4s") /* v5 = [fabsf(max) > fabsf(x0)] */ - __ASM_EMIT("bit v0.16b, v16.16b, v4.16b") /* v0 = (fabsf(min) > fabsf(x0)) ? x0 : min */ - __ASM_EMIT("bif v1.16b, v16.16b, v5.16b") /* v1 = (fabsf(max) > fabsf(x0)) ? max : x0 */ - __ASM_EMIT("bit v2.16b, v6.16b, v4.16b") /* v2 = (fabsf(min) > fabsf(x0)) ? fabsf(x0) : fabsf(min) */ - __ASM_EMIT("bif v3.16b, v6.16b, v5.16b") /* v3 = (fabsf(max) > fabsf(x0)) ? fabsf(max) : fabsf(x0) */ - __ASM_EMIT("ext v16.16b, v0.16b, v0.16b, #4") /* v16 = x0 */ - __ASM_EMIT("ext v6.16b, v2.16b, v2.16b, #4") /* v6 = fabsf(x0) */ - __ASM_EMIT("fcmgt v4.4s, v2.4s, v6.4s") /* v4 = [fabsf(min) > fabsf(x0)] */ - __ASM_EMIT("fcmgt v5.4s, v3.4s, v6.4s") /* v5 = [fabsf(max) > fabsf(x0)] */ - __ASM_EMIT("bit v0.16b, v16.16b, v4.16b") /* v0 = (fabsf(min) > fabsf(x0)) ? x0 : min */ - __ASM_EMIT("bif v1.16b, v16.16b, v5.16b") /* v1 = (fabsf(max) > fabsf(x0)) ? max : x0 */ + __ASM_EMIT("ext v16.16b, v0.16b, v0.16b, #8") /* v16 = min candidates */ + __ASM_EMIT("ext v6.16b, v2.16b, v2.16b, #8") /* v6 = fabsf(min candidates) */ + __ASM_EMIT("ext v17.16b, v1.16b, v1.16b, #8") /* v17 = max candidates */ + __ASM_EMIT("ext v7.16b, v3.16b, v3.16b, #8") /* v7 = fabsf(max candidates) */ + __ASM_EMIT("fcmgt v4.4s, v2.4s, v6.4s") /* v4 = [fabsf(min) > fabsf(min candidates)] */ + __ASM_EMIT("fcmgt v5.4s, v3.4s, v7.4s") /* v5 = [fabsf(max) > fabsf(max candidates)] */ + __ASM_EMIT("bit v0.16b, v16.16b, v4.16b") /* v0 = (fabsf(min) > fabsf(min candidates)) ? min candidates : min */ + __ASM_EMIT("bif v1.16b, v17.16b, v5.16b") /* v1 = (fabsf(max) > fabsf(max candidates)) ? max : max candidates */ + __ASM_EMIT("bit v2.16b, v6.16b, v4.16b") /* v2 = (fabsf(min) > fabsf(min candidates)) ? fabsf(min candidates) : fabsf(min) */ + __ASM_EMIT("bif v3.16b, v7.16b, v5.16b") /* v3 = (fabsf(max) > fabsf(max candidates)) ? fabsf(max) : fabsf(max candidates) */ + __ASM_EMIT("ext v16.16b, v0.16b, v0.16b, #4") /* v16 = min candidates */ + __ASM_EMIT("ext v6.16b, v2.16b, v2.16b, #4") /* v6 = fabsf(min candidates) */ + __ASM_EMIT("ext v17.16b, v1.16b, v1.16b, #4") /* v17 = max candidates */ + __ASM_EMIT("ext v7.16b, v3.16b, v3.16b, #4") /* v7 = fabsf(max candidates) */ + __ASM_EMIT("fcmgt v4.4s, v2.4s, v6.4s") /* v4 = [fabsf(min) > fabsf(min candidates)] */ + __ASM_EMIT("fcmgt v5.4s, v3.4s, v7.4s") /* v5 = [fabsf(max) > fabsf(max candidates)] */ + __ASM_EMIT("bit v0.16b, v16.16b, v4.16b") /* v0 = (fabsf(min) > fabsf(min candidates)) ? min candidates : min */ + __ASM_EMIT("bif v1.16b, v17.16b, v5.16b") /* v1 = (fabsf(max) > fabsf(max candidates)) ? max : max candidates */ + __ASM_EMIT("bit v2.16b, v6.16b, v4.16b") /* v2 = (fabsf(min) > fabsf(min candidates)) ? fabsf(min candidates) : fabsf(min) */ + __ASM_EMIT("bif v3.16b, v7.16b, v5.16b") /* v3 = (fabsf(max) > fabsf(max candidates)) ? fabsf(max) : fabsf(max candidates) */ __ASM_EMIT("12:") /* store */ __ASM_EMIT("st1 {v0.s}[0], [%[min]]") @@ -696,6 +700,7 @@ namespace lsp : [min] "r" (min), [max] "r" (max) : "cc", "memory", "v0", "v1", "v2", "v3", + "v4", "v5", "v6", "v7", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23" ); diff --git a/include/private/dsp/arch/generic/search.h b/include/private/dsp/arch/generic/search.h index 98834447..ff4a4a0f 100644 --- a/include/private/dsp/arch/generic/search.h +++ b/include/private/dsp/arch/generic/search.h @@ -197,7 +197,7 @@ namespace lsp vmin = vtmp; amin = atmp; } - if (vtmp > amax) + if (atmp > amax) { vmax = vtmp; amax = atmp; diff --git a/src/test/utest/search/minmax.cpp b/src/test/utest/search/minmax.cpp index 6869782c..dc53541c 100644 --- a/src/test/utest/search/minmax.cpp +++ b/src/test/utest/search/minmax.cpp @@ -165,7 +165,7 @@ UTEST_BEGIN("dsp.search", minmax) UTEST_ASSERT_MSG(src.valid(), "Source buffer corrupted"); // Compare buffers - if ((!float_equals_relative(min1, min2, 1e-5)) && (!float_equals_relative(max1, max2, 1e-5))) + if ((!float_equals_relative(min1, min2, 1e-5)) || (!float_equals_relative(max1, max2, 1e-5))) { src.dump("src1"); UTEST_FAIL_MSG("Result of function 1 (%f, %f) differs result of function 2 (%f, %f)", min1, max1, min2, max2); diff --git a/src/test/utest/search/sign_max.cpp b/src/test/utest/search/sign_max.cpp index 408b5dbd..5adf7fdb 100644 --- a/src/test/utest/search/sign_max.cpp +++ b/src/test/utest/search/sign_max.cpp @@ -75,7 +75,8 @@ UTEST_BEGIN("dsp.search", sign_max) return; UTEST_FOREACH(count, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 32, 64, 65, 100, 768, 999, 1023, 1024, 1025) + 16, 17, 18, 19, 20, 24, 28, 31, 32, 48, 50, 63, 64, 65, 100, 768, + 999, 1023, 1024, 1025) { for (size_t mask=0; mask <= 0x01; ++mask) { diff --git a/src/test/utest/search/sign_min.cpp b/src/test/utest/search/sign_min.cpp index 893e954a..2b211829 100644 --- a/src/test/utest/search/sign_min.cpp +++ b/src/test/utest/search/sign_min.cpp @@ -75,7 +75,8 @@ UTEST_BEGIN("dsp.search", sign_min) return; UTEST_FOREACH(count, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 32, 64, 65, 100, 768, 999, 1023, 1024, 1025) + 16, 17, 18, 19, 20, 24, 28, 31, 32, 48, 50, 63, 64, 65, 100, 768, + 999, 1023, 1024, 1025) { for (size_t mask=0; mask <= 0x01; ++mask) { diff --git a/src/test/utest/search/sign_minmax.cpp b/src/test/utest/search/sign_minmax.cpp index bc19445d..3e3f7f70 100644 --- a/src/test/utest/search/sign_minmax.cpp +++ b/src/test/utest/search/sign_minmax.cpp @@ -75,7 +75,8 @@ UTEST_BEGIN("dsp.search", sign_minmax) return; UTEST_FOREACH(count, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 32, 64, 65, 100, 768, 999, 1023, 1024, 1025) + 16, 17, 18, 19, 20, 24, 28, 31, 48, 50, 63, 32, 64, 65, 100, 768, + 999, 1023, 1024, 1025) { for (size_t mask=0; mask <= 0x01; ++mask) { @@ -92,7 +93,7 @@ UTEST_BEGIN("dsp.search", sign_minmax) UTEST_ASSERT_MSG(src.valid(), "Source buffer corrupted"); // Compare buffers - if ((!float_equals_relative(min1, min2, 1e-5)) && (!float_equals_relative(max1, max2, 1e-5))) + if ((!float_equals_relative(min1, min2, 1e-5)) || (!float_equals_relative(max1, max2, 1e-5))) { src.dump("src1"); UTEST_FAIL_MSG("Result of function 1 (%f, %f) differs result of function 2 (%f, %f)", min1, max1, min2, max2);