From f043d91d958fde7eac0665c9e00f817d0a11ddef Mon Sep 17 00:00:00 2001
From: Sergey Fedorov <barracuda@macos-powerpc.org>
Date: Fri, 24 Jul 2026 04:10:12 +0000
Subject: [PATCH 07/38] avcodec/ppc: add AltiVec ff_put/avg_pixels8_altivec for
 hpeldsp

Adds exported 8-wide plain copy/average pixel helpers, matching the
existing ff_put/avg_pixels16_altivec pattern (rightside-alignment
vec_perm blend, since block is only guaranteed 8-byte aligned).
Wired into ff_hpeldsp_init_ppc's put_pixels_tab[1][0] /
avg_pixels_tab[1][0] (previously unset for put, previously pointed at
an unexported near-identical static avg_pixels8_altivec, now removed
as a duplicate).

VALIDATED: checkasm hpeldsp passes under the cross-PPC/qemu harness
(qemu-ppc-static -cpu 7400), real ALTIVEC dispatch confirmed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0194bzLUrg6cVCQ7u4NNDpaB
---
 libavcodec/ppc/hpeldsp_altivec.c | 62 ++++++++++++++++++++++----------
 libavcodec/ppc/hpeldsp_altivec.h |  4 +++
 2 files changed, 48 insertions(+), 18 deletions(-)

diff --git a/libavcodec/ppc/hpeldsp_altivec.c b/libavcodec/ppc/hpeldsp_altivec.c
index d8cf751..def7972 100644
--- a/libavcodec/ppc/hpeldsp_altivec.c
+++ b/libavcodec/ppc/hpeldsp_altivec.c
@@ -82,32 +82,57 @@ void ff_avg_pixels16_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t li
 }
 
 /* next one assumes that ((line_size % 8) == 0) */
-static void avg_pixels8_altivec(uint8_t * block, const uint8_t * pixels, ptrdiff_t line_size, int h)
+void ff_put_pixels8_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
 {
     register vector unsigned char pixelsv, blockv;
     int i;
 
-   for (i = 0; i < h; i++) {
-       /* block is 8 bytes-aligned, so we're either in the
-          left block (16 bytes-aligned) or in the right block (not) */
-       int rightside = ((unsigned long)block & 0x0000000F);
+    for (i = 0; i < h; i++) {
+        int rightside = ((unsigned long)block & 0x0000000F);
+
+        blockv = vec_ld(0, block);
+        pixelsv = VEC_LD(0, pixels);
 
-       blockv = vec_ld(0, block);
-       pixelsv = VEC_LD( 0, pixels);
+        if (rightside) {
+            pixelsv = vec_perm(blockv, pixelsv, vcprm(0,1,s0,s1));
+        } else {
+            pixelsv = vec_perm(blockv, pixelsv, vcprm(s0,s1,2,3));
+        }
 
-       if (rightside) {
-           pixelsv = vec_perm(blockv, pixelsv, vcprm(0,1,s0,s1));
-       } else {
-           pixelsv = vec_perm(blockv, pixelsv, vcprm(s0,s1,2,3));
-       }
+        vec_st(pixelsv, 0, block);
 
-       blockv = vec_avg(blockv, pixelsv);
+        pixels += line_size;
+        block += line_size;
+    }
+}
 
-       vec_st(blockv, 0, block);
+/* next one assumes that ((line_size % 8) == 0) */
+void ff_avg_pixels8_altivec(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
+{
+    register vector unsigned char pixelsv, blockv;
+    int i;
 
-       pixels += line_size;
-       block += line_size;
-   }
+    for (i = 0; i < h; i++) {
+        /* block is 8 bytes-aligned, so we're either in the
+           left block (16 bytes-aligned) or in the right block (not) */
+        int rightside = ((unsigned long)block & 0x0000000F);
+
+        blockv = vec_ld(0, block);
+        pixelsv = VEC_LD( 0, pixels);
+
+        if (rightside) {
+            pixelsv = vec_perm(blockv, pixelsv, vcprm(0,1,s0,s1));
+        } else {
+            pixelsv = vec_perm(blockv, pixelsv, vcprm(s0,s1,2,3));
+        }
+
+        blockv = vec_avg(blockv, pixelsv);
+
+        vec_st(blockv, 0, block);
+
+        pixels += line_size;
+        block += line_size;
+    }
 }
 
 /* next one assumes that ((line_size % 8) == 0) */
@@ -372,10 +397,11 @@ av_cold void ff_hpeldsp_init_ppc(HpelDSPContext *c, int flags)
         return;
 
     c->avg_pixels_tab[0][0]        = ff_avg_pixels16_altivec;
-    c->avg_pixels_tab[1][0]        = avg_pixels8_altivec;
+    c->avg_pixels_tab[1][0]        = ff_avg_pixels8_altivec;
     c->avg_pixels_tab[1][3]        = avg_pixels8_xy2_altivec;
 
     c->put_pixels_tab[0][0]        = ff_put_pixels16_altivec;
+    c->put_pixels_tab[1][0]        = ff_put_pixels8_altivec;
     c->put_pixels_tab[1][3]        = put_pixels8_xy2_altivec;
     c->put_pixels_tab[0][3]        = put_pixels16_xy2_altivec;
 
diff --git a/libavcodec/ppc/hpeldsp_altivec.h b/libavcodec/ppc/hpeldsp_altivec.h
index 590809f..ff377ac 100644
--- a/libavcodec/ppc/hpeldsp_altivec.h
+++ b/libavcodec/ppc/hpeldsp_altivec.h
@@ -30,5 +30,9 @@ void ff_avg_pixels16_altivec(uint8_t *block, const uint8_t *pixels,
                              ptrdiff_t line_size, int h);
 void ff_put_pixels16_altivec(uint8_t *block, const uint8_t *pixels,
                              ptrdiff_t line_size, int h);
+void ff_avg_pixels8_altivec(uint8_t *block, const uint8_t *pixels,
+                            ptrdiff_t line_size, int h);
+void ff_put_pixels8_altivec(uint8_t *block, const uint8_t *pixels,
+                            ptrdiff_t line_size, int h);
 
 #endif /* AVCODEC_PPC_HPELDSP_ALTIVEC_H */
-- 
2.43.0

