Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  itx_tmpl.c   Sprache: C

 
/*
 * Copyright © 2024, VideoLAN and dav1d authors
 * Copyright © 2024, Luca Barbato
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


#include "src/ppc/dav1d_types.h"
#include "src/ppc/itx.h"
#include "src/ppc/utils.h"

#if BITDEPTH == 8

#define LOAD_4(src, stride, a, b, c, d) \
{  \
    uint8_t *s = src; \
    a = vec_xl(0, s); \
    s += stride; \
    b = vec_xl(0, s); \
    s += stride; \
    c = vec_xl(0, s); \
    s += stride; \
    d = vec_xl(0, s); \
}

#define LOAD_DECLARE_2_I16(src, a, b) \
    i16x8 a = vec_xl(0, src); \
    i16x8 b = vec_xl(0, src + 8);

#define UNPACK_DECLARE_4_I16_I32(sa, sb, a, b, c, d) \
    i32x4 a = i16h_to_i32(sa); \
    i32x4 b = i16l_to_i32(sa); \
    i32x4 c = i16h_to_i32(sb); \
    i32x4 d = i16l_to_i32(sb);

#define LOAD_COEFF_4(coeff) \
    LOAD_DECLARE_2_I16(coeff, c01, c23) \
    UNPACK_DECLARE_4_I16_I32(c01, c23, c0, c1, c2, c3)

#define LOAD_SCALE_COEFF_4x8(coeff, scale) \
    LOAD_DECLARE_2_I16(coeff, c04, c15) \
    LOAD_DECLARE_2_I16(coeff+16, c26, c37) \
    i16x8 c01 = (i16x8)vec_mergeh((i64x2)c04, (i64x2)c15); \
    i16x8 c23 = (i16x8)vec_mergeh((i64x2)c26, (i64x2)c37); \
    i16x8 c45 = (i16x8)vec_mergel((i64x2)c04, (i64x2)c15); \
    i16x8 c67 = (i16x8)vec_mergel((i64x2)c26, (i64x2)c37); \
    c01 = vec_mradds(c01, scale, vec_splat_s16(0)); \
    c23 = vec_mradds(c23, scale, vec_splat_s16(0)); \
    UNPACK_DECLARE_4_I16_I32(c01, c23, c0, c1, c2, c3) \
    c45 = vec_mradds(c45, scale, vec_splat_s16(0)); \
    c67 = vec_mradds(c67, scale, vec_splat_s16(0)); \
    UNPACK_DECLARE_4_I16_I32(c45, c67, c4, c5, c6, c7)

#define LOAD_SCALE_COEFF_8x4(coeff, scale) \
    LOAD_DECLARE_2_I16(coeff, c01, c23) \
    LOAD_DECLARE_2_I16(coeff+16, c45, c67) \
    c01 = vec_mradds(c01, scale, vec_splat_s16(0)); \
    c23 = vec_mradds(c23, scale, vec_splat_s16(0)); \
    UNPACK_DECLARE_4_I16_I32(c01, c23, c0, c1, c2, c3) \
    c45 = vec_mradds(c45, scale, vec_splat_s16(0)); \
    c67 = vec_mradds(c67, scale, vec_splat_s16(0)); \
    UNPACK_DECLARE_4_I16_I32(c45, c67, c4, c5, c6, c7)

#define LOAD_COEFF_8x8(coeff) \
    LOAD_DECLARE_2_I16(coeff, c0, c1) \
    LOAD_DECLARE_2_I16(coeff+16, c2, c3) \
    LOAD_DECLARE_2_I16(coeff+32, c4, c5) \
    LOAD_DECLARE_2_I16(coeff+48, c6, c7) \
    UNPACK_DECLARE_4_I16_I32(c0, c1, c0h, c0l, c1h, c1l) \
    UNPACK_DECLARE_4_I16_I32(c2, c3, c2h, c2l, c3h, c3l) \
    UNPACK_DECLARE_4_I16_I32(c4, c5, c4h, c4l, c5h, c5l) \
    UNPACK_DECLARE_4_I16_I32(c6, c7, c6h, c6l, c7h, c7l) \

#define LOAD_COEFF_4x16(coeff) \
    LOAD_DECLARE_2_I16(coeff,    a0b0, c0d0) \
    LOAD_DECLARE_2_I16(coeff+16, a1b1, c1d1) \
    LOAD_DECLARE_2_I16(coeff+32, a2b2, c2d2) \
    LOAD_DECLARE_2_I16(coeff+48, a3b3, c3d3) \
    UNPACK_DECLARE_4_I16_I32(a0b0, c0d0, cA0, cB0, cC0, cD0) \
    UNPACK_DECLARE_4_I16_I32(a1b1, c1d1, cA1, cB1, cC1, cD1) \
    UNPACK_DECLARE_4_I16_I32(a2b2, c2d2, cA2, cB2, cC2, cD2) \
    UNPACK_DECLARE_4_I16_I32(a3b3, c3d3, cA3, cB3, cC3, cD3)

#define LOAD_DECLARE_4(src, stride, a, b, c, d) \
    u8x16 a, b, c, d; \
    LOAD_4(src, stride, a, b, c, d)

#define STORE_LEN(l, dst, stride, a, b, c, d) \
{ \
    uint8_t *dst2 = dst; \
    vec_xst_len(a, dst2, l); \
    dst2 += stride; \
    vec_xst_len(b, dst2, l); \
    dst2 += stride; \
    vec_xst_len(c, dst2, l); \
    dst2 += stride; \
    vec_xst_len(d, dst2, l); \
}

#define STORE_4(dst, stride, a, b, c, d) \
    STORE_LEN(4, dst, stride, a, b, c, d)

#define STORE_8(dst, stride, ab, cd, ef, gh) \
    STORE_LEN(8, dst, stride, ab, cd, ef, gh)

#define STORE_16(dst, stride, l0, l1, l2, l3) \
{ \
    uint8_t *dst##2 = dst; \
    vec_xst(l0, 0, dst##2); \
    dst##2 += stride; \
    vec_xst(l1, 0, dst##2); \
    dst##2 += stride; \
    vec_xst(l2, 0, dst##2); \
    dst##2 += stride; \
    vec_xst(l3, 0, dst##2); \
}

#define APPLY_COEFF_4(a, b, c, d, c01, c23) \
{ \
    u8x16 ab = (u8x16)vec_mergeh((u32x4)a, (u32x4)b); \
    u8x16 cd = (u8x16)vec_mergeh((u32x4)c, (u32x4)d); \
 \
    c01 = vec_adds(c01, vec_splat_s16(8)); \
    c23 = vec_adds(c23, vec_splat_s16(8)); \
    c01 = vec_sra(c01, vec_splat_u16(4)); \
    c23 = vec_sra(c23, vec_splat_u16(4)); \
 \
    i16x8 abs = u8h_to_i16(ab); \
    i16x8 cds = u8h_to_i16(cd); \
 \
    abs = vec_adds(abs, c01); \
    cds = vec_adds(cds, c23); \
 \
    a = vec_packsu(abs, abs); \
    c = vec_packsu(cds, cds); \
 \
    b = (u8x16)vec_mergeo((u32x4)a, (u32x4)a); \
    d = (u8x16)vec_mergeo((u32x4)c, (u32x4)c); \
}

#define APPLY_COEFF_8x4(ab, cd, c01, c23) \
{ \
    i16x8 abs = u8h_to_i16(ab); \
    i16x8 cds = u8h_to_i16(cd); \
    c01 = vec_adds(c01, vec_splat_s16(8)); \
    c23 = vec_adds(c23, vec_splat_s16(8)); \
    c01 = vec_sra(c01, vec_splat_u16(4)); \
    c23 = vec_sra(c23, vec_splat_u16(4)); \
 \
    abs = vec_adds(abs, c01); \
    cds = vec_adds(cds, c23); \
 \
    ab = vec_packsu(abs, abs); \
    cd = vec_packsu(cds, cds); \
}

#define APPLY_COEFF_16x4(a, b, c, d, \
                         c00c01, c02c03, c04c05, c06c07, \
                         c08c09, c10c11, c12c13, c14c15) \
{ \
    i16x8 ah = u8h_to_i16(a); \
    i16x8 al = u8l_to_i16(a); \
    i16x8 bh = u8h_to_i16(b); \
    i16x8 bl = u8l_to_i16(b); \
    i16x8 ch = u8h_to_i16(c); \
    i16x8 cl = u8l_to_i16(c); \
    i16x8 dh = u8h_to_i16(d); \
    i16x8 dl = u8l_to_i16(d); \
    SCALE_ROUND_4(c00c01, c02c03, c04c05, c06c07, vec_splat_s16(8), vec_splat_u16(4)) \
    SCALE_ROUND_4(c08c09, c10c11, c12c13, c14c15, vec_splat_s16(8), vec_splat_u16(4)) \
 \
    ah = vec_adds(ah, c00c01); \
    al = vec_adds(al, c02c03); \
    bh = vec_adds(bh, c04c05); \
    bl = vec_adds(bl, c06c07); \
    ch = vec_adds(ch, c08c09); \
    cl = vec_adds(cl, c10c11); \
    dh = vec_adds(dh, c12c13); \
    dl = vec_adds(dl, c14c15); \
 \
    a = vec_packsu(ah, al); \
    b = vec_packsu(bh, bl); \
    c = vec_packsu(ch, cl); \
    d = vec_packsu(dh, dl); \
}

#define IDCT_4_INNER(c0, c1, c2, c3) \
{ \
    i32x4 o0 = vec_add(c0, c2); \
    i32x4 o1 = vec_sub(c0, c2); \
 \
    i32x4 v2896 = vec_splats(2896); \
    i32x4 v1567 = vec_splats(1567); \
    i32x4 v3784 = vec_splats(3784); \
    i32x4 v2048 = vec_splats(2048); \
 \
    o0 = vec_mul(o0, v2896); \
    o1 = vec_mul(o1, v2896); \
 \
    i32x4 o2a = vec_mul(c1, v1567); \
    i32x4 o2b = vec_mul(c3, v3784); \
    i32x4 o3a = vec_mul(c1, v3784); \
    i32x4 o3b = vec_mul(c3, v1567); \
 \
    i32x4 o2 = vec_sub(o2a, o2b); \
    i32x4 o3 = vec_add(o3a, o3b); \
 \
    u32x4 v12 = vec_splat_u32(12); \
 \
    o0 = vec_add(o0, v2048); \
    o1 = vec_add(o1, v2048); \
    o2 = vec_add(o2, v2048); \
    o3 = vec_add(o3, v2048); \
 \
    o0 = vec_sra(o0, v12); \
    o1 = vec_sra(o1, v12); \
    o2 = vec_sra(o2, v12); \
    o3 = vec_sra(o3, v12); \
 \
    c0 = vec_add(o0, o3); \
    c1 = vec_add(o1, o2); \
    c2 = vec_sub(o1, o2); \
    c3 = vec_sub(o0, o3); \
 \
}

#define dct4_for_dct8(c0, c1, c2, c3, c03, c12) \
    IDCT_4_INNER(c0, c1, c2, c3) \
    c03 = vec_packs(c0, c3); \
    c12 = vec_packs(c1, c2); \

#define dct_4_in(c0, c1, c2, c3, c01, c23) \
{ \
    IDCT_4_INNER(c0, c1, c2, c3) \
    c01 = vec_packs(c0, c1); \
    c23 = vec_packs(c2, c3); \
    c0 = i16h_to_i32(c01); \
    c1 = i16l_to_i32(c01); \
    c2 = i16h_to_i32(c23); \
    c3 = i16l_to_i32(c23); \
}

#define dct_4_out(c0, c1, c2, c3, c01, c23) \
    IDCT_4_INNER(c0, c1, c2, c3) \
    c01 = vec_packs(c0, c1); \
    c23 = vec_packs(c2, c3); \


#define IDENTITY_4(c01, c23) \
{ \
    i16x8 v1697 = vec_splats((int16_t)(1697*8)); \
    i16x8 o01 = vec_mradds(c01, v1697, vec_splat_s16(0)); \
    i16x8 o23 = vec_mradds(c23, v1697, vec_splat_s16(0)); \
    c01 = vec_adds(c01, o01); \
    c23 = vec_adds(c23, o23); \
}

#define identity_4_in(c0, c1, c2, c3, c01, c23) \
{ \
    IDENTITY_4(c01, c23) \
    c0 = i16h_to_i32(c01); \
    c1 = i16l_to_i32(c01); \
    c2 = i16h_to_i32(c23); \
    c3 = i16l_to_i32(c23); \
}

#define identity_4_out(c0, c1, c2, c3, c01, c23) \
{ \
    c01 = vec_packs(c0, c1); \
    c23 = vec_packs(c2, c3); \
    IDENTITY_4(c01, c23) \
}

#define ADST_INNER_4(c0, c1, c2, c3, oc0, oc1, oc2, oc3) \
{ \
    i32x4 v1321 = vec_splats(1321); \
    i32x4 v3803 = vec_splats(3803); \
    i32x4 v2482 = vec_splats(2482); \
    i32x4 v3344 = vec_splats(3344); \
    i32x4 v2048 = vec_splats(2048); \
    i32x4 i0_v1321 = vec_mul(c0, v1321); \
    i32x4 i0_v2482 = vec_mul(c0, v2482); \
    i32x4 i0_v3803 = vec_mul(c0, v3803); \
    i32x4 i1 = vec_mul(c1, v3344); \
    i32x4 i2_v1321 = vec_mul(c2, v1321); \
    i32x4 i2_v2482 = vec_mul(c2, v2482); \
    i32x4 i2_v3803 = vec_mul(c2, v3803); \
    i32x4 i3_v1321 = vec_mul(c3, v1321); \
    i32x4 i3_v2482 = vec_mul(c3, v2482); \
    i32x4 i3_v3803 = vec_mul(c3, v3803); \
 \
    i32x4 n1 = vec_sub(i1, v2048); \
    i1 = vec_add(i1, v2048); \
 \
 \
    i32x4 o0 = vec_add(i0_v1321, i2_v3803); \
    i32x4 o1 = vec_sub(i0_v2482, i2_v1321); \
    i32x4 o2 = vec_sub(c0, c2); \
    i32x4 o3 = vec_add(i0_v3803, i2_v2482); \
 \
    o0 = vec_add(o0, i3_v2482); \
    o1 = vec_sub(o1, i3_v3803); \
    o2 = vec_add(o2, c3); \
    o3 = vec_sub(o3, i3_v1321); \
 \
    o0 = vec_add(o0, i1); \
    o1 = vec_add(o1, i1); \
    o2 = vec_mul(o2, v3344); \
    o3 = vec_sub(o3, n1); \
 \
    o2 = vec_add(o2, v2048); \
 \
    oc0 = vec_sra(o0, vec_splat_u32(12)); \
    oc1 = vec_sra(o1, vec_splat_u32(12)); \
    oc2 = vec_sra(o2, vec_splat_u32(12)); \
    oc3 = vec_sra(o3, vec_splat_u32(12)); \
}

#define adst_4_in(c0, c1, c2, c3, c01, c23) \
{ \
    ADST_INNER_4(c0, c1, c2, c3, c0, c1, c2, c3) \
}

#define flipadst_4_in(c0, c1, c2, c3, c01, c23) \
{ \
    ADST_INNER_4(c0, c1, c2, c3, c3, c2, c1, c0) \
}

#define adst_4_out(c0, c1, c2, c3, c01, c23) \
{ \
    ADST_INNER_4(c0, c1, c2, c3, c0, c1, c2, c3) \
    c01 = vec_packs(c0, c1); \
    c23 = vec_packs(c2, c3); \
}

#define flipadst_4_out(c0, c1, c2, c3, c01, c23) \
{ \
    ADST_INNER_4(c0, c1, c2, c3, c3, c2, c1, c0) \
    c01 = vec_packs(c0, c1); \
    c23 = vec_packs(c2, c3); \
}

static void dc_only_4xN(uint8_t *dst, const ptrdiff_t stride, int16_t *const coeff, int n, int is_rect2, int shift)
{
    int dc = coeff[0];
    const int rnd = (1 << shift) >> 1;
    if (is_rect2)
        dc = (dc * 181 + 128) >> 8;
    dc = (dc * 181 + 128) >> 8;
    dc = (dc + rnd) >> shift;
    dc = (dc * 181 + 128 + 2048) >> 12;

    i16x8 vdc = vec_splats((int16_t)dc);
    coeff[0] = 0;
    for (int i = 0; i < n; i++, dst += 4 * stride) {
        LOAD_DECLARE_4(dst, stride, a, b, c, d)

        i16x8 as = u8h_to_i16(a);
        i16x8 bs = u8h_to_i16(b);
        i16x8 cs = u8h_to_i16(c);
        i16x8 ds = u8h_to_i16(d);

        as = vec_adds(as, vdc);
        bs = vec_adds(bs, vdc);
        cs = vec_adds(cs, vdc);
        ds = vec_adds(ds, vdc);

        a = vec_packsu(as, as);
        b = vec_packsu(bs, bs);
        c = vec_packsu(cs, cs);
        d = vec_packsu(ds, ds);

        STORE_4(dst, stride, a, b, c, d)
    }
}

static void dc_only_8xN(uint8_t *dst, const ptrdiff_t stride, int16_t *const coeff, int n, int is_rect2, int shift)
{
    int dc = coeff[0];
    const int rnd = (1 << shift) >> 1;
    if (is_rect2)
        dc = (dc * 181 + 128) >> 8;
    dc = (dc * 181 + 128) >> 8;
    dc = (dc + rnd) >> shift;
    dc = (dc * 181 + 128 + 2048) >> 12;

    i16x8 vdc = vec_splats((int16_t)dc);
    coeff[0] = 0;

    for (int i = 0; i < n; i++, dst += 4 * stride) {
        LOAD_DECLARE_4(dst, stride, a, b, c, d)

        i16x8 as = u8h_to_i16(a);
        i16x8 bs = u8h_to_i16(b);
        i16x8 cs = u8h_to_i16(c);
        i16x8 ds = u8h_to_i16(d);

        as = vec_adds(as, vdc);
        bs = vec_adds(bs, vdc);
        cs = vec_adds(cs, vdc);
        ds = vec_adds(ds, vdc);

        a = vec_packsu(as, as);
        b = vec_packsu(bs, bs);
        c = vec_packsu(cs, cs);
        d = vec_packsu(ds, ds);

        STORE_8(dst, stride, a, b, c, d)
    }
}

static void dc_only_16xN(uint8_t *dst, const ptrdiff_t stride, int16_t *const coeff, int n, int is_rect2, int shift)
{
    int dc = coeff[0];
    const int rnd = (1 << shift) >> 1;
    if (is_rect2)
        dc = (dc * 181 + 128) >> 8;
    dc = (dc * 181 + 128) >> 8;
    dc = (dc + rnd) >> shift;
    dc = (dc * 181 + 128 + 2048) >> 12;

    i16x8 vdc = vec_splats((int16_t)dc);
    coeff[0] = 0;

    for (int i = 0; i < n; i++, dst += 4 * stride) {
        LOAD_DECLARE_4(dst, stride, a, b, c, d)

        i16x8 ah = u8h_to_i16(a);
        i16x8 bh = u8h_to_i16(b);
        i16x8 ch = u8h_to_i16(c);
        i16x8 dh = u8h_to_i16(d);
        i16x8 al = u8l_to_i16(a);
        i16x8 bl = u8l_to_i16(b);
        i16x8 cl = u8l_to_i16(c);
        i16x8 dl = u8l_to_i16(d);

        ah = vec_adds(ah, vdc);
        bh = vec_adds(bh, vdc);
        ch = vec_adds(ch, vdc);
        dh = vec_adds(dh, vdc);
        al = vec_adds(al, vdc);
        bl = vec_adds(bl, vdc);
        cl = vec_adds(cl, vdc);
        dl = vec_adds(dl, vdc);

        a = vec_packsu(ah, al);
        b = vec_packsu(bh, bl);
        c = vec_packsu(ch, cl);
        d = vec_packsu(dh, dl);

        STORE_16(dst, stride, a, b, c, d)
    }
}

void dav1d_inv_txfm_add_dct_dct_4x4_8bpc_pwr9(uint8_t *dst, const ptrdiff_t stride,
                                              int16_t *const coeff, const int eob)
{
    assert(eob >= 0);

    if (eob < 1) {
        return dc_only_4xN(dst, stride, coeff, 1, 0, 0);
    }

    LOAD_COEFF_4(coeff)

    dct_4_in(c0, c1, c2, c3, c01, c23)

    TRANSPOSE4_I32(c0, c1, c2, c3)

    memset(coeff, 0, sizeof(*coeff) * 4 * 4);

    dct_4_out(c0, c1, c2, c3, c01, c23)

    LOAD_DECLARE_4(dst, stride, a, b, c, d)

    APPLY_COEFF_4(a, b, c, d, c01, c23)

    STORE_4(dst, stride, a, b, c, d)
}

void dav1d_inv_txfm_add_wht_wht_4x4_8bpc_pwr9(pixel *dst, const ptrdiff_t stride,
                                              coef *const coeff, const int eob)
{
    LOAD_COEFF_4(coeff)

    u32x4 v2 = vec_splat_u32(2);

    c0 = vec_sra(c0, v2);
    c1 = vec_sra(c1, v2);
    c2 = vec_sra(c2, v2);
    c3 = vec_sra(c3, v2);

    i32x4 t0 = vec_add(c0, c1);
    i32x4 t2 = vec_sub(c2, c3);
    i32x4 t4 = vec_sra(vec_sub(t0, t2), vec_splat_u32(1));
    i32x4 t3 = vec_sub(t4, c3);
    i32x4 t1 = vec_sub(t4, c1);
    c0 = vec_sub(t0, t3);
    c1 = t3;
    c2 = t1;
    c3 = vec_add(t2, t1);

    memset(coeff, 0, sizeof(*coeff) * 4 * 4);

    TRANSPOSE4_I32(c0, c1, c2, c3)

    t0 = vec_add(c0, c1);
    t2 = vec_sub(c2, c3);
    t4 = vec_sra(vec_sub(t0, t2), vec_splat_u32(1));
    t3 = vec_sub(t4, c3);
    t1 = vec_sub(t4, c1);
    c0 = vec_sub(t0, t3);
    c1 = t3;
    c2 = t1;
    c3 = vec_add(t2, t1);

    c01 = vec_packs(c0, c1);
    c23 = vec_packs(c2, c3);

    LOAD_DECLARE_4(dst, stride, a, b, c, d)

    u8x16 ab = (u8x16)vec_mergeh((u32x4)a, (u32x4)b);
    u8x16 cd = (u8x16)vec_mergeh((u32x4)c, (u32x4)d);

    i16x8 abs = u8h_to_i16(ab);
    i16x8 cds = u8h_to_i16(cd);

    abs = vec_adds(abs, c01);
    cds = vec_adds(cds, c23);

    a = vec_packsu(abs, abs);
    c = vec_packsu(cds, cds);

    b = (u8x16)vec_mergeo((u32x4)a, (u32x4)a);
    d = (u8x16)vec_mergeo((u32x4)c, (u32x4)c);

    STORE_4(dst, stride, a, b, c, d)
}

#define inv_txfm_fn4x4(type1, type2) \
void dav1d_inv_txfm_add_##type1##_##type2##_4x4_8bpc_pwr9(uint8_t *dst, const ptrdiff_t stride, \
                                                          int16_t *const coeff, const int eob) \
{ \
    LOAD_COEFF_4(coeff) \
    type1##_4_in(c0, c1, c2, c3, c01, c23) \
    memset(coeff, 0, sizeof(*coeff) * 4 * 4); \
    TRANSPOSE4_I32(c0, c1, c2, c3) \
    type2##_4_out(c0, c1, c2, c3, c01, c23) \
    LOAD_DECLARE_4(dst, stride, a, b, c, d) \
    APPLY_COEFF_4(a, b, c, d, c01, c23) \
    STORE_4(dst, stride, a, b, c, d) \
}

inv_txfm_fn4x4(adst,     dct     )
inv_txfm_fn4x4(dct,      adst    )
inv_txfm_fn4x4(dct,      flipadst)
inv_txfm_fn4x4(flipadst, dct     )
inv_txfm_fn4x4(adst,     flipadst)
inv_txfm_fn4x4(flipadst, adst    )
inv_txfm_fn4x4(identity, dct     )
inv_txfm_fn4x4(dct,      identity)
inv_txfm_fn4x4(identity, flipadst)
inv_txfm_fn4x4(flipadst, identity)
inv_txfm_fn4x4(identity, adst   )
inv_txfm_fn4x4(adst,     identity)
inv_txfm_fn4x4(identity, identity)
inv_txfm_fn4x4(adst,     adst    )
inv_txfm_fn4x4(flipadst, flipadst)


#define IDCT_8_INNER(c0, c1, c2, c3, c4, c5, c6, c7, c03, c12, c74, c65) \
    dct4_for_dct8(c0, c2, c4, c6, c03, c12) \
 \
    i32x4 v799 = vec_splats(799); \
    i32x4 v4017 = vec_splats(4017); \
    i32x4 v3406 = vec_splats(3406); \
    i32x4 v2276 = vec_splats(2276); \
    i32x4 v2048 = vec_splats(2048); \
    u32x4 v12 = vec_splat_u32(12); \
 \
    i32x4 c1v799 = vec_mul(c1, v799); \
    i32x4 c7v4017 = vec_mul(c7, v4017); \
    i32x4 c5v3406 = vec_mul(c5, v3406); \
    i32x4 c3v2276 = vec_mul(c3, v2276); \
    i32x4 c5v2276 = vec_mul(c5, v2276); \
    i32x4 c3v3406 = vec_mul(c3, v3406); \
    i32x4 c1v4017 = vec_mul(c1, v4017); \
    i32x4 c7v799 = vec_mul(c7, v799); \
 \
    i32x4 t4a = vec_subs(c1v799, c7v4017); \
    i32x4 t5a = vec_subs(c5v3406, c3v2276); \
    i32x4 t6a = vec_adds(c5v2276, c3v3406); \
    i32x4 t7a = vec_adds(c1v4017, c7v799); \
 \
    t4a = vec_adds(t4a, v2048); \
    t5a = vec_adds(t5a, v2048); \
    t6a = vec_adds(t6a, v2048); \
    t7a = vec_adds(t7a, v2048); \
 \
    t4a = vec_sra(t4a, v12); \
    t7a = vec_sra(t7a, v12); \
    t5a = vec_sra(t5a, v12); \
    t6a = vec_sra(t6a, v12); \
 \
    i16x8 t7at4a = vec_packs(t7a, t4a); \
    i16x8 t6at5a = vec_packs(t6a, t5a); \
 \
    i16x8 t7t4 = vec_adds(t7at4a, t6at5a); \
    t6at5a = vec_subs(t7at4a, t6at5a); \
 \
    t6a = i16h_to_i32(t6at5a); \
    t5a = i16l_to_i32(t6at5a); \
 \
    i32x4 t6 = vec_add(t6a, t5a); \
    i32x4 t5 = vec_sub(t6a, t5a); \
 \
    t6 = vec_mul(t6, vec_splats(181)); \
    t5 = vec_mul(t5, vec_splats(181)); \
    t6 = vec_add(t6, vec_splats(128)); \
    t5 = vec_add(t5, vec_splats(128)); \
 \
    t6 = vec_sra(t6, vec_splat_u32(8)); \
    t5 = vec_sra(t5, vec_splat_u32(8)); \
 \
    i16x8 t6t5 = vec_packs(t6, t5); \
 \
    c74 = vec_subs(c03, t7t4); \
    c65 = vec_subs(c12, t6t5); \
    c03 = vec_adds(c03, t7t4); \
    c12 = vec_adds(c12, t6t5); \

#define UNPACK_4_I16_I32(t0, t1, t2, t3) \
    t0 = i16h_to_i32(t0##t1); \
    t1 = i16l_to_i32(t0##t1); \
    t2 = i16h_to_i32(t2##t3); \
    t3 = i16l_to_i32(t2##t3);

#define UNPACK_PAIR_I16_I32(hi, lo, v) \
    hi = i16h_to_i32(v); \
    lo = i16l_to_i32(v); \


#define dct_8_in(c0, c1, c2, c3, c4, c5, c6, c7, ...) \
{ \
    i16x8 c0##c3, c1##c2, c7##c4, c6##c5; \
    IDCT_8_INNER(c0, c1, c2, c3, c4, c5, c6, c7, c0##c3, c1##c2, c7##c4, c6##c5) \
    UNPACK_4_I16_I32(c0, c3, c1, c2) \
    UNPACK_4_I16_I32(c7, c4, c6, c5) \
}

#define dct_8_out(c0, c1, c2, c3, c4, c5, c6, c7, c01, c23, c45, c67) \
{ \
    i16x8 c03, c12, c74, c65; \
    IDCT_8_INNER(c0, c1, c2, c3, c4, c5, c6, c7, c03, c12, c74, c65) \
    c01 = (i16x8)vec_mergeh((u64x2)c03, (u64x2)c12); \
    c23 = (i16x8)vec_mergel((u64x2)c12, (u64x2)c03); \
    c45 = (i16x8)vec_mergel((u64x2)c74, (u64x2)c65); \
    c67 = (i16x8)vec_mergeh((u64x2)c65, (u64x2)c74); \
}

#define dct_8x2_in(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
                   c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l, \
                   c0, c1, c2, c3, c4, c5, c6, c7) \
{ \
    dct_8_in(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h,) \
    dct_8_in(c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l,) \
}

#define dct_8x2_out(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
                    c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l, \
                    c0, c1, c2, c3, c4, c5, c6, c7) \
{ \
    i16x8 c03h, c12h, c74h, c65h; \
    i16x8 c03l, c12l, c74l, c65l; \
    { \
        IDCT_8_INNER(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, c03h, c12h, c74h, c65h) \
    } \
    { \
        IDCT_8_INNER(c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l, c03l, c12l, c74l, c65l) \
    } \
    c0 = (i16x8)vec_mergeh((u64x2)c03h, (u64x2)c03l); \
    c3 = (i16x8)vec_mergel((u64x2)c03h, (u64x2)c03l); \
    c1 = (i16x8)vec_mergeh((u64x2)c12h, (u64x2)c12l); \
    c2 = (i16x8)vec_mergel((u64x2)c12h, (u64x2)c12l); \
    c7 = (i16x8)vec_mergeh((u64x2)c74h, (u64x2)c74l); \
    c4 = (i16x8)vec_mergel((u64x2)c74h, (u64x2)c74l); \
    c6 = (i16x8)vec_mergeh((u64x2)c65h, (u64x2)c65l); \
    c5 = (i16x8)vec_mergel((u64x2)c65h, (u64x2)c65l); \
}

#define IDENTITY_8(c01, c23, c45, c67) \
{ \
    c01 = vec_adds(c01, c01); \
    c23 = vec_adds(c23, c23); \
    c45 = vec_adds(c45, c45); \
    c67 = vec_adds(c67, c67); \
}

#define identity_8_in(c0, c1, c2, c3, c4, c5, c6, c7, c01, c23, c45, c67) \
{ \
    IDENTITY_8(c01, c23, c45, c67) \
    UNPACK_PAIR_I16_I32(c0, c1, c01) \
    UNPACK_PAIR_I16_I32(c2, c3, c23) \
    UNPACK_PAIR_I16_I32(c4, c5, c45) \
    UNPACK_PAIR_I16_I32(c6, c7, c67) \
}

#define identity_8_out(c0, c1, c2, c3, c4, c5, c6, c7, c01, c23, c45, c67) \
    c01 = vec_packs(c0, c1); \
    c23 = vec_packs(c2, c3); \
    c45 = vec_packs(c4, c5); \
    c67 = vec_packs(c6, c7); \
    IDENTITY_8(c01, c23, c45, c67)

#define identity_8x2_in(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
                        c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l, \
                        c0, c1, c2, c3, c4, c5, c6, c7) \
{ \
    IDENTITY_8(c0, c1, c2, c3) \
    IDENTITY_8(c4, c5, c6, c7) \
    UNPACK_PAIR_I16_I32(c0h, c0l, c0) \
    UNPACK_PAIR_I16_I32(c1h, c1l, c1) \
    UNPACK_PAIR_I16_I32(c2h, c2l, c2) \
    UNPACK_PAIR_I16_I32(c3h, c3l, c3) \
    UNPACK_PAIR_I16_I32(c4h, c4l, c4) \
    UNPACK_PAIR_I16_I32(c5h, c5l, c5) \
    UNPACK_PAIR_I16_I32(c6h, c6l, c6) \
    UNPACK_PAIR_I16_I32(c7h, c7l, c7) \
}

#define PACK_4(c0, c1, c2, c3, \
               c0h, c1h, c2h, c3h, \
               c0l, c1l, c2l, c3l) \
{ \
    c0 = vec_packs(c0h, c0l); \
    c1 = vec_packs(c1h, c1l); \
    c2 = vec_packs(c2h, c2l); \
    c3 = vec_packs(c3h, c3l); \
}

#define DECLARE_PACK_4(c0, c1, c2, c3, \
                       c0h, c1h, c2h, c3h, \
                       c0l, c1l, c2l, c3l) \
    i16x8 c0, c1, c2, c3; \
    PACK_4(c0, c1, c2, c3, c0h, c1h, c2h, c3h, c0l, c1l, c2l, c3l);

#define PACK_8(c0, c1, c2, c3, c4, c5, c6, c7, \
               c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
               c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l) \
{ \
    c0 = vec_packs(c0h, c0l); \
    c1 = vec_packs(c1h, c1l); \
    c2 = vec_packs(c2h, c2l); \
    c3 = vec_packs(c3h, c3l); \
    c4 = vec_packs(c4h, c4l); \
    c5 = vec_packs(c5h, c5l); \
    c6 = vec_packs(c6h, c6l); \
    c7 = vec_packs(c7h, c7l); \
}

#define identity_8x2_out(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
                         c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l, \
                         c0, c1, c2, c3, c4, c5, c6, c7) \
{ \
    PACK_8(c0, c1, c2, c3, c4, c5, c6, c7, \
           c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
           c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l) \
    IDENTITY_8(c0, c1, c2, c3) \
    IDENTITY_8(c4, c5, c6, c7) \
}

#define DECLARE_SPLAT_I32(val) \
    i32x4 v##val = vec_splats(val);

#define DECLARE_MUL_PAIR_I32(ca, cb, va, vb) \
    i32x4 ca##va = vec_mul(ca, va); \
    i32x4 cb##vb = vec_mul(cb, vb); \
    i32x4 ca##vb = vec_mul(ca, vb); \
    i32x4 cb##va = vec_mul(cb, va);

#define ADD_SUB_PAIR(r0, r1, ca, cb, va, vb) \
    r0 = vec_adds(ca##va, cb##vb); \
    r1 = vec_subs(ca##vb, cb##va);

#define DECLARE_ADD_SUB_PAIR(r0, r1, ca, cb, va, vb) \
    i32x4 r0, r1; \
    ADD_SUB_PAIR(r0, r1, ca, cb, va, vb)

#define SCALE_ROUND_4(a, b, c, d, rnd, shift) \
    a = vec_adds(a, rnd); \
    b = vec_adds(b, rnd); \
    c = vec_adds(c, rnd); \
    d = vec_adds(d, rnd); \
    a = vec_sra(a, shift); \
    b = vec_sra(b, shift); \
    c = vec_sra(c, shift); \
    d = vec_sra(d, shift);

#define ADST_INNER_8(c0, c1, c2, c3, c4, c5, c6, c7, \
                     o0, o1, o2, o3, o4, o5, o6, o7) \
{ \
    DECLARE_SPLAT_I32(4076) \
    DECLARE_SPLAT_I32(401) \
 \
    DECLARE_SPLAT_I32(3612) \
    DECLARE_SPLAT_I32(1931) \
 \
    DECLARE_SPLAT_I32(2598) \
    DECLARE_SPLAT_I32(3166) \
 \
    DECLARE_SPLAT_I32(1189) \
    DECLARE_SPLAT_I32(3920) \
 \
    DECLARE_SPLAT_I32(3784) \
    DECLARE_SPLAT_I32(1567) \
 \
    DECLARE_SPLAT_I32(2048) \
    u32x4 v12 = vec_splat_u32(12); \
 \
    DECLARE_MUL_PAIR_I32(c7, c0, v4076, v401) \
    DECLARE_MUL_PAIR_I32(c5, c2, v3612, v1931) \
    DECLARE_MUL_PAIR_I32(c3, c4, v2598, v3166) \
    DECLARE_MUL_PAIR_I32(c1, c6, v1189, v3920) \
 \
    DECLARE_ADD_SUB_PAIR(t0a, t1a, c7, c0, v4076, v401) \
    DECLARE_ADD_SUB_PAIR(t2a, t3a, c5, c2, v3612, v1931) \
    DECLARE_ADD_SUB_PAIR(t4a, t5a, c3, c4, v2598, v3166) \
    DECLARE_ADD_SUB_PAIR(t6a, t7a, c1, c6, v1189, v3920) \
 \
    SCALE_ROUND_4(t0a, t1a, t2a, t3a, v2048, v12) \
    SCALE_ROUND_4(t4a, t5a, t6a, t7a, v2048, v12) \
 \
    i32x4 t0 = vec_add(t0a, t4a); \
    i32x4 t1 = vec_add(t1a, t5a); \
    i32x4 t2 = vec_add(t2a, t6a); \
    i32x4 t3 = vec_add(t3a, t7a); \
    i32x4 t4 = vec_sub(t0a, t4a); \
    i32x4 t5 = vec_sub(t1a, t5a); \
    i32x4 t6 = vec_sub(t2a, t6a); \
    i32x4 t7 = vec_sub(t3a, t7a); \
 \
    i16x8 t0t1 = vec_packs(t0, t1); \
    i16x8 t2t3 = vec_packs(t2, t3); \
    i16x8 t4t5 = vec_packs(t4, t5); \
    i16x8 t6t7 = vec_packs(t6, t7); \
 \
    UNPACK_4_I16_I32(t4, t5, t6, t7) \
    UNPACK_4_I16_I32(t0, t1, t2, t3) \
 \
    DECLARE_MUL_PAIR_I32(t4, t5, v3784, v1567) \
    DECLARE_MUL_PAIR_I32(t7, t6, v3784, v1567) \
 \
    ADD_SUB_PAIR(t4a, t5a, t4, t5, v3784, v1567) \
    ADD_SUB_PAIR(t7a, t6a, t7, t6, v1567, v3784) \
 \
    SCALE_ROUND_4(t4a, t5a, t6a, t7a, v2048, v12) \
  \
    o0 = vec_add(t0, t2); \
    o1 = vec_add(t4a, t6a); \
    o7 = vec_add(t1, t3); \
    o6 = vec_add(t5a, t7a); \
    t2 = vec_sub(t0, t2); \
    t3 = vec_sub(t1, t3); \
    t6 = vec_sub(t4a, t6a); \
    t7 = vec_sub(t5a, t7a); \
 \
    i16x8 o7##o1 = vec_packs(o7, o1); \
    i16x8 o0##o6 = vec_packs(o0, o6); \
    t2t3 = vec_packs(t2, t3); \
    t6t7 = vec_packs(t6, t7); \
 \
    UNPACK_4_I16_I32(t2, t3, t6, t7) \
    UNPACK_4_I16_I32(o7, o1, o0, o6) \
 \
    o7 = -o7; \
    o1 = -o1; \
 \
    o3 = vec_add(t2, t3); \
    o4 = vec_sub(t2, t3); \
    o5 = vec_sub(t6, t7); \
    o2 = vec_add(t6, t7); \
 \
    i32x4 v181 = vec_splats(181); \
    i32x4 v128 = vec_splats(128); \
    u32x4 v8 = vec_splat_u32(8); \
 \
    o2 = vec_mul(o2, v181); \
    o3 = vec_mul(o3, v181); \
    o4 = vec_mul(o4, v181); \
    o5 = vec_mul(o5, v181); \
 \
    SCALE_ROUND_4(o2, o3, o4, o5, v128, v8) \
 \
    o3 = -o3; \
    o5 = -o5; \
}

#define adst_8_in(c0, c1, c2, c3, c4, c5, c6, c7, c01, c23, c45, c67) \
{\
    ADST_INNER_8(c0, c1, c2, c3, c4, c5, c6, c7, \
                 c0, c1, c2, c3, c4, c5, c6, c7) \
    c01 = vec_packs(c0, c1); \
    c23 = vec_packs(c2, c3); \
    c45 = vec_packs(c4, c5); \
    c67 = vec_packs(c6, c7); \
    UNPACK_PAIR_I16_I32(c0, c1, c01) \
    UNPACK_PAIR_I16_I32(c2, c3, c23) \
    UNPACK_PAIR_I16_I32(c4, c5, c45) \
    UNPACK_PAIR_I16_I32(c6, c7, c67) \
}

#define adst_8_out(c0, c1, c2, c3, c4, c5, c6, c7, c01, c23, c45, c67) \
{\
    ADST_INNER_8(c0, c1, c2, c3, c4, c5, c6, c7, \
                 c0, c1, c2, c3, c4, c5, c6, c7) \
    c01 = vec_packs(c0, c1); \
    c23 = vec_packs(c2, c3); \
    c45 = vec_packs(c4, c5); \
    c67 = vec_packs(c6, c7); \
}

#define adst_8x2_in(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
                    c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l, \
                    c0, c1, c2, c3, c4, c5, c6, c7) \
{ \
    ADST_INNER_8(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
                 c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h) \
    ADST_INNER_8(c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l, \
                 c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l) \
}

#define adst_8x2_out(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
                    c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l, \
                    c0, c1, c2, c3, c4, c5, c6, c7) \
{ \
    ADST_INNER_8(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
                 c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h) \
    ADST_INNER_8(c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l, \
                 c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l) \
    PACK_8(c0, c1, c2, c3, c4, c5, c6, c7, \
           c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
           c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l) \
}

#define flipadst_8_in(c0, c1, c2, c3, c4, c5, c6, c7, c01, c23, c45, c67) \
{\
    ADST_INNER_8(c0, c1, c2, c3, c4, c5, c6, c7, \
                 c7, c6, c5, c4, c3, c2, c1, c0) \
    c01 = vec_packs(c0, c1); \
    c23 = vec_packs(c2, c3); \
    c45 = vec_packs(c4, c5); \
    c67 = vec_packs(c6, c7); \
    UNPACK_PAIR_I16_I32(c0, c1, c01) \
    UNPACK_PAIR_I16_I32(c2, c3, c23) \
    UNPACK_PAIR_I16_I32(c4, c5, c45) \
    UNPACK_PAIR_I16_I32(c6, c7, c67) \
}

#define flipadst_8_out(c0, c1, c2, c3, c4, c5, c6, c7, c01, c23, c45, c67) \
{\
    ADST_INNER_8(c0, c1, c2, c3, c4, c5, c6, c7, \
                 c7, c6, c5, c4, c3, c2, c1, c0) \
    c01 = vec_packs(c0, c1); \
    c23 = vec_packs(c2, c3); \
    c45 = vec_packs(c4, c5); \
    c67 = vec_packs(c6, c7); \
}

#define flipadst_8x2_in(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
                        c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l, \
                        c0, c1, c2, c3, c4, c5, c6, c7) \
{ \
    ADST_INNER_8(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
                 c7h, c6h, c5h, c4h, c3h, c2h, c1h, c0h) \
    ADST_INNER_8(c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l, \
                 c7l, c6l, c5l, c4l, c3l, c2l, c1l, c0l) \
}

#define flipadst_8x2_out(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
                         c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l, \
                         c0, c1, c2, c3, c4, c5, c6, c7) \
{ \
    ADST_INNER_8(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
                 c7h, c6h, c5h, c4h, c3h, c2h, c1h, c0h) \
    ADST_INNER_8(c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l, \
                 c7l, c6l, c5l, c4l, c3l, c2l, c1l, c0l) \
    PACK_8(c0, c1, c2, c3, c4, c5, c6, c7, \
           c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
           c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l) \
}

void dav1d_inv_txfm_add_dct_dct_4x8_8bpc_pwr9(uint8_t *dst, const ptrdiff_t stride,
                                              int16_t *const coeff, const int eob)
{
    i16x8 v = vec_splats((int16_t)(2896*8));

    if (eob < 1) {
        return dc_only_4xN(dst, stride, coeff, 2, 1, 0);
    }

    LOAD_SCALE_COEFF_4x8(coeff, v)

    dct_4_in(c0, c1, c2, c3, c01, c23)
    dct_4_in(c4, c5, c6, c7, c45, c67)


    memset(coeff, 0, sizeof(*coeff) * 4 * 8);

    TRANSPOSE4_I32(c0, c1, c2, c3);
    TRANSPOSE4_I32(c4, c5, c6, c7);

    dct_8_out(c0, c1, c2, c3, c4, c5, c6, c7, c01, c23, c45, c67)

    LOAD_DECLARE_4(dst, stride, a, b, cc, d)
    LOAD_DECLARE_4(dst + 4 * stride, stride, e, f, g, hh)

    APPLY_COEFF_4(a, b, cc, d, c01, c23)
    APPLY_COEFF_4(e, f, g, hh, c45, c67)

    STORE_4(dst, stride, a, b, cc, d)
    STORE_4(dst + 4 * stride, stride, e, f, g, hh)
}


#define inv_txfm_fn4x8(type1, type2) \
void dav1d_inv_txfm_add_##type1##_##type2##_4x8_8bpc_pwr9(uint8_t *dst, const ptrdiff_t stride, \
                                                          int16_t *const coeff, const int eob) \
{ \
    i16x8 v = vec_splats((int16_t)(2896*8)); \
    LOAD_SCALE_COEFF_4x8(coeff, v) \
    type1##_4_in(c0, c1, c2, c3, c01, c23) \
    type1##_4_in(c4, c5, c6, c7, c45, c67) \
    memset(coeff, 0, sizeof(*coeff) * 4 * 8); \
    TRANSPOSE4_I32(c0, c1, c2, c3); \
    TRANSPOSE4_I32(c4, c5, c6, c7); \
    type2##_8_out(c0, c1, c2, c3, c4, c5, c6, c7, c01, c23, c45, c67) \
    LOAD_DECLARE_4(dst, stride, a, b, c, d) \
    LOAD_DECLARE_4(dst + 4 * stride, stride, e, f, g, h) \
    APPLY_COEFF_4(a, b, c, d, c01, c23) \
    APPLY_COEFF_4(e, f, g, h, c45, c67) \
    STORE_4(dst, stride, a, b, c, d) \
    STORE_4(dst + 4 * stride, stride, e, f, g, h) \
}

inv_txfm_fn4x8(adst,     dct     )
inv_txfm_fn4x8(dct,      adst    )
inv_txfm_fn4x8(dct,      flipadst)
inv_txfm_fn4x8(flipadst, dct     )
inv_txfm_fn4x8(adst,     flipadst)
inv_txfm_fn4x8(flipadst, adst    )
inv_txfm_fn4x8(identity, dct     )
inv_txfm_fn4x8(dct,      identity)
inv_txfm_fn4x8(identity, flipadst)
inv_txfm_fn4x8(flipadst, identity)
inv_txfm_fn4x8(identity, adst   )
inv_txfm_fn4x8(adst,     identity)
inv_txfm_fn4x8(identity, identity)
inv_txfm_fn4x8(adst,     adst    )
inv_txfm_fn4x8(flipadst, flipadst)


void dav1d_inv_txfm_add_dct_dct_8x4_8bpc_pwr9(uint8_t *dst, const ptrdiff_t stride,
                                              int16_t *const coeff, const int eob)
{
    i16x8 v = vec_splats((int16_t)(2896*8));

    if (eob < 1) {
        return dc_only_8xN(dst, stride, coeff, 1, 1, 0);
    }

    LOAD_SCALE_COEFF_8x4(coeff, v)

    dct_8_in(c0, c1, c2, c3, c4, c5, c6, c7, c01, c23, c45, c67)

    memset(coeff, 0, sizeof(*coeff) * 8 * 4);

    TRANSPOSE4_I32(c0, c1, c2, c3)
    TRANSPOSE4_I32(c4, c5, c6, c7)

    dct_4_out(c0, c1, c2, c3, c01, c23)
    dct_4_out(c4, c5, c6, c7, c45, c67)

    LOAD_DECLARE_4(dst, stride, ae, bf, cg, dh)

    i16x8 c04 = (i16x8)vec_mergeh((u64x2)c01, (u64x2)c45);
    i16x8 c15 = (i16x8)vec_mergel((u64x2)c01, (u64x2)c45);
    i16x8 c26 = (i16x8)vec_mergeh((u64x2)c23, (u64x2)c67);
    i16x8 c37 = (i16x8)vec_mergel((u64x2)c23, (u64x2)c67);

    APPLY_COEFF_8x4(ae, bf, c04, c15)
    APPLY_COEFF_8x4(cg, dh, c26, c37)

    STORE_8(dst, stride, ae, bf, cg, dh)
}


#define inv_txfm_fn8x4(type1, type2) \
void dav1d_inv_txfm_add_##type1##_##type2##_8x4_8bpc_pwr9(uint8_t *dst, const ptrdiff_t stride, \
                                                          int16_t *const coeff, const int eob) \
{ \
    i16x8 v = vec_splats((int16_t)(2896*8)); \
    LOAD_SCALE_COEFF_8x4(coeff, v) \
    type1##_8_in(c0, c1, c2, c3, c4, c5, c6, c7, c01, c23, c45, c67) \
    memset(coeff, 0, sizeof(*coeff) * 8 * 4); \
    TRANSPOSE4_I32(c0, c1, c2, c3) \
    TRANSPOSE4_I32(c4, c5, c6, c7) \
    type2##_4_out(c0, c1, c2, c3, c01, c23) \
    type2##_4_out(c4, c5, c6, c7, c45, c67) \
    LOAD_DECLARE_4(dst, stride, ae, bf, cg, dh) \
    i16x8 c04 = (i16x8)vec_mergeh((u64x2)c01, (u64x2)c45); \
    i16x8 c15 = (i16x8)vec_mergel((u64x2)c01, (u64x2)c45); \
    i16x8 c26 = (i16x8)vec_mergeh((u64x2)c23, (u64x2)c67); \
    i16x8 c37 = (i16x8)vec_mergel((u64x2)c23, (u64x2)c67); \
    APPLY_COEFF_8x4(ae, bf, c04, c15) \
    APPLY_COEFF_8x4(cg, dh, c26, c37) \
    STORE_8(dst, stride, ae, bf, cg, dh) \
}
inv_txfm_fn8x4(adst,     dct     )
inv_txfm_fn8x4(dct,      adst    )
inv_txfm_fn8x4(dct,      flipadst)
inv_txfm_fn8x4(flipadst, dct     )
inv_txfm_fn8x4(adst,     flipadst)
inv_txfm_fn8x4(flipadst, adst    )
inv_txfm_fn8x4(identity, dct     )
inv_txfm_fn8x4(dct,      identity)
inv_txfm_fn8x4(identity, flipadst)
inv_txfm_fn8x4(flipadst, identity)
inv_txfm_fn8x4(identity, adst   )
inv_txfm_fn8x4(adst,     identity)
inv_txfm_fn8x4(identity, identity)
inv_txfm_fn8x4(adst,     adst    )
inv_txfm_fn8x4(flipadst, flipadst)

void dav1d_inv_txfm_add_dct_dct_8x8_8bpc_pwr9(uint8_t *dst, const ptrdiff_t stride,
                                              int16_t *const coeff, const int eob)
{
    if (eob < 1) {
        return dc_only_8xN(dst, stride, coeff, 2, 0, 1);
    }

    LOAD_COEFF_8x8(coeff)

    dct_8x2_in(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h,
               c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l,
               c0, c1, c2, c3, c4, c5, c6, c7)

    memset(coeff, 0, sizeof(*coeff) * 8 * 8);

    SCALE_ROUND_4(c0h, c1h, c2h, c3h, vec_splat_s32(1), vec_splat_u32(1))
    SCALE_ROUND_4(c4h, c5h, c6h, c7h, vec_splat_s32(1), vec_splat_u32(1))
    SCALE_ROUND_4(c0l, c1l, c2l, c3l, vec_splat_s32(1), vec_splat_u32(1))
    SCALE_ROUND_4(c4l, c5l, c6l, c7l, vec_splat_s32(1), vec_splat_u32(1))

    TRANSPOSE8_I32(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h,
                   c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l)

    dct_8x2_out(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h,
                c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l,
                c0, c1, c2, c3, c4, c5, c6, c7)

    LOAD_DECLARE_4(dst, stride, a, b, cc, d)
    LOAD_DECLARE_4(dst + 4 * stride, stride, e, f, g, hh)

    APPLY_COEFF_8x4(a, b, c0, c1)
    APPLY_COEFF_8x4(cc, d, c2, c3)
    APPLY_COEFF_8x4(e, f, c4, c5)
    APPLY_COEFF_8x4(g, hh, c6, c7)

    STORE_8(dst, stride, a, b, cc, d)
    STORE_8(dst + 4 * stride, stride, e, f, g, hh)
}

#define inv_txfm_fn8x8(type1, type2) \
void dav1d_inv_txfm_add_##type1##_##type2##_8x8_8bpc_pwr9(uint8_t *dst, const ptrdiff_t stride, \
                                                          int16_t *const coeff, const int eob) \
{ \
    LOAD_COEFF_8x8(coeff) \
    type1##_8x2_in(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
                   c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l, \
                   c0, c1, c2, c3, c4, c5, c6, c7) \
    SCALE_ROUND_4(c0h, c1h, c2h, c3h, vec_splat_s32(1), vec_splat_u32(1)) \
    SCALE_ROUND_4(c4h, c5h, c6h, c7h, vec_splat_s32(1), vec_splat_u32(1)) \
    SCALE_ROUND_4(c0l, c1l, c2l, c3l, vec_splat_s32(1), vec_splat_u32(1)) \
    SCALE_ROUND_4(c4l, c5l, c6l, c7l, vec_splat_s32(1), vec_splat_u32(1)) \
    memset(coeff, 0, sizeof(*coeff) * 8 * 8); \
    TRANSPOSE8_I32(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
                   c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l) \
    type2##_8x2_out(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
                    c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l, \
                    c0, c1, c2, c3, c4, c5, c6, c7) \
    LOAD_DECLARE_4(dst, stride, a, b, c, d) \
    LOAD_DECLARE_4(dst + 4 * stride, stride, e, f, g, h) \
    APPLY_COEFF_8x4(a, b, c0, c1) \
    APPLY_COEFF_8x4(c, d, c2, c3) \
    APPLY_COEFF_8x4(e, f, c4, c5) \
    APPLY_COEFF_8x4(g, h, c6, c7) \
    STORE_8(dst, stride, a, b, c, d) \
    STORE_8(dst + 4 * stride, stride, e, f, g, h) \
}
inv_txfm_fn8x8(adst,     dct     )
inv_txfm_fn8x8(dct,      adst    )
inv_txfm_fn8x8(dct,      flipadst)
inv_txfm_fn8x8(flipadst, dct     )
inv_txfm_fn8x8(adst,     flipadst)
inv_txfm_fn8x8(flipadst, adst    )
inv_txfm_fn8x8(dct,      identity)
inv_txfm_fn8x8(flipadst, identity)
inv_txfm_fn8x8(adst,     identity)
inv_txfm_fn8x8(adst,     adst    )
inv_txfm_fn8x8(flipadst, flipadst)

// identity + scale is a no op
#define inv_txfm_fn8x8_identity(type2) \
void dav1d_inv_txfm_add_identity_##type2##_8x8_8bpc_pwr9(uint8_t *dst, const ptrdiff_t stride, \
                                                         int16_t *const coeff, const int eob) \
{ \
    LOAD_COEFF_8x8(coeff) \
    memset(coeff, 0, sizeof(*coeff) * 8 * 8); \
    TRANSPOSE8_I32(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
                   c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l) \
    type2##_8x2_out(c0h, c1h, c2h, c3h, c4h, c5h, c6h, c7h, \
                    c0l, c1l, c2l, c3l, c4l, c5l, c6l, c7l, \
                    c0, c1, c2, c3, c4, c5, c6, c7) \
    LOAD_DECLARE_4(dst, stride, a, b, c, d) \
    LOAD_DECLARE_4(dst + 4 * stride, stride, e, f, g, h) \
    APPLY_COEFF_8x4(a, b, c0, c1) \
    APPLY_COEFF_8x4(c, d, c2, c3) \
    APPLY_COEFF_8x4(e, f, c4, c5) \
    APPLY_COEFF_8x4(g, h, c6, c7) \
    STORE_8(dst, stride, a, b, c, d) \
    STORE_8(dst + 4 * stride, stride, e, f, g, h) \
}
inv_txfm_fn8x8_identity(dct     )
inv_txfm_fn8x8_identity(flipadst)
inv_txfm_fn8x8_identity(adst    )
inv_txfm_fn8x8_identity(identity)

#define CLIP16_I32_8(a, b, c, d, e, f, g, h, \
                     ab, cd, ef, gh) \
{ \
    ab = vec_packs(a, b); \
    cd = vec_packs(c, d); \
    ef = vec_packs(e, f); \
    gh = vec_packs(g, h); \
    UNPACK_PAIR_I16_I32(a, b, ab) \
    UNPACK_PAIR_I16_I32(c, d, cd) \
    UNPACK_PAIR_I16_I32(e, f, ef) \
    UNPACK_PAIR_I16_I32(g, h, gh) \
}

#define MUL_4_INPLACE(a, b, c, d, v) \
    a = vec_mul(a, v); \
    b = vec_mul(b, v); \
    c = vec_mul(c, v); \
    d = vec_mul(d, v); \

#define IDENTITY_16_V(v) \
{ \
    i16x8 v_ = vec_adds(v, v); \
    v = vec_mradds(v, v1697_16, v_); \
}

#define IDENTITY_16_INNER(c00c01, c02c03, c04c05, c06c07, \
                          c08c09, c10c11, c12c13, c14c15) \
{ \
    i16x8 v1697_16 = vec_splats((int16_t)(1697*16)); \
    IDENTITY_16_V(c00c01) \
    IDENTITY_16_V(c02c03) \
    IDENTITY_16_V(c04c05) \
    IDENTITY_16_V(c06c07) \
    IDENTITY_16_V(c08c09) \
    IDENTITY_16_V(c10c11) \
    IDENTITY_16_V(c12c13) \
    IDENTITY_16_V(c14c15) \
}

#define IDENTITY_16_4_I32(a, b, c, d) \
{ \
    i32x4 a2 = vec_add(a, a); \
    i32x4 b2 = vec_add(b, b); \
    i32x4 c2 = vec_add(c, c); \
    i32x4 d2 = vec_add(d, d); \
    MUL_4_INPLACE(a, b, c, d, v1697) \
    SCALE_ROUND_4(a, b, c, d, v1024, vec_splat_u32(11)); \
    a = vec_add(a2, a); \
    b = vec_add(b2, b); \
    c = vec_add(c2, c); \
    d = vec_add(d2, d); \
}


#define identity_16_in(c00, c01, c02, c03, c04, c05, c06, c07, \
                       c08, c09, c10, c11, c12, c13, c14, c15, \
                       c00c01, c02c03, c04c05, c06c07, \
                       c08c09, c10c11, c12c13, c14c15) \
{ \
    DECLARE_SPLAT_I32(1697) \
    DECLARE_SPLAT_I32(1024) \
    IDENTITY_16_4_I32(c00, c01, c02, c03) \
    IDENTITY_16_4_I32(c04, c05, c06, c07) \
    IDENTITY_16_4_I32(c08, c09, c10, c11) \
    IDENTITY_16_4_I32(c12, c13, c14, c15) \
}

#define identity_16_out(c00, c01, c02, c03, c04, c05, c06, c07, \
                        c08, c09, c10, c11, c12, c13, c14, c15, \
                        c00c01, c02c03, c04c05, c06c07, \
                        c08c09, c10c11, c12c13, c14c15) \
{ \
    PACK_8(c00c01, c02c03, c04c05, c06c07, c08c09, c10c11, c12c13, c14c15, \
           c00, c02, c04, c06, c08, c10, c12, c14, \
           c01, c03, c05, c07, c09, c11, c13, c15)  \
    IDENTITY_16_INNER(c00c01, c02c03, c04c05, c06c07, \
                      c08c09, c10c11, c12c13, c14c15) \
}

#define IDCT_16_INNER(c00, c01, c02, c03, c04, c05, c06, c07, \
                      c08, c09, c10, c11, c12, c13, c14, c15, \
                      c00c03, c01c02, c07c04, c06c05, \
                      c08c11, c09c10, c14c13, c15c12) \
    IDCT_8_INNER(c00, c02, c04, c06, c08, c10, c12, c14, \
                 c00c03, c01c02, c07c04, c06c05) \
    DECLARE_SPLAT_I32(128) \
    DECLARE_SPLAT_I32(181) \
    DECLARE_SPLAT_I32(401) \
    DECLARE_SPLAT_I32(4076) \
    DECLARE_SPLAT_I32(3166) \
    DECLARE_SPLAT_I32(2598) \
    DECLARE_SPLAT_I32(1931) \
    DECLARE_SPLAT_I32(3612) \
    DECLARE_SPLAT_I32(3920) \
    DECLARE_SPLAT_I32(1189) \
    DECLARE_SPLAT_I32(1567) \
    DECLARE_SPLAT_I32(3784) \
\
    DECLARE_MUL_PAIR_I32(c01, c15,  v401, v4076) \
    DECLARE_MUL_PAIR_I32(c09, c07, v3166, v2598) \
    DECLARE_MUL_PAIR_I32(c05, c11, v1931, v3612) \
    DECLARE_MUL_PAIR_I32(c13, c03, v3920, v1189) \
\
    DECLARE_ADD_SUB_PAIR(t15a, t08a, c01, c15, v4076,  v401) \
    DECLARE_ADD_SUB_PAIR(t14a, t09a, c09, c07, v2598, v3166) \
    DECLARE_ADD_SUB_PAIR(t13a, t10a, c05, c11, v3612, v1931) \
    DECLARE_ADD_SUB_PAIR(t12a, t11a, c13, c03, v1189, v3920) \
\
    SCALE_ROUND_4(t15a, t08a, t14a, t09a, v2048, v12) \
    SCALE_ROUND_4(t13a, t10a, t12a, t11a, v2048, v12) \
\
    CLIP16_I32_8(t15a, t08a, t14a, t09a, \
                 t13a, t10a, t12a, t11a, \
                 c08c11, c09c10, c14c13, c15c12) \
    DECLARE_ADD_SUB_PAIR(t08, t09, t08a, t09a,,) \
    DECLARE_ADD_SUB_PAIR(t11, t10, t11a, t10a,,) \
    DECLARE_ADD_SUB_PAIR(t12, t13, t12a, t13a,,) \
    DECLARE_ADD_SUB_PAIR(t15, t14, t15a, t14a,,) \
\
    CLIP16_I32_8(t08, t09, t11, t10, \
                 t12, t13, t15, t14, \
                 c08c11, c09c10, c14c13, c15c12) \
\
    DECLARE_MUL_PAIR_I32(t14, t09, v1567, v3784) \
    DECLARE_MUL_PAIR_I32(t13, t10, v1567, v3784) \
    \
    ADD_SUB_PAIR(t14a, t09a, t14, t09, v3784, v1567) \
    ADD_SUB_PAIR(t10a, t13a, t13, t10, v3784, v1567) \
    t10a = -t10a; \
\
    SCALE_ROUND_4(t14a, t09a, t13a, t10a, v2048, v12) \
\
    ADD_SUB_PAIR(t08a, t11a, t08, t11,,) \
    ADD_SUB_PAIR(t09, t10, t09a, t10a,,) \
    ADD_SUB_PAIR(t15a, t12a, t15, t12,,) \
    ADD_SUB_PAIR(t14, t13, t14a, t13a,,) \
\
    CLIP16_I32_8(t08a, t11a, t09, t10, \
                 t15a, t12a, t14, t13, \
                 c08c11, c09c10, c14c13, c15c12) \
    ADD_SUB_PAIR(t13a, t10a, t13, t10,,); \
    ADD_SUB_PAIR(t12, t11, t12a, t11a,,); \
\
    MUL_4_INPLACE(t13a, t10a, t12, t11, v181); \
    SCALE_ROUND_4(t13a, t10a, t12, t11, v128, vec_splat_u32(8)) \
\
    DECLARE_PACK_4(t15at12, t14t13a, t08at11, t09t10a, \
                   t15a, t14, t08a, t09, \
                   t12, t13a, t11,  t10a) \
\
    c15c12 = vec_subs(c00c03, t15at12); \
    c14c13 = vec_subs(c01c02, t14t13a); \
    c08c11 = vec_subs(c07c04, t08at11); \
    c09c10 = vec_subs(c06c05, t09t10a); \
    c00c03 = vec_adds(c00c03, t15at12); \
    c01c02 = vec_adds(c01c02, t14t13a); \
    c07c04 = vec_adds(c07c04, t08at11); \
    c06c05 = vec_adds(c06c05, t09t10a); \

#define dct_16_out(c00, c01, c02, c03, c04, c05, c06, c07, \
                   c08, c09, c10, c11, c12, c13, c14, c15, \
                   c00c01, c02c03, c04c05, c06c07, c08c09, c10c11, c12c13, c14c15) \
\
    i16x8 c00c03, c01c02, c07c04, c06c05, c08c11, c09c10, c14c13, c15c12; \
    IDCT_16_INNER(c00, c01, c02, c03, c04, c05, c06, c07, c08, c09, c10, c11, c12, c13, c14, c15, \
                  c00c03, c01c02, c07c04, c06c05, c08c11, c09c10, c14c13, c15c12) \
    c00c01 = (i16x8)vec_mergeh((u64x2)c00c03, (u64x2)c01c02); \
    c02c03 = (i16x8)vec_mergel((u64x2)c01c02, (u64x2)c00c03); \
    c04c05 = (i16x8)vec_mergel((u64x2)c07c04, (u64x2)c06c05); \
    c06c07 = (i16x8)vec_mergeh((u64x2)c06c05, (u64x2)c07c04); \
    c08c09 = (i16x8)vec_mergeh((u64x2)c08c11, (u64x2)c09c10); \
    c10c11 = (i16x8)vec_mergel((u64x2)c09c10, (u64x2)c08c11); \
    c12c13 = (i16x8)vec_mergel((u64x2)c15c12, (u64x2)c14c13); \
    c14c15 = (i16x8)vec_mergeh((u64x2)c14c13, (u64x2)c15c12); \

#define dct_16_in(c00, c01, c02, c03, c04, c05, c06, c07, \
                  c08, c09, c10, c11, c12, c13, c14, c15, \
                  c00c03, c01c02, c07c04, c06c05, c08c11, c09c10, c14c13, c15c12) \
\
    IDCT_16_INNER(c00, c01, c02, c03, c04, c05, c06, c07, c08, c09, c10, c11, c12, c13, c14, c15, \
                  c00c03, c01c02, c07c04, c06c05, c08c11, c09c10, c14c13, c15c12) \
    UNPACK_PAIR_I16_I32(c00, c03, c00c03) \
    UNPACK_PAIR_I16_I32(c01, c02, c01c02) \
    UNPACK_PAIR_I16_I32(c07, c04, c07c04) \
    UNPACK_PAIR_I16_I32(c06, c05, c06c05) \
    UNPACK_PAIR_I16_I32(c08, c11, c08c11) \
    UNPACK_PAIR_I16_I32(c09, c10, c09c10) \
    UNPACK_PAIR_I16_I32(c14, c13, c14c13) \
    UNPACK_PAIR_I16_I32(c15, c12, c15c12) \


#define dct_4x4_in(cA0, cA1, cA2, cA3, cB0, cB1, cB2, cB3, \
                   cC0, cC1, cC2, cC3, cD0, cD1, cD2, cD3, \
                   a0b0, c0d0, a1b1, c1d1, a2b2, c2d2, a3b3, c3d3) \
    dct_4_in(cA0, cA1, cA2, cA3, a0b0, c0d0) \
    dct_4_in(cB0, cB1, cB2, cB3, a1b1, c1d1) \
    dct_4_in(cC0, cC1, cC2, cC3, a2b2, c2d2) \
    dct_4_in(cD0, cD1, cD2, cD3, a3b3, c3d3)


#define PACK_4x4(c00, c01, c02, c03, \
                 c04, c05, c06, c07, \
                 c08, c09, c10, c11, \
                 c12, c13, c14, c15, \
                 c00c01, c02c03, c04c05, c06c07, \
                 c08c09, c10c11, c12c13, c14c15) \
{ \
    c00c01 = vec_packs(c00, c04); c02c03 = vec_packs(c08, c12); \
    c04c05 = vec_packs(c01, c05); c06c07 = vec_packs(c09, c13); \
    c08c09 = vec_packs(c02, c06); c10c11 = vec_packs(c10, c14); \
    c12c13 = vec_packs(c03, c07); c14c15 = vec_packs(c11, c15); \
}



#define dct_4x4_out(c00, c01, c02, c03, \
                    c04, c05, c06, c07, \
                    c08, c09, c10, c11, \
                    c12, c13, c14, c15, \
                    c00c01, c02c03, c04c05, c06c07, \
                    c08c09, c10c11, c12c13, c14c15) \
{ \
    IDCT_4_INNER(c00, c01, c02, c03) \
    IDCT_4_INNER(c04, c05, c06, c07) \
    IDCT_4_INNER(c08, c09, c10, c11) \
    IDCT_4_INNER(c12, c13, c14, c15) \
\
    PACK_4x4(c00, c01, c02, c03, \
             c04, c05, c06, c07, \
             c08, c09, c10, c11, \
             c12, c13, c14, c15, \
             c00c01, c02c03, c04c05, c06c07, \
             c08c09, c10c11, c12c13, c14c15) \
}

#define IDENTITY_4_I32(a, b, c, d) \
{ \
    DECLARE_SPLAT_I32(5793) \
    DECLARE_SPLAT_I32(2048) \
    MUL_4_INPLACE(a, b, c, d, v5793) \
    SCALE_ROUND_4(a, b, c, d, v2048, vec_splat_u32(12)) \
}

#define identity_4x4_in(cA0, cA1, cA2, cA3, cB0, cB1, cB2, cB3, \
                       cC0, cC1, cC2, cC3, cD0, cD1, cD2, cD3, \
                       a0b0, c0d0, a1b1, c1d1, a2b2, c2d2, a3b3, c3d3) \
{ \
    IDENTITY_4_I32(cA0, cA1, cA2, cA3) \
    IDENTITY_4_I32(cB0, cB1, cB2, cB3) \
    IDENTITY_4_I32(cC0, cC1, cC2, cC3) \
    IDENTITY_4_I32(cD0, cD1, cD2, cD3) \
}

#define identity_4x4_out(c00, c01, c02, c03, \
                         c04, c05, c06, c07, \
                         c08, c09, c10, c11, \
                         c12, c13, c14, c15, \
                         c00c01, c02c03, c04c05, c06c07, \
                         c08c09, c10c11, c12c13, c14c15) \
{ \
    PACK_4x4(c00, c01, c02, c03, \
             c04, c05, c06, c07, \
             c08, c09, c10, c11, \
             c12, c13, c14, c15, \
             c00c01, c02c03, c04c05, c06c07, \
             c08c09, c10c11, c12c13, c14c15) \
    IDENTITY_4(c00c01, c02c03) \
    IDENTITY_4(c04c05, c06c07) \
    IDENTITY_4(c08c09, c10c11) \
    IDENTITY_4(c12c13, c14c15) \
}

#define adst_4x4_in(cA0, cA1, cA2, cA3, cB0, cB1, cB2, cB3, \
                    cC0, cC1, cC2, cC3, cD0, cD1, cD2, cD3, \
                    a0b0, c0d0, a1b1, c1d1, a2b2, c2d2, a3b3, c3d3) \
    adst_4_in(cA0, cA1, cA2, cA3, a0b0, c0d0) \
    adst_4_in(cB0, cB1, cB2, cB3, a1b1, c1d1) \
    adst_4_in(cC0, cC1, cC2, cC3, a2b2, c2d2) \
    adst_4_in(cD0, cD1, cD2, cD3, a3b3, c3d3)

#define adst_4x4_out(c00, c01, c02, c03, \
                     c04, c05, c06, c07, \
                     c08, c09, c10, c11, \
                     c12, c13, c14, c15, \
                     c00c01, c02c03, c04c05, c06c07, \
                     c08c09, c10c11, c12c13, c14c15) \
{ \
    ADST_INNER_4(c00, c01, c02, c03, c00, c01, c02, c03) \
    ADST_INNER_4(c04, c05, c06, c07, c04, c05, c06, c07) \
    ADST_INNER_4(c08, c09, c10, c11, c08, c09, c10, c11) \
    ADST_INNER_4(c12, c13, c14, c15, c12, c13, c14, c15) \
\
    PACK_4x4(c00, c01, c02, c03, \
             c04, c05, c06, c07, \
             c08, c09, c10, c11, \
             c12, c13, c14, c15, \
             c00c01, c02c03, c04c05, c06c07, \
             c08c09, c10c11, c12c13, c14c15) \
}

#define flipadst_4x4_in(cA0, cA1, cA2, cA3, cB0, cB1, cB2, cB3, \
                        cC0, cC1, cC2, cC3, cD0, cD1, cD2, cD3, \
                        a0b0, c0d0, a1b1, c1d1, a2b2, c2d2, a3b3, c3d3) \
    flipadst_4_in(cA0, cA1, cA2, cA3, a0b0, c0d0) \
    flipadst_4_in(cB0, cB1, cB2, cB3, a1b1, c1d1) \
    flipadst_4_in(cC0, cC1, cC2, cC3, a2b2, c2d2) \
    flipadst_4_in(cD0, cD1, cD2, cD3, a3b3, c3d3)

#define flipadst_4x4_out(c00, c01, c02, c03, \
                         c04, c05, c06, c07, \
                         c08, c09, c10, c11, \
                         c12, c13, c14, c15, \
                         c00c01, c02c03, c04c05, c06c07, \
                         c08c09, c10c11, c12c13, c14c15) \
{ \
    ADST_INNER_4(c00, c01, c02, c03, c03, c02, c01, c00) \
    ADST_INNER_4(c04, c05, c06, c07, c07, c06, c05, c04) \
    ADST_INNER_4(c08, c09, c10, c11, c11, c10, c09, c08) \
    ADST_INNER_4(c12, c13, c14, c15, c15, c14, c13, c12) \
\
    PACK_4x4(c00, c01, c02, c03, \
             c04, c05, c06, c07, \
             c08, c09, c10, c11, \
             c12, c13, c14, c15, \
             c00c01, c02c03, c04c05, c06c07, \
             c08c09, c10c11, c12c13, c14c15) \
}

#define ADST_INNER_16(c00, c01, c02, c03, c04, c05, c06, c07, \
                      c08, c09, c10, c11, c12, c13, c14, c15, \
                      o00, o01, o02, o03, o04, o05, o06, o07, \
                      o08, o09, o10, o11, o12, o13, o14, o15, \
                      c00c01, c02c03, c04c05, c06c07) \
    DECLARE_SPLAT_I32(2048); \
    u32x4 v12 = vec_splat_u32(12); \
    DECLARE_SPLAT_I32(4091) \
    DECLARE_SPLAT_I32(201) \
    DECLARE_SPLAT_I32(3973) \
    DECLARE_SPLAT_I32(995) \
    DECLARE_SPLAT_I32(3703) \
    DECLARE_SPLAT_I32(1751) \
    DECLARE_SPLAT_I32(3290) \
    DECLARE_SPLAT_I32(2440) \
    DECLARE_SPLAT_I32(2751) \
    DECLARE_SPLAT_I32(3035) \
    DECLARE_SPLAT_I32(2106) \
    DECLARE_SPLAT_I32(3513) \
    DECLARE_SPLAT_I32(1380) \
    DECLARE_SPLAT_I32(3857) \
    DECLARE_SPLAT_I32(601) \
    DECLARE_SPLAT_I32(4052) \
\
    DECLARE_MUL_PAIR_I32(c15, c00, v4091, v201) \
    DECLARE_MUL_PAIR_I32(c13, c02, v3973, v995) \
    DECLARE_MUL_PAIR_I32(c11, c04, v3703, v1751) \
    DECLARE_MUL_PAIR_I32(c09, c06, v3290, v2440) \
    DECLARE_MUL_PAIR_I32(c07, c08, v2751, v3035) \
    DECLARE_MUL_PAIR_I32(c05, c10, v2106, v3513) \
    DECLARE_MUL_PAIR_I32(c03, c12, v1380, v3857) \
    DECLARE_MUL_PAIR_I32(c01, c14,  v601, v4052) \
\
    DECLARE_ADD_SUB_PAIR(t00, t01, c15, c00, v4091, v201);\
    DECLARE_ADD_SUB_PAIR(t02, t03, c13, c02, v3973, v995) \
    DECLARE_ADD_SUB_PAIR(t04, t05, c11, c04, v3703, v1751) \
    DECLARE_ADD_SUB_PAIR(t06, t07, c09, c06, v3290, v2440) \
    DECLARE_ADD_SUB_PAIR(t08, t09, c07, c08, v2751, v3035) \
    DECLARE_ADD_SUB_PAIR(t10, t11, c05, c10, v2106, v3513) \
    DECLARE_ADD_SUB_PAIR(t12, t13, c03, c12, v1380, v3857) \
    DECLARE_ADD_SUB_PAIR(t14, t15, c01, c14,  v601, v4052) \
\
    SCALE_ROUND_4(t00, t01, t02, t03, v2048, v12) \
    SCALE_ROUND_4(t04, t05, t06, t07, v2048, v12) \
    SCALE_ROUND_4(t08, t09, t10, t11, v2048, v12) \
    SCALE_ROUND_4(t12, t13, t14, t15, v2048, v12) \
\
    DECLARE_ADD_SUB_PAIR(t00a, t08a, t00, t08,,) \
    DECLARE_ADD_SUB_PAIR(t01a, t09a, t01, t09,,) \
    DECLARE_ADD_SUB_PAIR(t02a, t10a, t02, t10,,) \
    DECLARE_ADD_SUB_PAIR(t03a, t11a, t03, t11,,) \
    DECLARE_ADD_SUB_PAIR(t04a, t12a, t04, t12,,) \
    DECLARE_ADD_SUB_PAIR(t05a, t13a, t05, t13,,) \
    DECLARE_ADD_SUB_PAIR(t06a, t14a, t06, t14,,) \
    DECLARE_ADD_SUB_PAIR(t07a, t15a, t07, t15,,) \
\
    CLIP16_I32_8(t00a, t08a, t01a, t09a, t02a, t10a, t03a, t11a, \
                 c00c01, c02c03, c04c05, c06c07); \
    CLIP16_I32_8(t04a, t12a, t05a, t13a, t06a, t14a, t07a, t15a, \
                 c00c01, c02c03, c04c05, c06c07); \
\
    DECLARE_SPLAT_I32(4017) \
    DECLARE_SPLAT_I32(799) \
    DECLARE_SPLAT_I32(2276) \
    DECLARE_SPLAT_I32(3406) \
\
    DECLARE_MUL_PAIR_I32(t08a, t09a, v4017,  v799); \
    DECLARE_MUL_PAIR_I32(t10a, t11a, v2276, v3406); \
    DECLARE_MUL_PAIR_I32(t13a, t12a,  v799, v4017); \
    DECLARE_MUL_PAIR_I32(t15a, t14a, v3406, v2276); \
\
    ADD_SUB_PAIR(t08, t09, t08a, t09a, v4017,  v799); \
    ADD_SUB_PAIR(t10, t11, t10a, t11a, v2276, v3406); \
    ADD_SUB_PAIR(t13, t12, t13a, t12a,  v799, v4017); \
    ADD_SUB_PAIR(t15, t14, t15a, t14a, v3406, v2276); \
\
    SCALE_ROUND_4(t08, t09, t10, t11, v2048, v12) \
    SCALE_ROUND_4(t13, t12, t15, t14, v2048, v12) \
\
    ADD_SUB_PAIR(t00, t04, t00a, t04a,,); \
    ADD_SUB_PAIR(t01, t05, t01a, t05a,,); \
    ADD_SUB_PAIR(t02, t06, t02a, t06a,,); \
    ADD_SUB_PAIR(t03, t07, t03a, t07a,,); \
    ADD_SUB_PAIR(t08a, t12a, t08, t12,,); \
    ADD_SUB_PAIR(t09a, t13a, t09, t13,,); \
    ADD_SUB_PAIR(t10a, t14a, t10, t14,,); \
    ADD_SUB_PAIR(t11a, t15a, t11, t15,,); \
\
    CLIP16_I32_8(t00, t04, t01, t05, t02, t06, t03, t07, \
                 c00c01, c02c03, c04c05, c06c07) \
    CLIP16_I32_8(t08a, t12a, t09a, t13a, t10a, t14a, t11a, t15a, \
                 c00c01, c02c03, c04c05, c06c07) \
\
    DECLARE_SPLAT_I32(3784) \
    DECLARE_SPLAT_I32(1567) \
\
    DECLARE_MUL_PAIR_I32(t04, t05, v3784, v1567) \
    DECLARE_MUL_PAIR_I32(t07, t06, v1567, v3784) \
    DECLARE_MUL_PAIR_I32(t12a, t13a, v3784, v1567) \
    DECLARE_MUL_PAIR_I32(t15a, t14a, v1567, v3784) \
\
    ADD_SUB_PAIR(t04a, t05a, t04, t05, v3784, v1567) \
    ADD_SUB_PAIR(t07a, t06a, t07, t06, v1567, v3784) \
    ADD_SUB_PAIR(t12, t13, t12a, t13a, v3784, v1567) \
    ADD_SUB_PAIR(t15, t14, t15a, t14a, v1567, v3784) \
\
    SCALE_ROUND_4(t04a, t05a, t07a, t06a, v2048, v12) \
    SCALE_ROUND_4(t12, t13, t15, t14, v2048, v12) \
\
    ADD_SUB_PAIR(o00, t02a, t00,  t02,,) \
    ADD_SUB_PAIR(o15, t03a, t01,  t03,,) \
    ADD_SUB_PAIR(o03, t06,  t04a, t06a,,) \
    ADD_SUB_PAIR(o12, t07,  t05a, t07a,,) \
    ADD_SUB_PAIR(o01, t10,  t08a, t10a,,) \
    ADD_SUB_PAIR(o14, t11,  t09a, t11a,,) \
    ADD_SUB_PAIR(o02, t14a, t12,  t14,,) \
    ADD_SUB_PAIR(o13, t15a, t13,  t15,,) \
\
    CLIP16_I32_8(o00, t02a, o15, t03a, o03, t06, o12, t07, \
                 c00c01, c02c03, c04c05, c06c07) \
    CLIP16_I32_8(o01, t10, o14, t11, o02, t14a, o13, t15a, \
                 c00c01, c02c03, c04c05, c06c07) \
\
    DECLARE_SPLAT_I32(181) \
    DECLARE_SPLAT_I32(128) \
    u32x4 v8 = vec_splat_u32(8); \
\
    ADD_SUB_PAIR(o07, o08, t02a, t03a,,) \
    ADD_SUB_PAIR(o04, o11, t06,  t07,,) \
    ADD_SUB_PAIR(o06, o09, t10,  t11,,) \
    ADD_SUB_PAIR(o05, o10, t14a, t15a,,) \
\
    MUL_4_INPLACE(o07, o08, o04, o11, v181) \
    MUL_4_INPLACE(o06, o09, o05, o10, v181) \
\
    SCALE_ROUND_4(o07, o08, o04, o11, v128, v8) \
    SCALE_ROUND_4(o06, o09, o05, o10, v128, v8) \
\
    o01 = -o01; \
    o03 = -o03; \
    o05 = -o05; \
    o07 = -o07; \
    o09 = -o09; \
    o11 = -o11; \
    o13 = -o13; \
    o15 = -o15; \

#define adst_16_in(c00, c01, c02, c03, c04, c05, c06, c07, \
                   c08, c09, c10, c11, c12, c13, c14, c15, \
                   c00c01, c02c03, c04c05, c06c07, c08c09, c10c11, c12c13, c14c15) \
{ \
    ADST_INNER_16(c00, c01, c02, c03, c04, c05, c06, c07, c08, c09, c10, c11, c12, c13, c14, c15, \
                  c00, c01, c02, c03, c04, c05, c06, c07, c08, c09, c10, c11, c12, c13, c14, c15, \
                  c00c01, c02c03, c04c05, c06c07) \
}

#define adst_16_out(c00, c01, c02, c03, c04, c05, c06, c07, \
                    c08, c09, c10, c11, c12, c13, c14, c15, \
                    c00c01, c02c03, c04c05, c06c07, c08c09, c10c11, c12c13, c14c15) \
{ \
    ADST_INNER_16(c00, c01, c02, c03, c04, c05, c06, c07, c08, c09, c10, c11, c12, c13, c14, c15, \
                  c00, c01, c02, c03, c04, c05, c06, c07, c08, c09, c10, c11, c12, c13, c14, c15, \
                  c00c01, c02c03, c04c05, c06c07) \
    PACK_8(c00c01, c02c03, c04c05, c06c07, c08c09, c10c11, c12c13, c14c15, \
           c00, c02, c04, c06, c08, c10, c12, c14, \
           c01, c03, c05, c07, c09, c11, c13, c15) \
}

#define flipadst_16_in(c00, c01, c02, c03, c04, c05, c06, c07, \
                       c08, c09, c10, c11, c12, c13, c14, c15, \
                       c00c01, c02c03, c04c05, c06c07, c08c09, c10c11, c12c13, c14c15) \
{ \
    ADST_INNER_16(c00, c01, c02, c03, c04, c05, c06, c07, c08, c09, c10, c11, c12, c13, c14, c15, \
                  c15, c14, c13, c12, c11, c10, c09, c08, c07, c06, c05, c04, c03, c02, c01, c00, \
                  c00c01, c02c03, c04c05, c06c07) \
}

#define flipadst_16_out(c00, c01, c02, c03, c04, c05, c06, c07, \
                        c08, c09, c10, c11, c12, c13, c14, c15, \
                        c00c01, c02c03, c04c05, c06c07, c08c09, c10c11, c12c13, c14c15) \
{ \
    ADST_INNER_16(c00, c01, c02, c03, c04, c05, c06, c07, c08, c09, c10, c11, c12, c13, c14, c15, \
                  c15, c14, c13, c12, c11, c10, c09, c08, c07, c06, c05, c04, c03, c02, c01, c00, \
                  c00c01, c02c03, c04c05, c06c07) \
    PACK_8(c00c01, c02c03, c04c05, c06c07, c08c09, c10c11, c12c13, c14c15, \
           c00, c02, c04, c06, c08, c10, c12, c14, \
           c01, c03, c05, c07, c09, c11, c13, c15) \
}


void dav1d_inv_txfm_add_dct_dct_4x16_8bpc_pwr9(uint8_t *dst, const ptrdiff_t stride,
                                               int16_t *const coeff, const int eob
                                               HIGHBD_DECL_SUFFIX)
{
    if (eob < 1) {
        return dc_only_4xN(dst, stride, coeff, 4, 0, 1);
    }

    LOAD_COEFF_4x16(coeff)

    dct_4x4_in(cA0, cA1, cA2, cA3, cB0, cB1, cB2, cB3,
               cC0, cC1, cC2, cC3, cD0, cD1, cD2, cD3,
               a0b0, c0d0, a1b1, c1d1, a2b2, c2d2, a3b3, c3d3)

    memset(coeff, 0, sizeof(*coeff) * 4 * 16);

    SCALE_ROUND_4(cA0, cB0, cC0, cD0, vec_splat_s32(1), vec_splat_u32(1))
    SCALE_ROUND_4(cA1, cB1, cC1, cD1, vec_splat_s32(1), vec_splat_u32(1))
    SCALE_ROUND_4(cA2, cB2, cC2, cD2, vec_splat_s32(1), vec_splat_u32(1))
    SCALE_ROUND_4(cA3, cB3, cC3, cD3, vec_splat_s32(1), vec_splat_u32(1))
    TRANSPOSE4x16_I32(cA0, cA1, cA2, cA3, cB0, cB1, cB2, cB3,
                      cC0, cC1, cC2, cC3, cD0, cD1, cD2, cD3)

    dct_16_out(cA0, cA1, cA2, cA3, cB0, cB1, cB2, cB3,
               cC0, cC1, cC2, cC3, cD0, cD1, cD2, cD3,
               a0b0, c0d0, a1b1, c1d1, a2b2, c2d2, a3b3, c3d3)

    LOAD_DECLARE_4(dst, stride, l00, l01, l02, l03)
    LOAD_DECLARE_4(dst + 4 * stride, stride, l04, l05, l06, l07)
    LOAD_DECLARE_4(dst + 8 * stride, stride, l08, l09, l10, l11)
    LOAD_DECLARE_4(dst + 12 * stride, stride, l12, l13, l14, l15)

    APPLY_COEFF_4(l00, l01, l02, l03, a0b0, c0d0);
    APPLY_COEFF_4(l04, l05, l06, l07, a1b1, c1d1);
    APPLY_COEFF_4(l08, l09, l10, l11, a2b2, c2d2);
    APPLY_COEFF_4(l12, l13, l14, l15, a3b3, c3d3);

    STORE_4(dst, stride,               l00, l01, l02, l03);
    STORE_4(dst + 4 * stride, stride,  l04, l05, l06, l07);
    STORE_4(dst + 8 * stride, stride,  l08, l09, l10, l11);
    STORE_4(dst + 12 * stride, stride, l12, l13, l14, l15);
}

#define inv_txfm_fn4x16(type1, type2) \
void dav1d_inv_txfm_add_##type1##_##type2##_4x16_8bpc_pwr9(uint8_t *dst, const ptrdiff_t stride, \
                                                          int16_t *const coeff, const int eob) \
{ \
    LOAD_COEFF_4x16(coeff) \
    type1##_4x4_in(cA0, cA1, cA2, cA3, cB0, cB1, cB2, cB3, \
                   cC0, cC1, cC2, cC3, cD0, cD1, cD2, cD3, \
                   a0b0, c0d0, a1b1, c1d1, a2b2, c2d2, a3b3, c3d3) \
    memset(coeff, 0, sizeof(*coeff) * 4 * 16); \
    SCALE_ROUND_4(cA0, cB0, cC0, cD0, vec_splat_s32(1), vec_splat_u32(1)) \
    SCALE_ROUND_4(cA1, cB1, cC1, cD1, vec_splat_s32(1), vec_splat_u32(1)) \
    SCALE_ROUND_4(cA2, cB2, cC2, cD2, vec_splat_s32(1), vec_splat_u32(1)) \
    SCALE_ROUND_4(cA3, cB3, cC3, cD3, vec_splat_s32(1), vec_splat_u32(1)) \
    TRANSPOSE4x16_I32(cA0, cA1, cA2, cA3, cB0, cB1, cB2, cB3, \
                      cC0, cC1, cC2, cC3, cD0, cD1, cD2, cD3) \
    type2##_16_out(cA0, cA1, cA2, cA3, cB0, cB1, cB2, cB3, \
                   cC0, cC1, cC2, cC3, cD0, cD1, cD2, cD3, \
                   a0b0, c0d0, a1b1, c1d1, a2b2, c2d2, a3b3, c3d3) \
    LOAD_DECLARE_4(dst, stride, l00, l01, l02, l03) \
    LOAD_DECLARE_4(dst + 4 * stride, stride, l04, l05, l06, l07) \
    LOAD_DECLARE_4(dst + 8 * stride, stride, l08, l09, l10, l11) \
    LOAD_DECLARE_4(dst + 12 * stride, stride, l12, l13, l14, l15) \
    APPLY_COEFF_4(l00, l01, l02, l03, a0b0, c0d0); \
    APPLY_COEFF_4(l04, l05, l06, l07, a1b1, c1d1); \
    APPLY_COEFF_4(l08, l09, l10, l11, a2b2, c2d2); \
    APPLY_COEFF_4(l12, l13, l14, l15, a3b3, c3d3); \
    STORE_4(dst, stride,               l00, l01, l02, l03); \
    STORE_4(dst + 4 * stride, stride,  l04, l05, l06, l07); \
    STORE_4(dst + 8 * stride, stride,  l08, l09, l10, l11); \
    STORE_4(dst + 12 * stride, stride, l12, l13, l14, l15); \
}
inv_txfm_fn4x16(adst,     dct     )
inv_txfm_fn4x16(dct,      adst    )
inv_txfm_fn4x16(dct,      flipadst)
inv_txfm_fn4x16(flipadst, dct     )
inv_txfm_fn4x16(adst,     flipadst)
inv_txfm_fn4x16(flipadst, adst    )
inv_txfm_fn4x16(identity, dct     )
inv_txfm_fn4x16(dct,      identity)
inv_txfm_fn4x16(identity, flipadst)
inv_txfm_fn4x16(flipadst, identity)
inv_txfm_fn4x16(identity, adst   )
inv_txfm_fn4x16(adst,     identity)
inv_txfm_fn4x16(identity, identity)
inv_txfm_fn4x16(adst,     adst    )
inv_txfm_fn4x16(flipadst, flipadst)

void dav1d_inv_txfm_add_dct_dct_16x4_8bpc_pwr9(uint8_t *dst, const ptrdiff_t stride,
                                               int16_t *const coeff, const int eob)
{

    if (eob < 1) {
        return dc_only_16xN(dst, stride, coeff, 1, 0, 1);
    }

    LOAD_DECLARE_2_I16(coeff, c00c01, c02c03) \
    LOAD_DECLARE_2_I16(coeff+16, c04c05, c06c07) \
    LOAD_DECLARE_2_I16(coeff+32, c08c09, c10c11) \
    LOAD_DECLARE_2_I16(coeff+48, c12c13, c14c15) \
    UNPACK_DECLARE_4_I16_I32(c00c01, c02c03, c00, c01, c02, c03)
    UNPACK_DECLARE_4_I16_I32(c04c05, c06c07, c04, c05, c06, c07)
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=99 H=99 G=98

¤ Dauer der Verarbeitung: 0.18 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge