From a7a38b3d19a41590a959b63db7cf0be682f98a54 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Tue, 28 Jul 2026 02:46:25 +0000 Subject: [PATCH 6/6] PPC: Add AltiVec 8-tap subpel motion-compensation kernels (put/prep) New 8bpc put_8tap and prep_8tap kernels for the big-endian AltiVec (G4/G5) sub-target, covering all nine regular/smooth/sharp filter combinations plus the integer-MV copy and prep pixel-widening cases. Subpel MC is the hottest DSP family in inter decode and previously ran scalar C on these machines. Horizontal filtering loads the 15/16 source bytes for 8 outputs once and shuffles them into per-output 4-byte groups for vmsummbm (signed taps x unsigned pixels, summed into 32-bit lanes): one load, three permutes and four multiply-sums per 8 pixels. Vertical filtering on pixels byte- transposes the 8 sliding row registers into the same form with two merge levels; the 2D second pass runs vmsumshm on interleaved 16-bit row pairs from the mid buffer. Rounding mirrors src/mc_tmpl.c for intermediate_bits=4; the documented intermediate range [-5132, 9212] guarantees the saturating i32->i16 packs are exact and vec_packsu implements iclip_pixel. Registered under ARCH_PPC && !ARCH_PPC64LE only; the ppc64le build is unchanged. Verified bit-exact vs the C reference with checkasm under qemu-ppc (-cpu 7400, 32-bit big-endian): mc_8bpc.mc and mc_8bpc.mct pass for every filter/width/height/subpel combination (1473 tests), full suite regression-clean. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_011ufaEhvCRX9nswQTF2pzdN --- src/ppc/mc.h | 35 +++- src/ppc/mc_tmpl.c | 409 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 442 insertions(+), 2 deletions(-) diff --git a/src/ppc/mc.h b/src/ppc/mc.h index 1101fa3a..cf207206 100644 --- a/src/ppc/mc.h +++ b/src/ppc/mc.h @@ -38,11 +38,26 @@ decl_blend_dir_fn(BF(dav1d_blend_h, pwr9)); decl_blend_dir_fn(BF(dav1d_blend_v, pwr9)); #if !ARCH_PPC64LE -/* Compound-prediction kernels only built for the big-endian AltiVec (G4/G5) - * sub-target; ppc64le would need separate little-endian verification. */ +/* Compound-prediction and 8-tap subpel kernels only built for the big-endian + * AltiVec (G4/G5) sub-target; ppc64le would need separate LE verification. */ decl_avg_fn(BF(dav1d_avg, altivec)); decl_w_avg_fn(BF(dav1d_w_avg, altivec)); decl_mask_fn(BF(dav1d_mask, altivec)); + +#define decl_8tap_fns(type) \ +decl_mc_fn(BF(dav1d_put_8tap_##type, altivec)); \ +decl_mct_fn(BF(dav1d_prep_8tap_##type, altivec)) + +decl_8tap_fns(regular); +decl_8tap_fns(regular_sharp); +decl_8tap_fns(regular_smooth); +decl_8tap_fns(smooth); +decl_8tap_fns(smooth_regular); +decl_8tap_fns(smooth_sharp); +decl_8tap_fns(sharp); +decl_8tap_fns(sharp_regular); +decl_8tap_fns(sharp_smooth); +#undef decl_8tap_fns #endif #endif @@ -61,6 +76,22 @@ static ALWAYS_INLINE void mc_dsp_init_ppc(Dav1dMCDSPContext *const c) { c->avg = BF(dav1d_avg, altivec); c->w_avg = BF(dav1d_w_avg, altivec); c->mask = BF(dav1d_mask, altivec); + +#define init_8tap_fns(type, name) do { \ + c->mc [type] = BF(dav1d_put_8tap_##name, altivec); \ + c->mct[type] = BF(dav1d_prep_8tap_##name, altivec); \ +} while (0) + + init_8tap_fns(FILTER_2D_8TAP_REGULAR, regular); + init_8tap_fns(FILTER_2D_8TAP_REGULAR_SMOOTH, regular_smooth); + init_8tap_fns(FILTER_2D_8TAP_REGULAR_SHARP, regular_sharp); + init_8tap_fns(FILTER_2D_8TAP_SHARP_REGULAR, sharp_regular); + init_8tap_fns(FILTER_2D_8TAP_SHARP_SMOOTH, sharp_smooth); + init_8tap_fns(FILTER_2D_8TAP_SHARP, sharp); + init_8tap_fns(FILTER_2D_8TAP_SMOOTH_REGULAR, smooth_regular); + init_8tap_fns(FILTER_2D_8TAP_SMOOTH, smooth); + init_8tap_fns(FILTER_2D_8TAP_SMOOTH_SHARP, smooth_sharp); +#undef init_8tap_fns #endif #endif #else diff --git a/src/ppc/mc_tmpl.c b/src/ppc/mc_tmpl.c index 6f73bb5d..e62b15bc 100644 --- a/src/ppc/mc_tmpl.c +++ b/src/ppc/mc_tmpl.c @@ -764,6 +764,415 @@ void dav1d_mask_8bpc_altivec(pixel *dst, const ptrdiff_t dst_stride, } } +/* + * 8-tap subpel motion compensation (put + prep), the hottest DSP family in + * inter decode. Horizontal filtering uses vmsummbm (vec_msum on signed-taps x + * unsigned-pixels byte groups of 4): the 15/16 source bytes for 8 outputs are + * loaded once and shuffled into per-output 4-byte groups, so each group of 8 + * pixels costs one load, three permutes and four multiply-sums. Vertical + * filtering on pixels byte-transposes 4 rows per column group (two merge + * levels) into the same vmsummbm form; vertical filtering on the 16-bit + * intermediate (the 2D case) uses vmsumshm on interleaved row pairs. + * + * 8bpc rounding mirrors src/mc_tmpl.c: intermediate_bits = 4, so + * put h: (sum + 34) >> 6 put v: (sum + 32) >> 6 + * mid: (sum + 2) >> 2 put hv second pass: (sum + 512) >> 10 + * prep h/v: (sum + 2) >> 2 prep hv second pass: (sum + 32) >> 6 + * All 32-bit sums are packed with saturating vec_packs; the value ranges + * (documented in src/mc_tmpl.c: intermediate range [-5132, 9212]) guarantee + * the i32->i16 packs are exact, and the final vec_packsu is iclip_pixel. + */ + +/* Build the two byte-group tap vectors {f0..f3}x4 / {f4..f7}x4. */ +#define H8TAPS(fh, tapsA, tapsB) \ + const i8x16 tapsA = {fh[0],fh[1],fh[2],fh[3], fh[0],fh[1],fh[2],fh[3], \ + fh[0],fh[1],fh[2],fh[3], fh[0],fh[1],fh[2],fh[3]}; \ + const i8x16 tapsB = {fh[4],fh[5],fh[6],fh[7], fh[4],fh[5],fh[6],fh[7], \ + fh[4],fh[5],fh[6],fh[7], fh[4],fh[5],fh[6],fh[7]} + +/* 8 horizontal 8-tap sums from the 16 bytes at ptr (= &src[x - 3]): + * s03/s47 are i32x4 accumulators seeded with accv. Output j needs bytes + * j..j+7; groups of four taps make that bytes j..j+3 (perm base 0) and + * j+4..j+7 (perm base 4), with outputs 4..7 reusing base 4 and adding base 8. */ +#define H8TAP_SUMS(s03, s47, ptr, tapsA, tapsB, accv) \ + const u8x16 s03##_v = vec_xl(0, ptr); \ + const u8x16 s03##_a = vec_perm(s03##_v, s03##_v, \ + (u8x16){0,1,2,3, 1,2,3,4, 2,3,4,5, 3,4,5,6}); \ + const u8x16 s03##_b = vec_perm(s03##_v, s03##_v, \ + (u8x16){4,5,6,7, 5,6,7,8, 6,7,8,9, 7,8,9,10}); \ + const u8x16 s03##_c = vec_perm(s03##_v, s03##_v, \ + (u8x16){8,9,10,11, 9,10,11,12, 10,11,12,13, 11,12,13,14}); \ + const i32x4 s03 = vec_msum(tapsB, s03##_b, vec_msum(tapsA, s03##_a, accv)); \ + const i32x4 s47 = vec_msum(tapsB, s03##_c, vec_msum(tapsA, s03##_b, accv)) + +static inline void store_wN(uint8_t *dst, u8x16 v, const int w) { + ALIGN_STK_16(uint8_t, buf, 16,); + vec_st(v, 0, buf); + memcpy(dst, buf, w); +} + +static void put_8tap_h_altivec(pixel *dst, const ptrdiff_t dst_stride, + const pixel *src, const ptrdiff_t src_stride, + const int w, int h, const int8_t *const fh) +{ + const i32x4 accv = vec_splats((int32_t)34); // 32 + ((1 << 2) >> 1) + const u32x4 shv = vec_splats(6u); + H8TAPS(fh, tapsA, tapsB); + + if (w <= 8) { + do { + H8TAP_SUMS(s03, s47, src - 3, tapsA, tapsB, accv); + const i16x8 t = vec_packs(vec_sra(s03, shv), vec_sra(s47, shv)); + store_wN(dst, vec_packsu(t, t), w); + dst += PXSTRIDE(dst_stride); + src += PXSTRIDE(src_stride); + } while (--h); + } else { + do { + for (int x = 0; x < w; x += 16) { + H8TAP_SUMS(s03, s47, src + x - 3, tapsA, tapsB, accv); + H8TAP_SUMS(s8b, scf, src + x + 5, tapsA, tapsB, accv); + const i16x8 t0 = vec_packs(vec_sra(s03, shv), vec_sra(s47, shv)); + const i16x8 t1 = vec_packs(vec_sra(s8b, shv), vec_sra(scf, shv)); + vec_xst(vec_packsu(t0, t1), 0, dst + x); + } + dst += PXSTRIDE(dst_stride); + src += PXSTRIDE(src_stride); + } while (--h); + } +} + +static void prep_8tap_h_altivec(int16_t *tmp, const pixel *src, + const ptrdiff_t src_stride, + const int w, int h, const int8_t *const fh) +{ + const i32x4 accv = vec_splats((int32_t)2); // (1 << 2) >> 1 + const u32x4 shv = vec_splats(2u); // 6 - intermediate_bits + H8TAPS(fh, tapsA, tapsB); + + do { + if (w <= 4) { + H8TAP_SUMS(s03, s47, src - 3, tapsA, tapsB, accv); + const i16x8 t = vec_packs(vec_sra(s03, shv), vec_sra(s47, shv)); + ALIGN_STK_16(int16_t, buf, 8,); + vec_st(t, 0, buf); + memcpy(tmp, buf, 2 * w); + } else for (int x = 0; x < w; x += 8) { + H8TAP_SUMS(s03, s47, src + x - 3, tapsA, tapsB, accv); + vec_xst(vec_packs(vec_sra(s03, shv), vec_sra(s47, shv)), 0, tmp + x); + } + tmp += w; + src += PXSTRIDE(src_stride); + } while (--h); +} + +/* Vertical 8-tap: byte-transpose the 8 sliding row registers into per-column + * 4-byte groups (rows 0-3 then rows 4-7) and vmsummbm them, 8 columns at a + * time. cols 0-3 of rows 0-3 = mergeh(mergeh(r0,r1) as u16, mergeh(r2,r3)). */ +#define V8TAP_QUAD(q0, q1, ra, rb, rc, rd, mh) \ + const u8x16 q0##_ab = mh(ra, rb); \ + const u8x16 q0##_cd = mh(rc, rd); \ + const u8x16 q0 = (u8x16)vec_mergeh((u16x8)q0##_ab, (u16x8)q0##_cd); \ + const u8x16 q1 = (u8x16)vec_mergel((u16x8)q0##_ab, (u16x8)q0##_cd) + +#define V8TAP_SUMS8(s03, s47, uniq, r0, r1, r2, r3, r4, r5, r6, r7, tapsA, tapsB, accv, mh) \ + V8TAP_QUAD(uniq##q0, uniq##q1, r0, r1, r2, r3, mh); \ + V8TAP_QUAD(uniq##q2, uniq##q3, r4, r5, r6, r7, mh); \ + const i32x4 s03 = vec_msum(tapsB, uniq##q2, vec_msum(tapsA, uniq##q0, accv)); \ + const i32x4 s47 = vec_msum(tapsB, uniq##q3, vec_msum(tapsA, uniq##q1, accv)) + +#define V8TAP_SLIDE \ + r0 = r1; r1 = r2; r2 = r3; r3 = r4; r4 = r5; r5 = r6; r6 = r7 + +/* is_put: rounding 32 >> 6 and pixel output; else prep: 2 >> 2, int16_t. */ +static ALWAYS_INLINE void v8tap_altivec(pixel *dst, const ptrdiff_t dst_stride, + int16_t *tmp, + const pixel *src, const ptrdiff_t src_stride, + const int w, const int h, + const int8_t *const fv, + const i32x4 accv, const u32x4 shv, + const int is_put) +{ + H8TAPS(fv, tapsA, tapsB); + const ptrdiff_t stride = PXSTRIDE(src_stride); + + if (w <= 8) { + const pixel *s = src - 3 * stride; + u8x16 r0 = vec_xl(0, s); + u8x16 r1 = vec_xl(0, s + 1 * stride); + u8x16 r2 = vec_xl(0, s + 2 * stride); + u8x16 r3 = vec_xl(0, s + 3 * stride); + u8x16 r4 = vec_xl(0, s + 4 * stride); + u8x16 r5 = vec_xl(0, s + 5 * stride); + u8x16 r6 = vec_xl(0, s + 6 * stride); + s += 7 * stride; + for (int y = 0; y < h; y++) { + const u8x16 r7 = vec_xl(0, s); + V8TAP_SUMS8(s03, s47, a, r0, r1, r2, r3, r4, r5, r6, r7, + tapsA, tapsB, accv, vec_mergeh); + const i16x8 t = vec_packs(vec_sra(s03, shv), vec_sra(s47, shv)); + if (is_put) { + store_wN(dst, vec_packsu(t, t), w); + dst += PXSTRIDE(dst_stride); + } else { + if (w == 8) { + vec_xst(t, 0, tmp); + } else { + ALIGN_STK_16(int16_t, buf, 8,); + vec_st(t, 0, buf); + memcpy(tmp, buf, 2 * w); + } + tmp += w; + } + V8TAP_SLIDE; + s += stride; + } + } else { + for (int x = 0; x < w; x += 16) { + const pixel *s = src + x - 3 * stride; + pixel *d = dst + x; + int16_t *t16 = tmp + x; + u8x16 r0 = vec_xl(0, s); + u8x16 r1 = vec_xl(0, s + 1 * stride); + u8x16 r2 = vec_xl(0, s + 2 * stride); + u8x16 r3 = vec_xl(0, s + 3 * stride); + u8x16 r4 = vec_xl(0, s + 4 * stride); + u8x16 r5 = vec_xl(0, s + 5 * stride); + u8x16 r6 = vec_xl(0, s + 6 * stride); + s += 7 * stride; + for (int y = 0; y < h; y++) { + const u8x16 r7 = vec_xl(0, s); + V8TAP_SUMS8(s03, s47, a, r0, r1, r2, r3, r4, r5, r6, r7, + tapsA, tapsB, accv, vec_mergeh); + V8TAP_SUMS8(s8b, scf, b, r0, r1, r2, r3, r4, r5, r6, r7, + tapsA, tapsB, accv, vec_mergel); + const i16x8 t0 = vec_packs(vec_sra(s03, shv), vec_sra(s47, shv)); + const i16x8 t1 = vec_packs(vec_sra(s8b, shv), vec_sra(scf, shv)); + if (is_put) { + vec_xst(vec_packsu(t0, t1), 0, d); + d += PXSTRIDE(dst_stride); + } else { + vec_xst(t0, 0, t16); + vec_xst(t1, 0, t16 + 8); + t16 += w; + } + V8TAP_SLIDE; + s += stride; + } + } + } +} + +/* First (horizontal) pass of the 2D filter into the 16-bit mid buffer, + * mirroring the C: rows [-3, h+3], (sum + 2) >> 2, mid stride 128. Widths + * below 8 just compute a full 8 and store 16 bytes into the scratch row. */ +static void h8tap_mid_altivec(int16_t *mid, const pixel *src, + const ptrdiff_t src_stride, + const int w, int rows, const int8_t *const fh) +{ + const i32x4 accv = vec_splats((int32_t)2); + const u32x4 shv = vec_splats(2u); + H8TAPS(fh, tapsA, tapsB); + + do { + for (int x = 0; x < w; x += 8) { + H8TAP_SUMS(s03, s47, src + x - 3, tapsA, tapsB, accv); + vec_st(vec_packs(vec_sra(s03, shv), vec_sra(s47, shv)), 0, mid + x); + } + mid += 128; + src += PXSTRIDE(src_stride); + } while (--rows); +} + +/* Second (vertical) pass over the mid buffer: vmsumshm on interleaved row + * pairs against (fv[k], fv[k+1]) tap pairs, 8 columns per slice. */ +#define MID_V_SUMS(s03, s47, m0, m1, m2, m3, m4, m5, m6, m7, accv) \ + i32x4 s03 = vec_msum(vec_mergeh(m0, m1), tp01, accv); \ + i32x4 s47 = vec_msum(vec_mergel(m0, m1), tp01, accv); \ + s03 = vec_msum(vec_mergeh(m2, m3), tp23, s03); \ + s47 = vec_msum(vec_mergel(m2, m3), tp23, s47); \ + s03 = vec_msum(vec_mergeh(m4, m5), tp45, s03); \ + s47 = vec_msum(vec_mergel(m4, m5), tp45, s47); \ + s03 = vec_msum(vec_mergeh(m6, m7), tp67, s03); \ + s47 = vec_msum(vec_mergel(m6, m7), tp67, s47) + +#define MID_V_TAPS(fv) \ + const i16x8 tp01 = vec_mergeh(vec_splats((int16_t)fv[0]), vec_splats((int16_t)fv[1])); \ + const i16x8 tp23 = vec_mergeh(vec_splats((int16_t)fv[2]), vec_splats((int16_t)fv[3])); \ + const i16x8 tp45 = vec_mergeh(vec_splats((int16_t)fv[4]), vec_splats((int16_t)fv[5])); \ + const i16x8 tp67 = vec_mergeh(vec_splats((int16_t)fv[6]), vec_splats((int16_t)fv[7])) + +#define MID_V_SLIDE \ + m0 = m1; m1 = m2; m2 = m3; m3 = m4; m4 = m5; m5 = m6; m6 = m7 + +static ALWAYS_INLINE void v8tap_mid_altivec(pixel *dst, const ptrdiff_t dst_stride, + int16_t *tmp, const int16_t *mid, + const int w, const int h, + const int8_t *const fv, + const i32x4 accv, const u32x4 shv, + const int is_put) +{ + MID_V_TAPS(fv); + + for (int x = 0; x < w; x += 8) { + const int16_t *m = mid + x; + pixel *d = dst + x; + int16_t *t16 = tmp + x; + i16x8 m0 = vec_ld(0, m); + i16x8 m1 = vec_ld(0, m + 1 * 128); + i16x8 m2 = vec_ld(0, m + 2 * 128); + i16x8 m3 = vec_ld(0, m + 3 * 128); + i16x8 m4 = vec_ld(0, m + 4 * 128); + i16x8 m5 = vec_ld(0, m + 5 * 128); + i16x8 m6 = vec_ld(0, m + 6 * 128); + m += 7 * 128; + for (int y = 0; y < h; y++) { + const i16x8 m7 = vec_ld(0, m); + MID_V_SUMS(s03, s47, m0, m1, m2, m3, m4, m5, m6, m7, accv); + const i16x8 t = vec_packs(vec_sra(s03, shv), vec_sra(s47, shv)); + if (is_put) { + if (w >= 8) store_h8(d, vec_packsu(t, t)); + else store_wN(d, vec_packsu(t, t), w); + d += PXSTRIDE(dst_stride); + } else { + if (w >= 8) { + vec_xst(t, 0, t16); + } else { + ALIGN_STK_16(int16_t, buf, 8,); + vec_st(t, 0, buf); + memcpy(t16, buf, 2 * w); + } + t16 += w; + } + MID_V_SLIDE; + m += 128; + } + if (w <= 8) break; + } +} + +static void put_copy_altivec(pixel *dst, const ptrdiff_t dst_stride, + const pixel *src, const ptrdiff_t src_stride, + const int w, int h) +{ + do { + memcpy(dst, src, w); + dst += PXSTRIDE(dst_stride); + src += PXSTRIDE(src_stride); + } while (--h); +} + +static void prep_copy_altivec(int16_t *tmp, const pixel *src, + const ptrdiff_t src_stride, const int w, int h) +{ + const u16x8 four = vec_splat_u16(4); + do { + if (w <= 4) { + const u8x16 s = vec_xl(0, src); + const i16x8 t = (i16x8)vec_sl((u16x8)u8h_to_i16(s), four); + ALIGN_STK_16(int16_t, buf, 8,); + vec_st(t, 0, buf); + memcpy(tmp, buf, 2 * w); + } else for (int x = 0; x < w; x += 8) { + const u8x16 s = vec_xl(0, src + x); + vec_xst((i16x8)vec_sl((u16x8)u8h_to_i16(s), four), 0, tmp + x); + } + tmp += w; + src += PXSTRIDE(src_stride); + } while (--h); +} + +static void put_8tap_altivec(pixel *dst, const ptrdiff_t dst_stride, + const pixel *src, const ptrdiff_t src_stride, + const int w, const int h, const int mx, const int my, + const int filter_type) +{ + const int8_t *const fh = !mx ? NULL : w > 4 ? + dav1d_mc_subpel_filters[filter_type & 3][mx - 1] : + dav1d_mc_subpel_filters[3 + (filter_type & 1)][mx - 1]; + const int8_t *const fv = !my ? NULL : h > 4 ? + dav1d_mc_subpel_filters[filter_type >> 2][my - 1] : + dav1d_mc_subpel_filters[3 + ((filter_type >> 2) & 1)][my - 1]; + + if (fh) { + if (fv) { + ALIGN_STK_16(int16_t, mid, 128 * 135,); + h8tap_mid_altivec(mid, src - 3 * PXSTRIDE(src_stride), src_stride, + w, h + 7, fh); + v8tap_mid_altivec(dst, dst_stride, NULL, mid, w, h, fv, + vec_splats((int32_t)512), vec_splats(10u), 1); + } else { + put_8tap_h_altivec(dst, dst_stride, src, src_stride, w, h, fh); + } + } else if (fv) { + v8tap_altivec(dst, dst_stride, NULL, src, src_stride, w, h, fv, + vec_splats((int32_t)32), vec_splats(6u), 1); + } else { + put_copy_altivec(dst, dst_stride, src, src_stride, w, h); + } +} + +static void prep_8tap_altivec(int16_t *tmp, const pixel *src, + const ptrdiff_t src_stride, + const int w, const int h, const int mx, const int my, + const int filter_type) +{ + const int8_t *const fh = !mx ? NULL : w > 4 ? + dav1d_mc_subpel_filters[filter_type & 3][mx - 1] : + dav1d_mc_subpel_filters[3 + (filter_type & 1)][mx - 1]; + const int8_t *const fv = !my ? NULL : h > 4 ? + dav1d_mc_subpel_filters[filter_type >> 2][my - 1] : + dav1d_mc_subpel_filters[3 + ((filter_type >> 2) & 1)][my - 1]; + + if (fh) { + if (fv) { + ALIGN_STK_16(int16_t, mid, 128 * 135,); + h8tap_mid_altivec(mid, src - 3 * PXSTRIDE(src_stride), src_stride, + w, h + 7, fh); + v8tap_mid_altivec(NULL, 0, tmp, mid, w, h, fv, + vec_splats((int32_t)32), vec_splats(6u), 0); + } else { + prep_8tap_h_altivec(tmp, src, src_stride, w, h, fh); + } + } else if (fv) { + v8tap_altivec(NULL, 0, tmp, src, src_stride, w, h, fv, + vec_splats((int32_t)2), vec_splats(2u), 0); + } else { + prep_copy_altivec(tmp, src, src_stride, w, h); + } +} + +#define filter_8tap_fns(type, type_h, type_v) \ +void BF(dav1d_put_8tap_##type, altivec)(pixel *const dst, \ + const ptrdiff_t dst_stride, \ + const pixel *const src, \ + const ptrdiff_t src_stride, \ + const int w, const int h, \ + const int mx, const int my) \ +{ \ + put_8tap_altivec(dst, dst_stride, src, src_stride, w, h, mx, my, \ + type_h | (type_v << 2)); \ +} \ +void BF(dav1d_prep_8tap_##type, altivec)(int16_t *const tmp, \ + const pixel *const src, \ + const ptrdiff_t src_stride, \ + const int w, const int h, \ + const int mx, const int my) \ +{ \ + prep_8tap_altivec(tmp, src, src_stride, w, h, mx, my, \ + type_h | (type_v << 2)); \ +} + +filter_8tap_fns(regular, DAV1D_FILTER_8TAP_REGULAR, DAV1D_FILTER_8TAP_REGULAR) +filter_8tap_fns(regular_sharp, DAV1D_FILTER_8TAP_REGULAR, DAV1D_FILTER_8TAP_SHARP) +filter_8tap_fns(regular_smooth, DAV1D_FILTER_8TAP_REGULAR, DAV1D_FILTER_8TAP_SMOOTH) +filter_8tap_fns(smooth, DAV1D_FILTER_8TAP_SMOOTH, DAV1D_FILTER_8TAP_SMOOTH) +filter_8tap_fns(smooth_regular, DAV1D_FILTER_8TAP_SMOOTH, DAV1D_FILTER_8TAP_REGULAR) +filter_8tap_fns(smooth_sharp, DAV1D_FILTER_8TAP_SMOOTH, DAV1D_FILTER_8TAP_SHARP) +filter_8tap_fns(sharp, DAV1D_FILTER_8TAP_SHARP, DAV1D_FILTER_8TAP_SHARP) +filter_8tap_fns(sharp_regular, DAV1D_FILTER_8TAP_SHARP, DAV1D_FILTER_8TAP_REGULAR) +filter_8tap_fns(sharp_smooth, DAV1D_FILTER_8TAP_SHARP, DAV1D_FILTER_8TAP_SMOOTH) + #endif // !ARCH_PPC64LE #endif // BITDEPTH -- 2.43.0