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);
}