integrate M-HT's neon scalers
[gpsp.git] / arm / neon_eagle2x.Sinc
diff --git a/arm/neon_eagle2x.Sinc b/arm/neon_eagle2x.Sinc
new file mode 100644 (file)
index 0000000..7413312
--- /dev/null
@@ -0,0 +1,761 @@
+@@\r
+@@  Copyright (C) 2012 Roman Pauer\r
+@@\r
+@@  Permission is hereby granted, free of charge, to any person obtaining a copy of\r
+@@  this software and associated documentation files (the "Software"), to deal in\r
+@@  the Software without restriction, including without limitation the rights to\r
+@@  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\r
+@@  of the Software, and to permit persons to whom the Software is furnished to do\r
+@@  so, subject to the following conditions:\r
+@@\r
+@@  The above copyright notice and this permission notice shall be included in all\r
+@@  copies or substantial portions of the Software.\r
+@@\r
+@@  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+@@  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+@@  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+@@  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+@@  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+@@  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+@@  SOFTWARE.\r
+@@\r
+\r
+\r
+@ S T U  --\ E1 E2\r
+@ V C W  --/ E3 E4\r
+@ X Y Z\r
+\r
+@ q0  = S1sl    < S >\r
+@ q1  = S2sl    < V >\r
+@ q2  = S3sl    < X >\r
+@ q3  = S1sr    < U >\r
+@ q4  = S2sr    < W >\r
+@ q5  = S3sr    < Z >\r
+@ q6  = E3\r
+@ q7  = E4\r
+@ q8  = S1\r
+@ q9  = S2\r
+@ q10 = S3\r
+@ q11 = S1prev  < T >\r
+@ q12 = S2prev  < C >\r
+@ q13 = S3prev  < Y >\r
+@ q14 = E1\r
+@ q15 = E2\r
+\r
+\r
+.macro __neon_eagle2x_8_8_line src1, src2, src3, counter, dst1, dst2, reg1, qT, qY, alsrc1, alsrc2, alsrc3, aldst1, aldst2\r
+\r
+    .ifeqs "\qT", "q11"\r
+        vld1.8 {d23[7]}, [\src1]        @ S1prev[15] = src[-srcstride]\r
+    .endif\r
+        vld1.8 {d25[7]}, [\src2]        @ S2prev[15] = src[0]\r
+    .ifeqs "\qY", "q13"\r
+        vld1.8 {d27[7]}, [\src3]        @ S3prev[15] = src[srcstride]\r
+    .endif\r
+        andS \reg1, \counter, #15       @ reg1 = counter & 15\r
+\r
+    .ifnes "\qT", "q11"\r
+        add \src1, \src1, \counter      @ src1 += counter\r
+    .endif\r
+    .ifnes "\qY", "q13"\r
+        add \src3, \src3, \counter      @ src3 += counter\r
+    .endif\r
+        beq 1f\r
+\r
+    @ first 1-15 pixels - align counter to 16 bytes\r
+\r
+@ q0  = S1sl    < S >\r
+@ q2  = S3sl    < X >\r
+@ q7  = tmp2\r
+@ q15 = tmp1\r
+\r
+    .ifeqs "\qT", "q11"\r
+        vld1.8 {q8}, [\src1], \reg1     @ S1 = [src - srcstride]; src1 += counter & 15\r
+    .endif\r
+\r
+        vld1.8 {q9}, [\src2], \reg1     @ S2 = [src            ]; src2 += counter & 15\r
+\r
+    .ifeqs "\qY", "q13"\r
+        vld1.8 {q10}, [\src3], \reg1    @ S3 = [src + srcstride]; src3 += counter & 15\r
+    .endif\r
+    .ifeqs "\qT", "q11"\r
+        vext.8 q0, \qT, q8, #15         @ S1sl = S1prev[15] | (S1 << 8)     < S >\r
+\r
+        vmov \qT, q8                    @ S1prev = S1       < T >\r
+    .endif\r
+        vext.8 q1, q12, q9, #15         @ S2sl = S2prev[15] | (S2 << 8)     < V >\r
+\r
+        vmov q12, q9                    @ S2prev = S2       < C >\r
+    .ifeqs "\qY", "q13"\r
+        vext.8 q2, \qY, q10, #15        @ S3sl = S3prev[15] | (S3 << 8)     < X >\r
+\r
+        vmov \qY, q10                   @ S3prev = S3       < Y >\r
+    .endif\r
+    .ifeqs "\qT", "q11"\r
+        vext.8 q3, \qT, q8, #1          @ S1sr = (S1prev >> 8) | ...        < U >\r
+    .endif\r
+\r
+        vext.8 q4, q12, q9, #1          @ S2sr = (S2prev >> 8) | ...        < W >\r
+\r
+    .ifeqs "\qY", "q13"\r
+        vext.8 q5, \qY, q10, #1         @ S3sr = (S3prev >> 8) | ...        < Z >\r
+    .else\r
+        vmov q2, q1                     @ S3sl = S2sl       < X >\r
+\r
+        vmov q5, q4                     @ S3sr = S2sr       < Z >\r
+    .endif\r
+\r
+    .ifnes "\qT", "q11"\r
+        vmov q0, q1                     @ S1sl = S2sl       < S >\r
+\r
+        vmov q3, q4                     @ S1sr = S2sr       < U >\r
+    .endif\r
+\r
+        vceq.i8 q14, q0, \qT            @ E1 = < S == T >\r
+\r
+        vceq.i8 q15, q0, q1             @ tmp1 = < S == V >\r
+\r
+        vceq.i8 q6, q2, \qY             @ E3 = < X == Y >\r
+\r
+        vceq.i8 q7, q2, q1              @ tmp2 = < X == V >\r
+\r
+        vand q14, q14, q15              @ E1 = < S == T && S == V >\r
+\r
+@ q0 = tmp3\r
+@ q15 = E2\r
+\r
+        vceq.i8 q15, q3, \qT            @ E2 = < U == T >\r
+\r
+        vceq.i8 q0, q3, q4              @ tmp3 = < U == W >\r
+\r
+        vand q6, q6, q7                 @ E3 = < X == Y && X == V >\r
+\r
+@ q2 = tmp4\r
+@ q7 = E4\r
+        vceq.i8 q7, q5, \qY             @ E4 = < Z == Y >\r
+\r
+        vceq.i8 q2, q5, q4              @ tmp4 = < Z == W >\r
+\r
+        vand q15, q15, q0               @ E2 = < U == T && U == W >\r
+\r
+        vbsl q14, \qT, q12              @ E1 = < (S == T && S == V) ? T : C >\r
+\r
+        vbsl q15, \qT, q12              @ E2 = < (U == T && U == W) ? T : C >\r
+\r
+        vand q7, q7, q2                 @ E4 = < Z == Y && Z == W >\r
+\r
+        vbsl q6, \qY, q12               @ E3 = < (X == Y && X == V) ? Y : C >\r
+\r
+    .ifeqs "\qT", "q11"\r
+        sub \reg1, \src1, #1\r
+    .else\r
+        sub \reg1, \src2, #1\r
+    .endif\r
+\r
+        vbsl q7, \qY, q12               @ E4 = < (Z == Y && Z == W) ? Y : C >\r
+    .ifeqs "\qT", "q11"\r
+        vld1.8 {d23[7]}, [\reg1]        @ S1prev[15] = src[counter & 15 - 1 - srcstride]\r
+\r
+        sub \reg1, \src2, #1\r
+    .endif\r
+\r
+        vld1.8 {d25[7]}, [\reg1]        @ S2prev[15] = src[counter & 15 - 1]\r
+\r
+    .ifeqs "\qY", "q13"\r
+        sub \reg1, \src3, #1\r
+\r
+        vld1.8 {d27[7]}, [\reg1]        @ S3prev[15] = src[counter & 15 - 1 + srcstride]\r
+    .endif\r
+\r
+        ubfx \reg1, \counter, #0, #4    @ reg1 = counter & 15\r
+\r
+        lsl \reg1, #1\r
+\r
+        vst2.8 {q14-q15}, [\dst1],\reg1 @ [dst] = E1,E2; dst1 += reg1\r
+\r
+        bic \counter, \counter, #15\r
+\r
+        vst2.8 {q6-q7}, [\dst2], \reg1  @ [dst + dststride] = E3,E4; dst2 += reg1\r
+\r
+    @ counter is aligned to 16 bytes\r
+\r
+    1:\r
+    .ifeqs "\qT", "q11"\r
+        vld1.8 {q8}, [\alsrc1]!         @ S1 = [src - srcstride]; src1 += 16\r
+    .endif\r
+        vld1.8 {q9}, [\alsrc2]!         @ S2 = [src            ]; src2 += 16\r
+    .ifeqs "\qY", "q13"\r
+        vld1.8 {q10}, [\alsrc3]!        @ S3 = [src + srcstride]; src3 += 16\r
+    .endif\r
+\r
+    @ inner loop (16 pixels per iteration)\r
+    2:\r
+\r
+@ q0  = S1sl    < S >\r
+@ q2  = S3sl    < X >\r
+@ q7  = tmp2\r
+@ q15 = tmp1\r
+\r
+    .ifeqs "\qT", "q11"\r
+        vext.8 q0, \qT, q8, #15         @ S1sl = S1prev[15] | (S1 << 8)     < S >\r
+        vmov \qT, q8                    @ S1prev = S1       < T >\r
+    .endif\r
+\r
+        vext.8 q1, q12, q9, #15         @ S2sl = S2prev[15] | (S2 << 8)     < V >\r
+        vmov q12, q9                    @ S2prev = S2       < C >\r
+\r
+    .ifeqs "\qY", "q13"\r
+        vext.8 q2, \qY, q10, #15        @ S3sl = S3prev[15] | (S3 << 8)     < X >\r
+        vmov \qY, q10                   @ S3prev = S3       < Y >\r
+    .endif\r
+\r
+    .ifeqs "\qT", "q11"\r
+        vld1.8 {q8}, [\alsrc1]!         @ S1 = [src - srcstride]; src1 += 16\r
+        vext.8 q3, \qT, q8, #1          @ S1sr = (S1prev >> 8) | S1[0]      < U >\r
+    .endif\r
+\r
+        vld1.8 {q9}, [\alsrc2]!         @ S2 = [src            ]; src2 += 16\r
+        vext.8 q4, q12, q9, #1          @ S2sr = (S2prev >> 8) | S2[0]      < W >\r
+\r
+    .ifeqs "\qY", "q13"\r
+        vld1.8 {q10}, [\alsrc3]!        @ S3 = [src + srcstride]; src3 += 16\r
+        vext.8 q5, \qY, q10, #1         @ S3sr = (S3prev >> 8) | S3[0]      < Z >\r
+    .else\r
+        vmov q2, q1                     @ S3sl = S2sl       < X >\r
+\r
+        vmov q5, q4                     @ S3sr = S2sr       < Z >\r
+    .endif\r
+\r
+    .ifnes "\qT", "q11"\r
+        vmov q0, q1                     @ S1sl = S2sl       < S >\r
+\r
+        vmov q3, q4                     @ S1sr = S2sr       < U >\r
+    .endif\r
+\r
+        sub \counter, \counter, #16     @ counter -= 16\r
+        vceq.i8 q14, q0, \qT            @ E1 = < S == T >\r
+\r
+        vceq.i8 q15, q0, q1             @ tmp1 = < S == V >\r
+\r
+        vceq.i8 q6, q2, \qY             @ E3 = < X == Y >\r
+\r
+        vceq.i8 q7, q2, q1              @ tmp2 = < X == V >\r
+\r
+        vand q14, q14, q15              @ E1 = < S == T && S == V >\r
+\r
+@ q0 = tmp3\r
+@ q15 = E2\r
+\r
+        vceq.i8 q15, q3, \qT            @ E2 = < U == T >\r
+\r
+        vceq.i8 q0, q3, q4              @ tmp3 = < U == W >\r
+\r
+        vand q6, q6, q7                 @ E3 = < X == Y && X == V >\r
+\r
+@ q2 = tmp4\r
+@ q7 = E4\r
+        vceq.i8 q7, q5, \qY             @ E4 = < Z == Y >\r
+\r
+        vceq.i8 q2, q5, q4              @ tmp4 = < Z == W >\r
+\r
+        vand q15, q15, q0               @ E2 = < U == T && U == W >\r
+\r
+        vbsl q14, \qT, q12              @ E1 = < (S == T && S == V) ? T : C >\r
+\r
+        vbsl q15, \qT, q12              @ E2 = < (U == T && U == W) ? T : C >\r
+\r
+        vand q7, q7, q2                 @ E4 = < Z == Y && Z == W >\r
+\r
+        vbsl q6, \qY, q12               @ E3 = < (X == Y && X == V) ? Y : C >\r
+\r
+        vbsl q7, \qY, q12               @ E4 = < (Z == Y && Z == W) ? Y : C >\r
+        vst2.8 {q14-q15}, [\aldst1]!    @ [dst] = E1,E2; dst1 += 2*16\r
+\r
+        cmp \counter, #16\r
+\r
+        vst2.8 {q6-q7}, [\aldst2]!      @ [dst + dststride] = E3,E4; dst2 += 2*16\r
+        bhi 2b\r
+\r
+    @ last 16 pixels\r
+\r
+@ q0  = S1sl    < S >\r
+@ q2  = S3sl    < X >\r
+@ q7  = tmp2\r
+@ q15 = tmp1\r
+\r
+    .ifeqs "\qT", "q11"\r
+        vext.8 q0, \qT, q8, #15         @ S1sl = S1prev[15] | (S1 << 8)     < S >\r
+        vmov \qT, q8                    @ S1prev = S1       < T >\r
+    .endif\r
+\r
+        vext.8 q1, q12, q9, #15         @ S2sl = S2prev[15] | (S2 << 8)     < V >\r
+        vmov q12, q9                    @ S2prev = S2       < C >\r
+\r
+    .ifeqs "\qY", "q13"\r
+        vext.8 q2, \qY, q10, #15        @ S3sl = S3prev[15] | (S3 << 8)     < X >\r
+        vmov \qY, q10                   @ S3prev = S3       < Y >\r
+    .endif\r
+\r
+    .ifeqs "\qT", "q11"\r
+        vshr.u64 d16, d17, #(64-8)      @ S1[0] = S1[15] | ...\r
+    .endif\r
+\r
+        vshr.u64 d18, d19, #(64-8)      @ S2[0] = S2[15] | ...\r
+\r
+    .ifeqs "\qY", "q13"\r
+        vshr.u64 d20, d21, #(64-8)      @ S3[0] = S3[15] | ...\r
+    .endif\r
+    .ifeqs "\qT", "q11"\r
+        vext.8 q3, \qT, q8, #1          @ S1sr = (S1prev >> 8) | S1[0]      < U >\r
+    .endif\r
+\r
+        vext.8 q4, q12, q9, #1          @ S2sr = (S2prev >> 8) | S2[0]      < W >\r
+\r
+    .ifeqs "\qY", "q13"\r
+        vext.8 q5, \qY, q10, #1         @ S3sr = (S3prev >> 8) | S3[0]      < Z >\r
+    .else\r
+        vmov q2, q1                     @ S3sl = S2sl       < X >\r
+\r
+        vmov q5, q4                     @ S3sr = S2sr       < Z >\r
+    .endif\r
+\r
+    .ifnes "\qT", "q11"\r
+        vmov q0, q1                     @ S1sl = S2sl       < S >\r
+\r
+        vmov q3, q4                     @ S1sr = S2sr       < U >\r
+    .endif\r
+\r
+        vceq.i8 q14, q0, \qT            @ E1 = < S == T >\r
+\r
+        vceq.i8 q15, q0, q1             @ tmp1 = < S == V >\r
+\r
+        vceq.i8 q6, q2, \qY             @ E3 = < X == Y >\r
+\r
+        vceq.i8 q7, q2, q1              @ tmp2 = < X == V >\r
+\r
+        vand q14, q14, q15              @ E1 = < S == T && S == V >\r
+\r
+@ q0 = tmp3\r
+@ q15 = E2\r
+\r
+        vceq.i8 q15, q3, \qT            @ E2 = < U == T >\r
+\r
+        vceq.i8 q0, q3, q4              @ tmp3 = < U == W >\r
+\r
+        vand q6, q6, q7                 @ E3 = < X == Y && X == V >\r
+\r
+@ q2 = tmp4\r
+@ q7 = E4\r
+        vceq.i8 q7, q5, \qY             @ E4 = < Z == Y >\r
+\r
+        vceq.i8 q2, q5, q4              @ tmp4 = < Z == W >\r
+\r
+        vand q15, q15, q0               @ E2 = < U == T && U == W >\r
+\r
+        vbsl q14, \qT, q12              @ E1 = < (S == T && S == V) ? T : C >\r
+\r
+        vbsl q15, \qT, q12              @ E2 = < (U == T && U == W) ? T : C >\r
+\r
+        vand q7, q7, q2                 @ E4 = < Z == Y && Z == W >\r
+\r
+        vbsl q6, \qY, q12               @ E3 = < (X == Y && X == V) ? Y : C >\r
+\r
+        vbsl q7, \qY, q12               @ E4 = < (Z == Y && Z == W) ? Y : C >\r
+        vst2.8 {q14-q15}, [\aldst1]!    @ [dst] = E1,E2; dst1 += 2*16\r
+\r
+        vst2.8 {q6-q7}, [\aldst2]!      @ [dst + dststride] = E3,E4; dst2 += 2*16\r
+\r
+.endm\r
+\r
+.macro _neon_eagle2x_8_8_line_first src1, src2, src3, counter, dst1, dst2, reg1, alsrc1, alsrc2, alsrc3, aldst1, aldst2\r
+        __neon_eagle2x_8_8_line \src1, \src2, \src3, \counter, \dst1, \dst2, \reg1, q12, q13, \alsrc1, \alsrc2, \alsrc3, \aldst1, \aldst2\r
+.endm\r
+\r
+.macro _neon_eagle2x_8_8_line_middle src1, src2, src3, counter, dst1, dst2, reg1, alsrc1, alsrc2, alsrc3, aldst1, aldst2\r
+        __neon_eagle2x_8_8_line \src1, \src2, \src3, \counter, \dst1, \dst2, \reg1, q11, q13, \alsrc1, \alsrc2, \alsrc3, \aldst1, \aldst2\r
+.endm\r
+\r
+.macro _neon_eagle2x_8_8_line_last src1, src2, src3, counter, dst1, dst2, reg1, alsrc1, alsrc2, alsrc3, aldst1, aldst2\r
+        __neon_eagle2x_8_8_line \src1, \src2, \src3, \counter, \dst1, \dst2, \reg1, q11, q12, \alsrc1, \alsrc2, \alsrc3, \aldst1, \aldst2\r
+.endm\r
+\r
+.macro neon_eagle2x_8_8_line part, src1, src2, src3, counter, dst1, dst2, reg1, srcalign16, dstalign32\r
+    .ifeq \srcalign16\r
+\r
+    .ifeq \dstalign32\r
+        _neon_eagle2x_8_8_line_\part \src1, \src2, \src3, \counter, \dst1, \dst2, \reg1, \src1, \src2, \src3, \dst1, \dst2\r
+    .else\r
+        _neon_eagle2x_8_8_line_\part \src1, \src2, \src3, \counter, \dst1, \dst2, \reg1, \src1, \src2, \src3, \dst1:256, \dst2:256\r
+    .endif\r
+\r
+    .else\r
+\r
+    .ifeq \dstalign32\r
+        _neon_eagle2x_8_8_line_\part \src1, \src2, \src3, \counter, \dst1, \dst2, \reg1, \src1:128, \src2:128, \src3:128, \dst1, \dst2\r
+    .else\r
+        _neon_eagle2x_8_8_line_\part \src1, \src2, \src3, \counter, \dst1, \dst2, \reg1, \src1:128, \src2:128, \src3:128, \dst1:256, \dst2:256\r
+    .endif\r
+\r
+    .endif\r
+.endm\r
+\r
+\r
+.macro __neon_eagle2x_16_16_line src1, src2, src3, counter, dst1, dst2, reg1, qT, qY, alsrc1, alsrc2, alsrc3, aldst1, aldst2\r
+\r
+    .ifeqs "\qT", "q11"\r
+        vld1.16 {d23[3]}, [\src1]       @ S1prev[7] = src[-srcstride]\r
+    .endif\r
+        vld1.16 {d25[3]}, [\src2]       @ S2prev[7] = src[0]\r
+    .ifeqs "\qY", "q13"\r
+        vld1.16 {d27[3]}, [\src3]       @ S3prev[7] = src[srcstride]\r
+    .endif\r
+        andS \reg1, \counter, #7        @ reg1 = counter & 7\r
+\r
+    .ifnes "\qT", "q11"\r
+        add \src1, \src1, \counter, lsl #1  @ src1 += 2 * counter\r
+    .endif\r
+    .ifnes "\qY", "q13"\r
+        add \src3, \src3, \counter, lsl #1  @ src3 += 2 * counter\r
+    .endif\r
+        beq 1f\r
+\r
+    @ first 1-7 pixels - align counter to 16 bytes\r
+\r
+@ q0  = S1sl    < S >\r
+@ q2  = S3sl    < X >\r
+@ q7  = tmp2\r
+@ q15 = tmp1\r
+\r
+    .ifeqs "\qT", "q11"\r
+        vld1.16 {q8}, [\src1]           @ S1 = [src - srcstride]\r
+        add \src1, \src1, \reg1, lsl #1 @ src1 += 2 * (counter & 7)\r
+    .endif\r
+\r
+        vld1.16 {q9}, [\src2]           @ S2 = [src            ]\r
+        add \src2, \src2, \reg1, lsl #1 @ src2 += 2 * (counter & 7)\r
+\r
+    .ifeqs "\qY", "q13"\r
+        vld1.16 {q10}, [\src3]          @ S3 = [src + srcstride]\r
+        add \src3, \src3, \reg1, lsl #1 @ src3 += 2 * (counter & 7)\r
+    .endif\r
+    .ifeqs "\qT", "q11"\r
+        vext.8 q0, \qT, q8, #14         @ S1sl = S1prev[7] | (S1 << 16)     < S >\r
+\r
+        vmov \qT, q8                    @ S1prev = S1       < T >\r
+    .endif\r
+        vext.8 q1, q12, q9, #14         @ S2sl = S2prev[7] | (S2 << 16)     < V >\r
+\r
+        vmov q12, q9                    @ S2prev = S2       < C >\r
+    .ifeqs "\qY", "q13"\r
+        vext.8 q2, \qY, q10, #14        @ S3sl = S3prev[7] | (S3 << 16)     < X >\r
+\r
+        vmov \qY, q10                   @ S3prev = S3       < Y >\r
+    .endif\r
+    .ifeqs "\qT", "q11"\r
+        vext.8 q3, \qT, q8, #2          @ S1sr = (S1prev >> 16) | ...        < U >\r
+    .endif\r
+\r
+        vext.8 q4, q12, q9, #2          @ S2sr = (S2prev >> 16) | ...        < W >\r
+\r
+    .ifeqs "\qY", "q13"\r
+        vext.8 q5, \qY, q10, #2         @ S3sr = (S3prev >> 16) | ...        < Z >\r
+    .else\r
+        vmov q2, q1                     @ S3sl = S2sl       < X >\r
+\r
+        vmov q5, q4                     @ S3sr = S2sr       < Z >\r
+    .endif\r
+\r
+    .ifnes "\qT", "q11"\r
+        vmov q0, q1                     @ S1sl = S2sl       < S >\r
+\r
+        vmov q3, q4                     @ S1sr = S2sr       < U >\r
+    .endif\r
+\r
+        vceq.i16 q14, q0, \qT           @ E1 = < S == T >\r
+\r
+        vceq.i16 q15, q0, q1            @ tmp1 = < S == V >\r
+\r
+        vceq.i16 q6, q2, \qY            @ E3 = < X == Y >\r
+\r
+        vceq.i16 q7, q2, q1             @ tmp2 = < X == V >\r
+\r
+        vand q14, q14, q15              @ E1 = < S == T && S == V >\r
+\r
+@ q0 = tmp3\r
+@ q15 = E2\r
+\r
+        vceq.i16 q15, q3, \qT           @ E2 = < U == T >\r
+\r
+        vceq.i16 q0, q3, q4             @ tmp3 = < U == W >\r
+\r
+        vand q6, q6, q7                 @ E3 = < X == Y && X == V >\r
+\r
+@ q2 = tmp4\r
+@ q7 = E4\r
+        vceq.i16 q7, q5, \qY            @ E4 = < Z == Y >\r
+\r
+        vceq.i16 q2, q5, q4             @ tmp4 = < Z == W >\r
+\r
+        vand q15, q15, q0               @ E2 = < U == T && U == W >\r
+\r
+        vbsl q14, \qT, q12              @ E1 = < (S == T && S == V) ? T : C >\r
+\r
+        vbsl q15, \qT, q12              @ E2 = < (U == T && U == W) ? T : C >\r
+\r
+        vand q7, q7, q2                 @ E4 = < Z == Y && Z == W >\r
+\r
+        vbsl q6, \qY, q12               @ E3 = < (X == Y && X == V) ? Y : C >\r
+\r
+    .ifeqs "\qT", "q11"\r
+        sub \reg1, \src1, #2\r
+    .else\r
+        sub \reg1, \src2, #2\r
+    .endif\r
+\r
+        vbsl q7, \qY, q12               @ E4 = < (Z == Y && Z == W) ? Y : C >\r
+    .ifeqs "\qT", "q11"\r
+        vld1.16 {d23[3]}, [\reg1]       @ S1prev[7] = src[2 * (counter & 7) - 2 - srcstride]\r
+\r
+        sub \reg1, \src2, #2\r
+    .endif\r
+\r
+        vld1.16 {d25[3]}, [\reg1]       @ S2prev[7] = src[2 * (counter & 7) - 2]\r
+\r
+    .ifeqs "\qY", "q13"\r
+        sub \reg1, \src3, #2\r
+\r
+        vld1.16 {d27[3]}, [\reg1]       @ S3prev[7] = src[2 * (counter & 7) - 2 + srcstride]\r
+    .endif\r
+\r
+        ubfx \reg1, \counter, #0, #3    @ reg1 = counter & 7\r
+\r
+        lsl \reg1, #2\r
+\r
+        vst2.16 {q14-q15}, [\dst1], \reg1   @ [dst] = E1,E2; dst1 += reg1\r
+\r
+        bic \counter, \counter, #7\r
+\r
+        vst2.16 {q6-q7}, [\dst2], \reg1     @ [dst + dststride] = E3,E4; dst2 += reg1\r
+\r
+    @ counter is aligned to 16 bytes\r
+\r
+    1:\r
+    .ifeqs "\qT", "q11"\r
+        vld1.16 {q8}, [\alsrc1]!        @ S1 = [src - srcstride]; src1 += 2*8\r
+    .endif\r
+        vld1.16 {q9}, [\alsrc2]!        @ S2 = [src            ]; src2 += 2*8\r
+    .ifeqs "\qY", "q13"\r
+        vld1.16 {q10}, [\alsrc3]!       @ S3 = [src + srcstride]; src3 += 2*8\r
+    .endif\r
+\r
+    @ inner loop (8 pixels per iteration)\r
+    2:\r
+\r
+@ q0  = S1sl    < S >\r
+@ q2  = S3sl    < X >\r
+@ q7  = tmp2\r
+@ q15 = tmp1\r
+\r
+    .ifeqs "\qT", "q11"\r
+        vext.8 q0, \qT, q8, #14         @ S1sl = S1prev[7] | (S1 << 16)     < S >\r
+        vmov \qT, q8                    @ S1prev = S1       < T >\r
+    .endif\r
+\r
+        vext.8 q1, q12, q9, #14         @ S2sl = S2prev[7] | (S2 << 16)     < V >\r
+        vmov q12, q9                    @ S2prev = S2       < C >\r
+\r
+    .ifeqs "\qY", "q13"\r
+        vext.8 q2, \qY, q10, #14        @ S3sl = S3prev[7] | (S3 << 16)     < X >\r
+        vmov \qY, q10                   @ S3prev = S3       < Y >\r
+    .endif\r
+\r
+    .ifeqs "\qT", "q11"\r
+        vld1.16 {q8}, [\alsrc1]!        @ S1 = [src - srcstride]; src1 += 2*8\r
+        vext.8 q3, \qT, q8, #2          @ S1sr = (S1prev >> 16) | S1[0]      < U >\r
+    .endif\r
+\r
+        vld1.16 {q9}, [\alsrc2]!        @ S2 = [src            ]; src2 += 2*8\r
+        vext.8 q4, q12, q9, #2          @ S2sr = (S2prev >> 16) | S2[0]      < W >\r
+\r
+    .ifeqs "\qY", "q13"\r
+        vld1.16 {q10}, [\alsrc3]!       @ S3 = [src + srcstride]; src3 += 2*8\r
+        vext.8 q5, \qY, q10, #2         @ S3sr = (S3prev >> 16) | S3[0]      < Z >\r
+    .else\r
+        vmov q2, q1                     @ S3sl = S2sl       < X >\r
+\r
+        vmov q5, q4                     @ S3sr = S2sr       < Z >\r
+    .endif\r
+\r
+    .ifnes "\qT", "q11"\r
+        vmov q0, q1                     @ S1sl = S2sl       < S >\r
+\r
+        vmov q3, q4                     @ S1sr = S2sr       < U >\r
+    .endif\r
+\r
+        sub \counter, \counter, #8      @ counter -= 8\r
+        vceq.i16 q14, q0, \qT           @ E1 = < S == T >\r
+\r
+        vceq.i16 q15, q0, q1            @ tmp1 = < S == V >\r
+\r
+        vceq.i16 q6, q2, \qY            @ E3 = < X == Y >\r
+\r
+        vceq.i16 q7, q2, q1             @ tmp2 = < X == V >\r
+\r
+        vand q14, q14, q15              @ E1 = < S == T && S == V >\r
+\r
+@ q0 = tmp3\r
+@ q15 = E2\r
+\r
+        vceq.i16 q15, q3, \qT           @ E2 = < U == T >\r
+\r
+        vceq.i16 q0, q3, q4             @ tmp3 = < U == W >\r
+\r
+        vand q6, q6, q7                 @ E3 = < X == Y && X == V >\r
+\r
+@ q2 = tmp4\r
+@ q7 = E4\r
+        vceq.i16 q7, q5, \qY            @ E4 = < Z == Y >\r
+\r
+        vceq.i16 q2, q5, q4             @ tmp4 = < Z == W >\r
+\r
+        vand q15, q15, q0               @ E2 = < U == T && U == W >\r
+\r
+        vbsl q14, \qT, q12              @ E1 = < (S == T && S == V) ? T : C >\r
+\r
+        vbsl q15, \qT, q12              @ E2 = < (U == T && U == W) ? T : C >\r
+\r
+        vand q7, q7, q2                 @ E4 = < Z == Y && Z == W >\r
+\r
+        vbsl q6, \qY, q12               @ E3 = < (X == Y && X == V) ? Y : C >\r
+\r
+        vbsl q7, \qY, q12               @ E4 = < (Z == Y && Z == W) ? Y : C >\r
+        vst2.16 {q14-q15}, [\aldst1]!   @ [dst] = E1,E2; dst1 += 2*2*8\r
+\r
+        cmp \counter, #8\r
+\r
+        vst2.16 {q6-q7}, [\aldst2]!     @ [dst + dststride] = E3,E4; dst2 += 2*2*8\r
+        bhi 2b\r
+\r
+    @ last 8 pixels\r
+\r
+@ q0  = S1sl    < S >\r
+@ q2  = S3sl    < X >\r
+@ q7  = tmp2\r
+@ q15 = tmp1\r
+\r
+    .ifeqs "\qT", "q11"\r
+        vext.8 q0, \qT, q8, #14         @ S1sl = S1prev[7] | (S1 << 16)     < S >\r
+        vmov \qT, q8                    @ S1prev = S1       < T >\r
+    .endif\r
+\r
+        vext.8 q1, q12, q9, #14         @ S2sl = S2prev[7] | (S2 << 16)     < V >\r
+        vmov q12, q9                    @ S2prev = S2       < C >\r
+\r
+    .ifeqs "\qY", "q13"\r
+        vext.8 q2, \qY, q10, #14        @ S3sl = S3prev[7] | (S3 << 16)     < X >\r
+        vmov \qY, q10                   @ S3prev = S3       < Y >\r
+    .endif\r
+\r
+    .ifeqs "\qT", "q11"\r
+        vshr.u64 d16, d17, #(64-16)     @ S1[0] = S1[7] | ...\r
+    .endif\r
+\r
+        vshr.u64 d18, d19, #(64-16)     @ S2[0] = S2[7] | ...\r
+\r
+    .ifeqs "\qY", "q13"\r
+        vshr.u64 d20, d21, #(64-16)     @ S3[0] = S3[7] | ...\r
+    .endif\r
+    .ifeqs "\qT", "q11"\r
+        vext.8 q3, \qT, q8, #2          @ S1sr = (S1prev >> 16) | S1[0]      < U >\r
+    .endif\r
+\r
+        vext.8 q4, q12, q9, #2          @ S2sr = (S2prev >> 16) | S2[0]      < W >\r
+\r
+    .ifeqs "\qY", "q13"\r
+        vext.8 q5, \qY, q10, #2         @ S3sr = (S3prev >> 16) | S3[0]      < Z >\r
+    .else\r
+        vmov q2, q1                     @ S3sl = S2sl       < X >\r
+\r
+        vmov q5, q4                     @ S3sr = S2sr       < Z >\r
+    .endif\r
+\r
+    .ifnes "\qT", "q11"\r
+        vmov q0, q1                     @ S1sl = S2sl       < S >\r
+\r
+        vmov q3, q4                     @ S1sr = S2sr       < U >\r
+    .endif\r
+\r
+        vceq.i16 q14, q0, \qT           @ E1 = < S == T >\r
+\r
+        vceq.i16 q15, q0, q1            @ tmp1 = < S == V >\r
+\r
+        vceq.i16 q6, q2, \qY            @ E3 = < X == Y >\r
+\r
+        vceq.i16 q7, q2, q1             @ tmp2 = < X == V >\r
+\r
+        vand q14, q14, q15              @ E1 = < S == T && S == V >\r
+\r
+@ q0 = tmp3\r
+@ q15 = E2\r
+\r
+        vceq.i16 q15, q3, \qT           @ E2 = < U == T >\r
+\r
+        vceq.i16 q0, q3, q4             @ tmp3 = < U == W >\r
+\r
+        vand q6, q6, q7                 @ E3 = < X == Y && X == V >\r
+\r
+@ q2 = tmp4\r
+@ q7 = E4\r
+        vceq.i16 q7, q5, \qY            @ E4 = < Z == Y >\r
+\r
+        vceq.i16 q2, q5, q4             @ tmp4 = < Z == W >\r
+\r
+        vand q15, q15, q0               @ E2 = < U == T && U == W >\r
+\r
+        vbsl q14, \qT, q12              @ E1 = < (S == T && S == V) ? T : C >\r
+\r
+        vbsl q15, \qT, q12              @ E2 = < (U == T && U == W) ? T : C >\r
+\r
+        vand q7, q7, q2                 @ E4 = < Z == Y && Z == W >\r
+\r
+        vbsl q6, \qY, q12               @ E3 = < (X == Y && X == V) ? Y : C >\r
+\r
+        vbsl q7, \qY, q12               @ E4 = < (Z == Y && Z == W) ? Y : C >\r
+        vst2.16 {q14-q15}, [\aldst1]!   @ [dst] = E1,E2; dst1 += 2*2*8\r
+\r
+        vst2.16 {q6-q7}, [\aldst2]!     @ [dst + dststride] = E3,E4; dst2 += 2*2*8\r
+\r
+.endm\r
+\r
+.macro _neon_eagle2x_16_16_line_first src1, src2, src3, counter, dst1, dst2, reg1, alsrc1, alsrc2, alsrc3, aldst1, aldst2\r
+        __neon_eagle2x_16_16_line \src1, \src2, \src3, \counter, \dst1, \dst2, \reg1, q12, q13, \alsrc1, \alsrc2, \alsrc3, \aldst1, \aldst2\r
+.endm\r
+\r
+.macro _neon_eagle2x_16_16_line_middle src1, src2, src3, counter, dst1, dst2, reg1, alsrc1, alsrc2, alsrc3, aldst1, aldst2\r
+        __neon_eagle2x_16_16_line \src1, \src2, \src3, \counter, \dst1, \dst2, \reg1, q11, q13, \alsrc1, \alsrc2, \alsrc3, \aldst1, \aldst2\r
+.endm\r
+\r
+.macro _neon_eagle2x_16_16_line_last src1, src2, src3, counter, dst1, dst2, reg1, alsrc1, alsrc2, alsrc3, aldst1, aldst2\r
+        __neon_eagle2x_16_16_line \src1, \src2, \src3, \counter, \dst1, \dst2, \reg1, q11, q12, \alsrc1, \alsrc2, \alsrc3, \aldst1, \aldst2\r
+.endm\r
+\r
+.macro neon_eagle2x_16_16_line part, src1, src2, src3, counter, dst1, dst2, reg1, srcalign16, dstalign32\r
+    .ifeq \srcalign16\r
+\r
+    .ifeq \dstalign32\r
+        _neon_eagle2x_16_16_line_\part \src1, \src2, \src3, \counter, \dst1, \dst2, \reg1, \src1, \src2, \src3, \dst1, \dst2\r
+    .else\r
+        _neon_eagle2x_16_16_line_\part \src1, \src2, \src3, \counter, \dst1, \dst2, \reg1, \src1, \src2, \src3, \dst1:256, \dst2:256\r
+    .endif\r
+\r
+    .else\r
+\r
+    .ifeq \dstalign32\r
+        _neon_eagle2x_16_16_line_\part \src1, \src2, \src3, \counter, \dst1, \dst2, \reg1, \src1:128, \src2:128, \src3:128, \dst1, \dst2\r
+    .else\r
+        _neon_eagle2x_16_16_line_\part \src1, \src2, \src3, \counter, \dst1, \dst2, \reg1, \src1:128, \src2:128, \src3:128, \dst1:256, \dst2:256\r
+    .endif\r
+\r
+    .endif\r
+.endm\r
+\r