From 054dabee3454ef811023dfa4f7ab1b805350f6cf Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Fri, 24 Jul 2026 03:47:08 +0000 Subject: [PATCH 05/38] avutil/ppc: add AltiVec vector_fmac/fmul_scalar, butterflies, scalarproduct Adds ff_vector_fmac_scalar_altivec, ff_vector_fmul_scalar_altivec, ff_butterflies_float_altivec, ff_scalarproduct_float_altivec to libavutil/ppc/float_dsp_altivec.c, wired into ff_float_dsp_init_ppc. Same style as the existing vec_ld/vec_madd/vec_st loops in this file; scalarproduct's horizontal sum goes through a 16-byte aligned stack temp (DECLARE_ALIGNED) since vec_st requires alignment. VALIDATED: checkasm float_dsp passes under the cross-PPC/qemu harness (qemu-ppc-static -cpu 7400), real ALTIVEC dispatch confirmed for all four functions against the C reference. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_0194bzLUrg6cVCQ7u4NNDpaB --- libavutil/ppc/float_dsp_altivec.c | 65 +++++++++++++++++++++++++++++++ libavutil/ppc/float_dsp_altivec.h | 11 ++++++ libavutil/ppc/float_dsp_init.c | 4 ++ 3 files changed, 80 insertions(+) diff --git a/libavutil/ppc/float_dsp_altivec.c b/libavutil/ppc/float_dsp_altivec.c index 6aa3e51..071a463 100644 --- a/libavutil/ppc/float_dsp_altivec.c +++ b/libavutil/ppc/float_dsp_altivec.c @@ -20,6 +20,7 @@ #include "util_altivec.h" #include "float_dsp_altivec.h" +#include "libavutil/mem_internal.h" void ff_vector_fmul_altivec(float *dst, const float *src0, const float *src1, int len) @@ -120,3 +121,67 @@ void ff_vector_fmul_reverse_altivec(float *dst, const float *src0, vec_st(d, 16, dst + i); } } + +void ff_vector_fmac_scalar_altivec(float *dst, const float *src, float mul, + int len) +{ + int i; + vec_f d0, d1, s0, s1, m = vec_splats(mul); + + for (i = 0; i < len - 7; i += 8) { + d0 = vec_ld( 0, dst + i); + d1 = vec_ld(16, dst + i); + s0 = vec_ld( 0, src + i); + s1 = vec_ld(16, src + i); + d0 = vec_madd(s0, m, d0); + d1 = vec_madd(s1, m, d1); + vec_st(d0, 0, dst + i); + vec_st(d1, 16, dst + i); + } +} + +void ff_vector_fmul_scalar_altivec(float *dst, const float *src, float mul, + int len) +{ + int i; + vec_f s, m = vec_splats(mul); + vec_f zero = (vec_f)vec_splat_u32(0); + + for (i = 0; i < len - 3; i += 4) { + s = vec_ld(0, src + i); + vec_st(vec_madd(s, m, zero), 0, dst + i); + } +} + +void ff_butterflies_float_altivec(float *restrict v1, float *restrict v2, + int len) +{ + int i; + vec_f a, b, sum, diff; + + for (i = 0; i < len - 3; i += 4) { + a = vec_ld(0, v1 + i); + b = vec_ld(0, v2 + i); + sum = vec_add(a, b); + diff = vec_sub(a, b); + vec_st(sum, 0, v1 + i); + vec_st(diff, 0, v2 + i); + } +} + +float ff_scalarproduct_float_altivec(const float *v1, const float *v2, int len) +{ + int i; + vec_f acc = (vec_f)vec_splat_u32(0); + vec_f a, b; + DECLARE_ALIGNED(16, float, sums)[4]; + + for (i = 0; i < len - 3; i += 4) { + a = vec_ld(0, v1 + i); + b = vec_ld(0, v2 + i); + acc = vec_madd(a, b, acc); + } + vec_st(acc, 0, sums); + + return sums[0] + sums[1] + sums[2] + sums[3]; +} diff --git a/libavutil/ppc/float_dsp_altivec.h b/libavutil/ppc/float_dsp_altivec.h index e1d530a..9db873e 100644 --- a/libavutil/ppc/float_dsp_altivec.h +++ b/libavutil/ppc/float_dsp_altivec.h @@ -35,4 +35,15 @@ void ff_vector_fmul_add_altivec(float *dst, const float *src0, void ff_vector_fmul_reverse_altivec(float *dst, const float *src0, const float *src1, int len); +void ff_vector_fmac_scalar_altivec(float *dst, const float *src, float mul, + int len); + +void ff_vector_fmul_scalar_altivec(float *dst, const float *src, float mul, + int len); + +void ff_butterflies_float_altivec(float *restrict v1, float *restrict v2, + int len); + +float ff_scalarproduct_float_altivec(const float *v1, const float *v2, int len); + #endif /* AVUTIL_PPC_FLOAT_DSP_ALTIVEC_H */ diff --git a/libavutil/ppc/float_dsp_init.c b/libavutil/ppc/float_dsp_init.c index 1d490bd..9336aa8 100644 --- a/libavutil/ppc/float_dsp_init.c +++ b/libavutil/ppc/float_dsp_init.c @@ -32,6 +32,10 @@ av_cold void ff_float_dsp_init_ppc(AVFloatDSPContext *fdsp, int bit_exact) fdsp->vector_fmul = ff_vector_fmul_altivec; fdsp->vector_fmul_add = ff_vector_fmul_add_altivec; fdsp->vector_fmul_reverse = ff_vector_fmul_reverse_altivec; + fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_altivec; + fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_altivec; + fdsp->butterflies_float = ff_butterflies_float_altivec; + fdsp->scalarproduct_float = ff_scalarproduct_float_altivec; if (!bit_exact) { fdsp->vector_fmul_window = ff_vector_fmul_window_altivec; -- 2.43.0