Rewrite of Daala tx SIMD using rotate and butterfly kernels Change-Id: I034558404d054b295908f7f45225facfb0cb15ee
diff --git a/av1/common/x86/daala_tx_kernels.h b/av1/common/x86/daala_tx_kernels.h index 90797b8..f7b51fc 100644 --- a/av1/common/x86/daala_tx_kernels.h +++ b/av1/common/x86/daala_tx_kernels.h
@@ -34,38 +34,165 @@ OD_KERNEL_FUNC_IMPL(name, kernel, word) #define OD_KERNEL_FUNC(name) OD_KERNEL_FUNC_WRAPPER(name, OD_KERNEL, OD_WORD) -static INLINE void OD_KERNEL_FUNC(od_idct2)(OD_REG *p0, OD_REG *p1) { - OD_REG t_; - t_ = OD_ADD(*p0, *p1); - /* 11585/8192 ~= 2*Sin[Pi/4] = 1.4142135623730951 */ - *p1 = OD_MUL(*p0, 11585, 13); - /* 11585/16384 ~= Cos[Pi/4] = 0.7071067811865475 */ - *p0 = OD_MUL(t_, 11585, 14); - *p1 = OD_SUB(*p1, *p0); -} - -static INLINE void OD_KERNEL_FUNC(od_idst2)(OD_REG *p0, OD_REG *p1) { +static INLINE void OD_KERNEL_FUNC(od_rotate_add)(OD_REG *q0, OD_REG *q1, int c0, + int r0, int c1, int r1, int c2, + int r2, int s) { OD_REG t_; OD_REG u_; - t_ = OD_AVG(*p0, *p1); + + t_ = OD_ADD(*q0, *q1); + u_ = OD_MUL(*q1, c0, r0); + *q1 = OD_MUL(*q0, c1, r1); + t_ = OD_MUL(t_, c2, r2); + if (s) + *q0 = OD_SUB(u_, OD_RSHIFT1(t_)); + else + *q0 = OD_SUB(u_, t_); + *q1 = OD_ADD(*q1, t_); +} + +static INLINE void OD_KERNEL_FUNC(od_rotate_addh)(OD_REG *q0, OD_REG *q1, + OD_REG *q1h, int c0, int r0, + int c1, int r1, int c2, + int r2, int s) { + OD_REG t_; + OD_REG u_; + + t_ = OD_ADD(*q0, *q1h); + u_ = OD_MUL(*q1, c0, r0); + *q1 = OD_MUL(*q0, c1, r1); + t_ = OD_MUL(t_, c2, r2); + *q0 = OD_SUB(u_, t_); + if (s) + *q1 = OD_ADD(*q1, OD_RSHIFT1(t_)); + else + *q1 = OD_ADD(*q1, t_); +} + +static INLINE void OD_KERNEL_FUNC(od_rotate_sub)(OD_REG *q0, OD_REG *q1, int c0, + int r0, int c1, int r1, int c2, + int r2, int s) { + OD_REG t_; + OD_REG u_; + + t_ = OD_SUB(*q0, *q1); + u_ = OD_MUL(*q1, c0, r0); + *q1 = OD_MUL(*q0, c1, r1); + t_ = OD_MUL(t_, c2, r2); + if (s) + *q0 = OD_ADD(u_, OD_RSHIFT1(t_)); + else + *q0 = OD_ADD(u_, t_); + *q1 = OD_ADD(*q1, t_); +} + +static INLINE void OD_KERNEL_FUNC(od_rotate_subh)(OD_REG *q0, OD_REG *q1, + OD_REG *q1h, int c0, int r0, + int c1, int r1, int c2, + int r2, int s) { + OD_REG t_; + OD_REG u_; + + t_ = OD_SUB(*q0, *q1h); + u_ = OD_MUL(*q1, c0, r0); + *q1 = OD_MUL(*q0, c1, r1); + t_ = OD_MUL(t_, c2, r2); + *q0 = OD_ADD(u_, t_); + if (s) + *q1 = OD_ADD(*q1, OD_RSHIFT1(t_)); + else + *q1 = OD_ADD(*q1, t_); +} + +static INLINE void OD_KERNEL_FUNC(od_rotate45)(OD_REG *p0, OD_REG *p1, + int avg) { + OD_REG t_; + if (avg) + t_ = OD_AVG(*p0, *p1); + else + t_ = OD_ADD(*p0, *p1); + /* 11585/8192 ~= 2*Sin[Pi/4] ~= 1.4142135623730951 */ + *p0 = OD_MUL(*p1, 11585, 13); + /* 11585/8192 ~= 2*Cos[Pi/4] ~= 1.4142135623730951 */ + if (avg) + *p1 = OD_MUL(t_, 11585, 13); + else + *p1 = OD_MUL(t_, 11585, 14); + *p0 = OD_SUB(*p0, *p1); +} + +static INLINE void OD_KERNEL_FUNC(od_butterfly_add)(OD_REG *q0, OD_REG *q1) { + *q0 = OD_ADD(*q0, OD_RSHIFT1(*q1)); + *q1 = OD_SUB(*q0, *q1); +} + +static INLINE void OD_KERNEL_FUNC(od_butterfly_addh)(OD_REG *q0, OD_REG *q1, + OD_REG *q1h) { + *q0 = OD_ADD(*q0, *q1h); + *q1 = OD_SUB(*q1, *q0); +} + +static INLINE void OD_KERNEL_FUNC(od_butterfly_subh)(OD_REG *q0, OD_REG *q1, + OD_REG *q1h) { + *q0 = OD_SUB(*q0, *q1h); + *q1 = OD_ADD(*q1, *q0); +} + +static INLINE void OD_KERNEL_FUNC(od_butterfly_v1)(OD_REG *q0, OD_REG *q1, + OD_REG *q1h) { + *q1 = OD_SUB(*q0, *q1); + *q1h = OD_RSHIFT1(*q1); + *q0 = OD_SUB(*q0, *q1h); +} + +static INLINE void OD_KERNEL_FUNC(od_butterfly_v2)(OD_REG *q0, OD_REG *q1, + OD_REG *q1h) { + *q1 = OD_SUB(*q1, *q0); + *q1h = OD_RSHIFT1(*q1); + *q0 = OD_ADD(*q0, *q1h); +} + +static INLINE void OD_KERNEL_FUNC(od_butterfly_v3)(OD_REG *q0, OD_REG *q1, + OD_REG *q1h) { + *q1 = OD_ADD(*q0, *q1); + *q1h = OD_RSHIFT1(*q1); + *q0 = OD_SUB(*q0, *q1h); +} + +static INLINE void OD_KERNEL_FUNC(od_idct2)(OD_REG *p0, OD_REG *p1) { + OD_KERNEL_FUNC(od_rotate45)(p1, p0, 0); +} + +static INLINE void OD_KERNEL_FUNC(od_idst2)(OD_REG *p0, OD_REG *p1, int neg) { + // Note: special case of rotation + OD_REG t_; + OD_REG u_; + if (neg) + t_ = OD_HRSUB(*p0, *p1); + else + t_ = OD_AVG(*p0, *p1); /* 21407/16384 ~= Sin[3*Pi/8] + Cos[3*Pi/8] ~= 1.3065629648763766 */ u_ = OD_MUL(*p0, 21407, 14); /* 8867/16384 ~= Sin[3*Pi/8] - Cos[3*Pi/8] ~= 0.541196100146197 */ *p0 = OD_MUL(*p1, 8867, 14); /* 3135/4096 ~= 2*Cos[3*Pi/8] ~= 0.7653668647301796 */ t_ = OD_MUL(t_, 3135, 12); - *p0 = OD_ADD(*p0, t_); - *p1 = OD_SUB(u_, t_); + if (neg) { + *p0 = OD_SUB(*p0, t_); + *p1 = OD_SUB(t_, u_); + } else { + *p0 = OD_ADD(*p0, t_); + *p1 = OD_SUB(u_, t_); + } } static INLINE void OD_KERNEL_FUNC(od_idct2_asym)(OD_REG *p0, OD_REG *p1, OD_REG *p1h) { - *p1 = OD_SUB(*p0, *p1); - *p1h = OD_RSHIFT1(*p1); - *p0 = OD_SUB(*p0, *p1h); + OD_KERNEL_FUNC(od_butterfly_v1)(p0, p1, p1h); } static INLINE void OD_KERNEL_FUNC(od_idst2_asym)(OD_REG *p0, OD_REG *p1) { + // Note: special case of rotation OD_REG t_; OD_REG u_; t_ = OD_AVG(*p0, *p1); @@ -84,27 +211,22 @@ OD_REG q1h; OD_KERNEL_FUNC(od_idst2_asym)(q3, q2); OD_KERNEL_FUNC(od_idct2_asym)(q0, q1, &q1h); - *q2 = OD_ADD(*q2, q1h); - *q1 = OD_SUB(*q1, *q2); - *q0 = OD_ADD(*q0, OD_RSHIFT1(*q3)); - *q3 = OD_SUB(*q0, *q3); + OD_KERNEL_FUNC(od_butterfly_addh)(q2, q1, &q1h); + OD_KERNEL_FUNC(od_butterfly_add)(q0, q3); } static INLINE void OD_KERNEL_FUNC(od_idct4_asym)(OD_REG *q0, OD_REG *q2, OD_REG *q1, OD_REG *q1h, OD_REG *q3, OD_REG *q3h) { - OD_KERNEL_FUNC(od_idst2)(q3, q2); + OD_KERNEL_FUNC(od_idst2)(q3, q2, 0); OD_KERNEL_FUNC(od_idct2)(q0, q1); - *q1 = OD_SUB(*q1, *q2); - *q1h = OD_RSHIFT1(*q1); - *q2 = OD_ADD(*q2, *q1h); - *q3 = OD_SUB(*q0, *q3); - *q3h = OD_RSHIFT1(*q3); - *q0 = OD_SUB(*q0, *q3h); + OD_KERNEL_FUNC(od_butterfly_v2)(q2, q1, q1h); + OD_KERNEL_FUNC(od_butterfly_v1)(q0, q3, q3h); } static INLINE void OD_KERNEL_FUNC(od_idst_vii4)(OD_REG *q0, OD_REG *q1, OD_REG *q2, OD_REG *q3) { + // Note: special case OD_REG t0; OD_REG t1; OD_REG t2; @@ -146,78 +268,40 @@ static INLINE void OD_KERNEL_FUNC(od_idst4)(OD_REG *q0, OD_REG *q1, OD_REG *q2, OD_REG *q3) { - OD_REG t_; - OD_REG u_; OD_REG q2h; OD_REG q3h; - t_ = OD_AVG(*q1, *q2); - /* 11585/8192 ~= 2*Sin[Pi/4] ~= 1.4142135623730951 */ - *q2 = OD_MUL(*q1, 11585, 13); - /* 11585/8192 ~= 2*Cos[Pi/4] ~= 1.4142135623730951 */ - *q1 = OD_MUL(t_, 11585, 13); - *q2 = OD_SUB(*q2, *q1); - *q2 = OD_ADD(*q2, *q0); - q2h = OD_RSHIFT1(*q2); - *q0 = OD_SUB(*q0, q2h); - *q3 = OD_ADD(*q3, *q1); - q3h = OD_RSHIFT1(*q3); - *q1 = OD_SUB(*q1, q3h); - t_ = OD_ADD(*q1, q2h); + OD_KERNEL_FUNC(od_rotate45)(q2, q1, 1); + OD_KERNEL_FUNC(od_butterfly_v3)(q0, q2, &q2h); + OD_KERNEL_FUNC(od_butterfly_v3)(q1, q3, &q3h); /* 16069/16384 ~= (Sin[5*Pi/16] + Cos[5*Pi/16])/Sqrt[2] ~= 0.9807852804032 */ - u_ = OD_MUL(*q2, 16069, 14); /* 12785/32768 ~= (Sin[5*Pi/16] - Cos[5*Pi/16])*Sqrt[2] ~= 0.3901806440323 */ - *q2 = OD_MUL(*q1, 12785, 15); /* 12873/16384 ~= Cos[5*Pi/16]*Sqrt[2] ~= 0.7856949583871021 */ - t_ = OD_MUL(t_, 12873, 14); - *q1 = OD_SUB(u_, t_); - *q2 = OD_ADD(*q2, t_); - t_ = OD_SUB(*q0, q3h); + OD_KERNEL_FUNC(od_rotate_addh) + (q1, q2, &q2h, 16069, 14, 12785, 15, 12873, 14, 0); /* 13623/16384 ~= (Sin[7*Pi/16] + Cos[7*Pi/16])/Sqrt[2] ~= 0.8314696123025 */ - u_ = OD_MUL(*q3, 13623, 14); /* 18205/16384 ~= (Sin[7*Pi/16] - Cos[7*Pi/16])*Sqrt[2] ~= 1.1111404660392 */ - *q3 = OD_MUL(*q0, 18205, 14); /* 9041/32768 ~= Cos[7*Pi/16]*Sqrt[2] = 0.275899379282943 */ - t_ = OD_MUL(t_, 9041, 15); - *q0 = OD_ADD(u_, t_); - *q3 = OD_ADD(*q3, t_); + OD_KERNEL_FUNC(od_rotate_subh) + (q0, q3, &q3h, 13623, 14, 18205, 14, 9041, 15, 0); } static INLINE void OD_KERNEL_FUNC(od_idst4_asym)(OD_REG *q0, OD_REG *q2, OD_REG *q1, OD_REG *q3) { - OD_REG t_; - OD_REG u_; OD_REG q1h; OD_REG q3h; - t_ = OD_AVG(*q1, *q2); - /* 11585/8192 ~= 2*Sin[Pi/4] ~= 1.4142135623730951 */ - *q1 = OD_MUL(*q2, 11585, 13); - /* 11585/8192 ~= 2*Cos[Pi/4] ~= 1.4142135623730951 */ - *q2 = OD_MUL(t_, 11585, 13); - *q1 = OD_SUB(*q1, *q2); - *q1 = OD_ADD(*q1, *q0); - q1h = OD_RSHIFT1(*q1); - *q0 = OD_SUB(*q0, q1h); - *q3 = OD_ADD(*q3, *q2); - q3h = OD_RSHIFT1(*q3); - *q2 = OD_SUB(*q2, q3h); - t_ = OD_ADD(q1h, *q2); + OD_KERNEL_FUNC(od_rotate45)(q1, q2, 1); + OD_KERNEL_FUNC(od_butterfly_v3)(q0, q1, &q1h); + OD_KERNEL_FUNC(od_butterfly_v3)(q2, q3, &q3h); /* 45451/32768 ~= Sin[5*Pi/16] + Cos[5*Pi/16] ~= 1.3870398453221475 */ - u_ = OD_MUL(*q1, 45451, 15); /* 9041/32768 ~= Sin[5*Pi/16] - Cos[5*Pi/16] ~= 0.27589937928294306 */ - *q1 = OD_MUL(*q2, 9041, 15); /* 18205/16384 ~= 2*Cos[5*Pi/16] ~= 1.1111404660392044 */ - t_ = OD_MUL(t_, 18205, 14); - *q1 = OD_ADD(*q1, OD_RSHIFT1(t_)); - *q2 = OD_SUB(u_, t_); - t_ = OD_SUB(*q0, q3h); + OD_KERNEL_FUNC(od_rotate_addh) + (q2, q1, &q1h, 45451, 15, 9041, 15, 18205, 14, 1); /* 38531/32768 ~= Sin[7*Pi/16] + Cos[7*Pi/16] = 1.1758756024193586 */ - u_ = OD_MUL(*q3, 38531, 15); /* 12873/16384 ~= Sin[7*Pi/16] - Cos[7*Pi/16] = 0.7856949583871022 */ - *q3 = OD_MUL(*q0, 12873, 14); /* 12785/32768 ~= 2*Cos[7*Pi/16] = 0.3901806440322565 */ - t_ = OD_MUL(t_, 12785, 15); - *q3 = OD_ADD(*q3, OD_RSHIFT1(t_)); - *q0 = OD_ADD(u_, t_); + OD_KERNEL_FUNC(od_rotate_subh) + (q0, q3, &q3h, 38531, 15, 12873, 14, 12785, 15, 1); } static INLINE void OD_KERNEL_FUNC(od_idct8)(OD_REG *r0, OD_REG *r4, OD_REG *r2, @@ -227,14 +311,10 @@ OD_REG r3h; OD_KERNEL_FUNC(od_idst4_asym)(r7, r5, r6, r4); OD_KERNEL_FUNC(od_idct4_asym)(r0, r2, r1, &r1h, r3, &r3h); - *r4 = OD_ADD(*r4, r3h); - *r3 = OD_SUB(*r3, *r4); - *r2 = OD_ADD(*r2, OD_RSHIFT1(*r5)); - *r5 = OD_SUB(*r2, *r5); - *r6 = OD_ADD(*r6, r1h); - *r1 = OD_SUB(*r1, *r6); - *r0 = OD_ADD(*r0, OD_RSHIFT1(*r7)); - *r7 = OD_SUB(*r0, *r7); + OD_KERNEL_FUNC(od_butterfly_addh)(r4, r3, &r3h); + OD_KERNEL_FUNC(od_butterfly_add)(r2, r5); + OD_KERNEL_FUNC(od_butterfly_addh)(r6, r1, &r1h); + OD_KERNEL_FUNC(od_butterfly_add)(r0, r7); } static INLINE void OD_KERNEL_FUNC(od_idct8_asym)( @@ -242,201 +322,83 @@ OD_REG *r5, OD_REG *r5h, OD_REG *r3, OD_REG *r3h, OD_REG *r7, OD_REG *r7h) { OD_KERNEL_FUNC(od_idst4)(r7, r5, r6, r4); OD_KERNEL_FUNC(od_idct4)(r0, r2, r1, r3); - *r7 = OD_SUB(*r0, *r7); - *r7h = OD_RSHIFT1(*r7); - *r0 = OD_SUB(*r0, *r7h); - *r1 = OD_SUB(*r1, *r6); - *r1h = OD_RSHIFT1(*r1); - *r6 = OD_ADD(*r6, *r1h); - *r5 = OD_SUB(*r2, *r5); - *r5h = OD_RSHIFT1(*r5); - *r2 = OD_SUB(*r2, *r5h); - *r3 = OD_SUB(*r3, *r4); - *r3h = OD_RSHIFT1(*r3); - *r4 = OD_ADD(*r4, *r3h); + OD_KERNEL_FUNC(od_butterfly_v1)(r0, r7, r7h); + OD_KERNEL_FUNC(od_butterfly_v2)(r6, r1, r1h); + OD_KERNEL_FUNC(od_butterfly_v1)(r2, r5, r5h); + OD_KERNEL_FUNC(od_butterfly_v2)(r4, r3, r3h); } static INLINE void OD_KERNEL_FUNC(od_idst8)(OD_REG *r0, OD_REG *r4, OD_REG *r2, OD_REG *r6, OD_REG *r1, OD_REG *r5, OD_REG *r3, OD_REG *r7) { - OD_REG t_; - OD_REG u_; OD_REG r0h; OD_REG r2h; OD_REG r5h; OD_REG r7h; - t_ = OD_AVG(*r1, *r6); - /* 11585/8192 ~= 2*Sin[Pi/4] ~= 1.4142135623730951 */ - *r1 = OD_MUL(*r6, 11585, 13); - /* 11585/8192 ~= 2*Cos[Pi/4] ~= 1.4142135623730951 */ - *r6 = OD_MUL(t_, 11585, 13); - *r1 = OD_SUB(*r1, *r6); - t_ = OD_HRSUB(*r5, *r2); - /* 21407/16384 ~= Sin[3*Pi/8] + Cos[3*Pi/8] ~= 1.3065629648763766 */ - u_ = OD_MUL(*r5, 21407, 14); - /* 8867/16384 ~= Sin[3*Pi/8] - Cos[3*Pi/8] ~= 0.5411961001461969 */ - *r5 = OD_MUL(*r2, 8867, 14); - /* 3135/4096 ~= 2*Cos[3*Pi/8] ~= 0.7653668647301796 */ - t_ = OD_MUL(t_, 3135, 12); - *r5 = OD_SUB(*r5, t_); - *r2 = OD_SUB(t_, u_); - t_ = OD_AVG(*r3, *r4); - /* 21407/16384 ~= Sin[3*Pi/8] + Cos[3*Pi/8] ~= 1.3065629648763766 */ - u_ = OD_MUL(*r4, 21407, 14); - /* 8867/16384 ~= Sin[3*Pi/8] - Cos[3*Pi/8] ~= 0.5411961001461969 */ - *r4 = OD_MUL(*r3, 8867, 14); - /* 3135/4096 ~= 2*Cos[3*Pi/8] ~= 0.7653668647301796 */ - t_ = OD_MUL(t_, 3135, 12); - *r3 = OD_SUB(u_, t_); - *r4 = OD_ADD(*r4, t_); - *r7 = OD_ADD(*r7, *r6); - r7h = OD_RSHIFT1(*r7); - *r6 = OD_SUB(*r6, r7h); - *r2 = OD_ADD(*r2, *r4); - r2h = OD_RSHIFT1(*r2); - *r4 = OD_SUB(*r4, r2h); - *r0 = OD_SUB(*r0, *r1); - r0h = OD_RSHIFT1(*r0); - *r1 = OD_ADD(*r1, r0h); - *r5 = OD_ADD(*r5, *r3); - r5h = OD_RSHIFT1(*r5); - *r3 = OD_SUB(*r3, r5h); - *r4 = OD_SUB(*r4, r7h); - *r7 = OD_ADD(*r7, *r4); - *r6 = OD_ADD(*r6, r5h); - *r5 = OD_SUB(*r5, *r6); - *r3 = OD_ADD(*r3, r0h); - *r0 = OD_SUB(*r0, *r3); - *r1 = OD_SUB(*r1, r2h); - *r2 = OD_ADD(*r2, *r1); - t_ = OD_ADD(*r0, *r7); + OD_KERNEL_FUNC(od_rotate45)(r1, r6, 1); + OD_KERNEL_FUNC(od_idst2)(r5, r2, 1); + OD_KERNEL_FUNC(od_idst2)(r4, r3, 0); + OD_KERNEL_FUNC(od_butterfly_v3)(r6, r7, &r7h); + OD_KERNEL_FUNC(od_butterfly_v3)(r4, r2, &r2h); + OD_KERNEL_FUNC(od_butterfly_v2)(r1, r0, &r0h); + OD_KERNEL_FUNC(od_butterfly_v3)(r3, r5, &r5h); + OD_KERNEL_FUNC(od_butterfly_subh)(r4, r7, &r7h); + OD_KERNEL_FUNC(od_butterfly_addh)(r6, r5, &r5h); + OD_KERNEL_FUNC(od_butterfly_addh)(r3, r0, &r0h); + OD_KERNEL_FUNC(od_butterfly_subh)(r1, r2, &r2h); /* 17911/16384 ~= Sin[15*Pi/32] + Cos[15*Pi/32] ~= 1.0932018670017576 */ - u_ = OD_MUL(*r0, 17911, 14); /* 14699/16384 ~= Sin[15*Pi/32] - Cos[15*Pi/32] ~= 0.8971675863426363 */ - *r0 = OD_MUL(*r7, 14699, 14); /* 803/8192 ~= Cos[15*Pi/32] ~= 0.0980171403295606 */ - t_ = OD_MUL(t_, 803, 13); - *r7 = OD_SUB(u_, t_); - *r0 = OD_ADD(*r0, t_); - t_ = OD_SUB(*r1, *r6); + OD_KERNEL_FUNC(od_rotate_add)(r7, r0, 17911, 14, 14699, 14, 803, 13, 0); /* 40869/32768 ~= Sin[13*Pi/32] + Cos[13*Pi/32] ~= 1.247225012986671 */ - u_ = OD_MUL(*r6, 40869, 15); /* 21845/32768 ~= Sin[13*Pi/32] - Cos[13*Pi/32] ~= 0.6666556584777465 */ - *r6 = OD_MUL(*r1, 21845, 15); /* 1189/4096 ~= Cos[13*Pi/32] ~= 0.29028467725446233 */ - t_ = OD_MUL(t_, 1189, 12); - *r1 = OD_ADD(u_, t_); - *r6 = OD_ADD(*r6, t_); - t_ = OD_ADD(*r2, *r5); + OD_KERNEL_FUNC(od_rotate_sub)(r1, r6, 40869, 15, 21845, 15, 1189, 12, 0); /* 22173/16384 ~= Sin[11*Pi/32] + Cos[11*Pi/32] ~= 1.3533180011743526 */ - u_ = OD_MUL(*r2, 22173, 14); /* 3363/8192 ~= Sin[11*Pi/32] - Cos[11*Pi/32] ~= 0.4105245275223574 */ - *r2 = OD_MUL(*r5, 3363, 13); /* 15447/32768 ~= Cos[11*Pi/32] ~= 0.47139673682599764 */ - t_ = OD_MUL(t_, 15447, 15); - *r5 = OD_SUB(u_, t_); - *r2 = OD_ADD(*r2, t_); - t_ = OD_SUB(*r3, *r4); + OD_KERNEL_FUNC(od_rotate_add)(r5, r2, 22173, 14, 3363, 13, 15447, 15, 0); /* 23059/16384 ~= Sin[9*Pi/32] + Cos[9*Pi/32] ~= 1.4074037375263826 */ - u_ = OD_MUL(*r4, 23059, 14); /* 2271/16384 ~= Sin[9*Pi/32] - Cos[9*Pi/32] ~= 0.1386171691990915 */ - *r4 = OD_MUL(*r3, 2271, 14); /* 5197/8192 ~= Cos[9*Pi/32] ~= 0.6343932841636455 */ - t_ = OD_MUL(t_, 5197, 13); - *r3 = OD_ADD(u_, t_); - *r4 = OD_ADD(*r4, t_); + OD_KERNEL_FUNC(od_rotate_sub)(r3, r4, 23059, 14, 2271, 14, 5197, 13, 0); } static INLINE void OD_KERNEL_FUNC(od_idst8_asym)(OD_REG *r0, OD_REG *r4, OD_REG *r2, OD_REG *r6, OD_REG *r1, OD_REG *r5, OD_REG *r3, OD_REG *r7) { - OD_REG t_; - OD_REG u_; OD_REG r0h; OD_REG r2h; OD_REG r5h; OD_REG r7h; - t_ = OD_AVG(*r1, *r6); - /* 11585/8192 ~= 2*Sin[Pi/4] ~= 1.4142135623730951 */ - *r1 = OD_MUL(*r6, 11585, 13); - /* 11585/8192 ~= 2*Cos[Pi/4] ~= 1.4142135623730951 */ - *r6 = OD_MUL(t_, 11585, 13); - *r1 = OD_SUB(*r1, *r6); - t_ = OD_HRSUB(*r5, *r2); - /* 21407/16384 ~= Sin[3*Pi/8] + Cos[3*Pi/8] ~= 1.3065629648763766 */ - u_ = OD_MUL(*r5, 21407, 14); - /* 8867/16384 ~= Sin[3*Pi/8] - Cos[3*Pi/8] ~= 0.5411961001461969 */ - *r5 = OD_MUL(*r2, 8867, 14); - /* 3135/4096 ~= 2*Cos[3*Pi/8] ~= 0.7653668647301796 */ - t_ = OD_MUL(t_, 3135, 12); - *r5 = OD_SUB(*r5, t_); - *r2 = OD_SUB(t_, u_); - t_ = OD_AVG(*r3, *r4); - /* 21407/16384 ~= Sin[3*Pi/8] + Cos[3*Pi/8] ~= 1.3065629648763766 */ - u_ = OD_MUL(*r4, 21407, 14); - /* 8867/16384 ~= Sin[3*Pi/8] - Cos[3*Pi/8] ~= 0.5411961001461969 */ - *r4 = OD_MUL(*r3, 8867, 14); - /* 3135/4096 ~= 2*Cos[3*Pi/8] ~= 0.7653668647301796 */ - t_ = OD_MUL(t_, 3135, 12); - *r3 = OD_SUB(u_, t_); - *r4 = OD_ADD(*r4, t_); - *r7 = OD_ADD(*r7, *r6); - r7h = OD_RSHIFT1(*r7); - *r6 = OD_SUB(*r6, r7h); - *r2 = OD_ADD(*r2, *r4); - r2h = OD_RSHIFT1(*r2); - *r4 = OD_SUB(*r4, r2h); - *r0 = OD_SUB(*r0, *r1); - r0h = OD_RSHIFT1(*r0); - *r1 = OD_ADD(*r1, r0h); - *r5 = OD_ADD(*r5, *r3); - r5h = OD_RSHIFT1(*r5); - *r3 = OD_SUB(*r3, r5h); - *r4 = OD_SUB(*r4, r7h); - *r7 = OD_ADD(*r7, *r4); - *r6 = OD_ADD(*r6, r5h); - *r5 = OD_SUB(*r5, *r6); - *r3 = OD_ADD(*r3, r0h); - *r0 = OD_SUB(*r0, *r3); - *r1 = OD_SUB(*r1, r2h); - *r2 = OD_ADD(*r2, *r1); - t_ = OD_ADD(*r0, *r7); + OD_KERNEL_FUNC(od_rotate45)(r1, r6, 1); + OD_KERNEL_FUNC(od_idst2)(r5, r2, 1); + OD_KERNEL_FUNC(od_idst2)(r4, r3, 0); + OD_KERNEL_FUNC(od_butterfly_v3)(r6, r7, &r7h); + OD_KERNEL_FUNC(od_butterfly_v3)(r4, r2, &r2h); + OD_KERNEL_FUNC(od_butterfly_v2)(r1, r0, &r0h); + OD_KERNEL_FUNC(od_butterfly_v3)(r3, r5, &r5h); + OD_KERNEL_FUNC(od_butterfly_subh)(r4, r7, &r7h); + OD_KERNEL_FUNC(od_butterfly_addh)(r6, r5, &r5h); + OD_KERNEL_FUNC(od_butterfly_addh)(r3, r0, &r0h); + OD_KERNEL_FUNC(od_butterfly_subh)(r1, r2, &r2h); /* 12665/16384 ~= (Sin[15*Pi/32] + Cos[15*Pi/32])/Sqrt[2] ~= 0.77301045336 */ - u_ = OD_MUL(*r0, 12665, 14); /* 5197/4096 ~= (Sin[15*Pi/32] - Cos[15*Pi/32])*Sqrt[2] ~= 1.2687865683273 */ - *r0 = OD_MUL(*r7, 5197, 12); /* 2271/16384 ~= Cos[15*Pi/32]*Sqrt[2] ~= 0.13861716919909148 */ - t_ = OD_MUL(t_, 2271, 14); - *r7 = OD_SUB(u_, OD_RSHIFT1(t_)); - *r0 = OD_ADD(*r0, t_); - t_ = OD_SUB(*r1, *r6); + OD_KERNEL_FUNC(od_rotate_add)(r7, r0, 12665, 14, 5197, 12, 2271, 14, 1); /* 28899/32768 ~= (Sin[13*Pi/32] + Cos[13*Pi/32])/Sqrt[2] ~= 0.88192126435 */ - u_ = OD_MUL(*r6, 28899, 15); /* 30893/32768 ~= (Sin[13*Pi/32] - Cos[13*Pi/32])*Sqrt[2] ~= 0.94279347365 */ - *r6 = OD_MUL(*r1, 30893, 15); /* 3363/8192 ~= Cos[13*Pi/32]*Sqrt[2] ~= 0.41052452752235735 */ - t_ = OD_MUL(t_, 3363, 13); - *r1 = OD_ADD(u_, OD_RSHIFT1(t_)); - *r6 = OD_ADD(*r6, t_); - t_ = OD_ADD(*r2, *r5); + OD_KERNEL_FUNC(od_rotate_sub)(r1, r6, 28899, 15, 30893, 15, 3363, 13, 1); /* 31357/32768 ~= (Sin[11*Pi/32] + Cos[11*Pi/32])/Sqrt[2] ~= 0.95694033573 */ - u_ = OD_MUL(*r2, 31357, 15); /* 1189/2048 ~= (Sin[11*Pi/32] - Cos[11*Pi/32])*Sqrt[2] ~= 0.5805693545089 */ - *r2 = OD_MUL(*r5, 1189, 11); /* 21845/32768 ~= Cos[11*Pi/32] ~= 0.6666556584777465 */ - t_ = OD_MUL(t_, 21845, 15); - *r5 = OD_SUB(u_, OD_RSHIFT1(t_)); - *r2 = OD_ADD(*r2, t_); - t_ = OD_SUB(*r3, *r4); + OD_KERNEL_FUNC(od_rotate_add)(r5, r2, 31357, 15, 1189, 11, 21845, 15, 1); /* 16305/16384 ~= (Sin[9*Pi/32] + Cos[9*Pi/32])/Sqrt[2] ~= 0.9951847266722 */ - u_ = OD_MUL(*r4, 16305, 14); /* 803/4096 ~= (Sin[9*Pi/32] - Cos[9*Pi/32])*Sqrt[2] ~= 0.1960342806591213 */ - *r4 = OD_MUL(*r3, 803, 12); /* 14699/16384 ~= Cos[9*Pi/32]*Sqrt[2] ~= 0.8971675863426364 */ - t_ = OD_MUL(t_, 14699, 14); - *r3 = OD_ADD(u_, OD_RSHIFT1(t_)); - *r4 = OD_ADD(*r4, t_); + OD_KERNEL_FUNC(od_rotate_sub)(r3, r4, 16305, 14, 803, 12, 14699, 14, 1); } static INLINE void OD_KERNEL_FUNC(od_flip_idst8)(OD_REG *r0, OD_REG *r4, @@ -463,20 +425,12 @@ OD_KERNEL_FUNC(od_idst8_asym)(sf, sb, sd, s9, se, sa, sc, s8); OD_KERNEL_FUNC(od_idct8_asym) (s0, s4, s2, s6, s1, &s1h, s5, &s5h, s3, &s3h, s7, &s7h); - *s8 = OD_ADD(*s8, s7h); - *s7 = OD_SUB(*s7, *s8); - *s6 = OD_ADD(*s6, OD_RSHIFT1(*s9)); - *s9 = OD_SUB(*s6, *s9); - *sa = OD_ADD(*sa, s5h); - *s5 = OD_SUB(*s5, *sa); - *s4 = OD_ADD(*s4, OD_RSHIFT1(*sb)); - *sb = OD_SUB(*s4, *sb); - *sc = OD_ADD(*sc, s3h); - *s3 = OD_SUB(*s3, *sc); - *s2 = OD_ADD(*s2, OD_RSHIFT1(*sd)); - *sd = OD_SUB(*s2, *sd); - *se = OD_ADD(*se, s1h); - *s1 = OD_SUB(*s1, *se); - *s0 = OD_ADD(*s0, OD_RSHIFT1(*sf)); - *sf = OD_SUB(*s0, *sf); + OD_KERNEL_FUNC(od_butterfly_addh)(s8, s7, &s7h); + OD_KERNEL_FUNC(od_butterfly_add)(s6, s9); + OD_KERNEL_FUNC(od_butterfly_addh)(sa, s5, &s5h); + OD_KERNEL_FUNC(od_butterfly_add)(s4, sb); + OD_KERNEL_FUNC(od_butterfly_addh)(sc, s3, &s3h); + OD_KERNEL_FUNC(od_butterfly_add)(s2, sd); + OD_KERNEL_FUNC(od_butterfly_addh)(se, s1, &s1h); + OD_KERNEL_FUNC(od_butterfly_add)(s0, sf); }