xref: /aosp_15_r20/external/libdav1d/src/arm/32/looprestoration.S (revision c09093415860a1c2373dacd84c4fde00c507cdfd)
1*c0909341SAndroid Build Coastguard Worker/*
2*c0909341SAndroid Build Coastguard Worker * Copyright © 2018, VideoLAN and dav1d authors
3*c0909341SAndroid Build Coastguard Worker * Copyright © 2019, Martin Storsjo
4*c0909341SAndroid Build Coastguard Worker * All rights reserved.
5*c0909341SAndroid Build Coastguard Worker *
6*c0909341SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
7*c0909341SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
8*c0909341SAndroid Build Coastguard Worker *
9*c0909341SAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright notice, this
10*c0909341SAndroid Build Coastguard Worker *    list of conditions and the following disclaimer.
11*c0909341SAndroid Build Coastguard Worker *
12*c0909341SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright notice,
13*c0909341SAndroid Build Coastguard Worker *    this list of conditions and the following disclaimer in the documentation
14*c0909341SAndroid Build Coastguard Worker *    and/or other materials provided with the distribution.
15*c0909341SAndroid Build Coastguard Worker *
16*c0909341SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17*c0909341SAndroid Build Coastguard Worker * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18*c0909341SAndroid Build Coastguard Worker * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19*c0909341SAndroid Build Coastguard Worker * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20*c0909341SAndroid Build Coastguard Worker * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21*c0909341SAndroid Build Coastguard Worker * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22*c0909341SAndroid Build Coastguard Worker * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23*c0909341SAndroid Build Coastguard Worker * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24*c0909341SAndroid Build Coastguard Worker * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25*c0909341SAndroid Build Coastguard Worker * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*c0909341SAndroid Build Coastguard Worker */
27*c0909341SAndroid Build Coastguard Worker
28*c0909341SAndroid Build Coastguard Worker#include "src/arm/asm.S"
29*c0909341SAndroid Build Coastguard Worker#include "util.S"
30*c0909341SAndroid Build Coastguard Worker
31*c0909341SAndroid Build Coastguard Workerconst right_ext_mask_buf
32*c0909341SAndroid Build Coastguard Worker        .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
33*c0909341SAndroid Build Coastguard Worker        .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
34*c0909341SAndroid Build Coastguard Worker        .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
35*c0909341SAndroid Build Coastguard Worker        .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
36*c0909341SAndroid Build Coastguard Workerright_ext_mask:
37*c0909341SAndroid Build Coastguard Worker        .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
38*c0909341SAndroid Build Coastguard Worker        .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
39*c0909341SAndroid Build Coastguard Worker        .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
40*c0909341SAndroid Build Coastguard Worker        .byte 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
41*c0909341SAndroid Build Coastguard Workerendconst
42*c0909341SAndroid Build Coastguard Worker
43*c0909341SAndroid Build Coastguard Worker// void dav1d_wiener_filter_h_8bpc_neon(int16_t *dst, const pixel (*left)[4],
44*c0909341SAndroid Build Coastguard Worker//                                      const pixel *src, ptrdiff_t stride,
45*c0909341SAndroid Build Coastguard Worker//                                      const int16_t fh[8], intptr_t w,
46*c0909341SAndroid Build Coastguard Worker//                                      int h, enum LrEdgeFlags edges);
47*c0909341SAndroid Build Coastguard Workerfunction wiener_filter_h_8bpc_neon, export=1
48*c0909341SAndroid Build Coastguard Worker        push            {r4-r11,lr}
49*c0909341SAndroid Build Coastguard Worker        vpush           {q4-q7}
50*c0909341SAndroid Build Coastguard Worker        ldrd            r4,  r5,  [sp, #100]
51*c0909341SAndroid Build Coastguard Worker        ldrd            r6,  r7,  [sp, #108]
52*c0909341SAndroid Build Coastguard Worker        mov             r8,  r5
53*c0909341SAndroid Build Coastguard Worker        vld1.16         {q0},  [r4, :128]
54*c0909341SAndroid Build Coastguard Worker        movw            r9,  #(1 << 14) - (1 << 2)
55*c0909341SAndroid Build Coastguard Worker        vdup.16         q14, r9
56*c0909341SAndroid Build Coastguard Worker        vmov.s16        q15, #2048
57*c0909341SAndroid Build Coastguard Worker        // Calculate mid_stride
58*c0909341SAndroid Build Coastguard Worker        add             r10, r5,  #7
59*c0909341SAndroid Build Coastguard Worker        bic             r10, r10, #7
60*c0909341SAndroid Build Coastguard Worker        lsl             r10, r10, #1
61*c0909341SAndroid Build Coastguard Worker
62*c0909341SAndroid Build Coastguard Worker        // Set up pointers for reading/writing alternate rows
63*c0909341SAndroid Build Coastguard Worker        add             r12, r0,  r10
64*c0909341SAndroid Build Coastguard Worker        lsl             r10, r10, #1
65*c0909341SAndroid Build Coastguard Worker        add             lr,  r2,  r3
66*c0909341SAndroid Build Coastguard Worker        lsl             r3,  r3,  #1
67*c0909341SAndroid Build Coastguard Worker
68*c0909341SAndroid Build Coastguard Worker        // Subtract the aligned width from mid_stride
69*c0909341SAndroid Build Coastguard Worker        add             r11, r5,  #7
70*c0909341SAndroid Build Coastguard Worker        bic             r11, r11, #7
71*c0909341SAndroid Build Coastguard Worker        sub             r10, r10, r11, lsl #1
72*c0909341SAndroid Build Coastguard Worker
73*c0909341SAndroid Build Coastguard Worker        // Subtract the number of pixels read from the source stride
74*c0909341SAndroid Build Coastguard Worker        add             r11, r11, #8
75*c0909341SAndroid Build Coastguard Worker        sub             r3,  r3,  r11
76*c0909341SAndroid Build Coastguard Worker
77*c0909341SAndroid Build Coastguard Worker        // Set up the src pointers to include the left edge, for LR_HAVE_LEFT, left == NULL
78*c0909341SAndroid Build Coastguard Worker        tst             r7,  #1 // LR_HAVE_LEFT
79*c0909341SAndroid Build Coastguard Worker        beq             2f
80*c0909341SAndroid Build Coastguard Worker        // LR_HAVE_LEFT
81*c0909341SAndroid Build Coastguard Worker        cmp             r1,  #0
82*c0909341SAndroid Build Coastguard Worker        bne             0f
83*c0909341SAndroid Build Coastguard Worker        // left == NULL
84*c0909341SAndroid Build Coastguard Worker        sub             r2,  r2,  #3
85*c0909341SAndroid Build Coastguard Worker        sub             lr,  lr,  #3
86*c0909341SAndroid Build Coastguard Worker        b               1f
87*c0909341SAndroid Build Coastguard Worker0:      // LR_HAVE_LEFT, left != NULL
88*c0909341SAndroid Build Coastguard Worker2:      // !LR_HAVE_LEFT, increase the stride.
89*c0909341SAndroid Build Coastguard Worker        // For this case we don't read the left 3 pixels from the src pointer,
90*c0909341SAndroid Build Coastguard Worker        // but shift it as if we had done that.
91*c0909341SAndroid Build Coastguard Worker        add             r3,  r3,  #3
92*c0909341SAndroid Build Coastguard Worker
93*c0909341SAndroid Build Coastguard Worker
94*c0909341SAndroid Build Coastguard Worker1:      // Loop vertically
95*c0909341SAndroid Build Coastguard Worker        vld1.8          {q2},  [r2]!
96*c0909341SAndroid Build Coastguard Worker        vld1.8          {q9},  [lr]!
97*c0909341SAndroid Build Coastguard Worker
98*c0909341SAndroid Build Coastguard Worker        tst             r7,  #1 // LR_HAVE_LEFT
99*c0909341SAndroid Build Coastguard Worker        beq             0f
100*c0909341SAndroid Build Coastguard Worker        cmp             r1,  #0
101*c0909341SAndroid Build Coastguard Worker        beq             2f
102*c0909341SAndroid Build Coastguard Worker        // LR_HAVE_LEFT, left != NULL
103*c0909341SAndroid Build Coastguard Worker        vld1.32         {d3[1]},  [r1]!
104*c0909341SAndroid Build Coastguard Worker        // Move r2/lr back to account for the last 3 bytes we loaded earlier,
105*c0909341SAndroid Build Coastguard Worker        // which we'll shift out.
106*c0909341SAndroid Build Coastguard Worker        sub             r2,  r2,  #3
107*c0909341SAndroid Build Coastguard Worker        sub             lr,  lr,  #3
108*c0909341SAndroid Build Coastguard Worker        vld1.32         {d17[1]},  [r1]!
109*c0909341SAndroid Build Coastguard Worker        vext.8          q2,  q1,  q2,  #13
110*c0909341SAndroid Build Coastguard Worker        vext.8          q9,  q8,  q9,  #13
111*c0909341SAndroid Build Coastguard Worker        b               2f
112*c0909341SAndroid Build Coastguard Worker0:
113*c0909341SAndroid Build Coastguard Worker        // !LR_HAVE_LEFT, fill q1 with the leftmost byte
114*c0909341SAndroid Build Coastguard Worker        // and shift q2 to have 3x the first byte at the front.
115*c0909341SAndroid Build Coastguard Worker        vdup.8          q1,  d4[0]
116*c0909341SAndroid Build Coastguard Worker        vdup.8          q8,  d18[0]
117*c0909341SAndroid Build Coastguard Worker        // Move r2 back to account for the last 3 bytes we loaded before,
118*c0909341SAndroid Build Coastguard Worker        // which we shifted out.
119*c0909341SAndroid Build Coastguard Worker        sub             r2,  r2,  #3
120*c0909341SAndroid Build Coastguard Worker        sub             lr,  lr,  #3
121*c0909341SAndroid Build Coastguard Worker        vext.8          q2,  q1,  q2,  #13
122*c0909341SAndroid Build Coastguard Worker        vext.8          q9,  q8,  q9,  #13
123*c0909341SAndroid Build Coastguard Worker
124*c0909341SAndroid Build Coastguard Worker2:
125*c0909341SAndroid Build Coastguard Worker        vmovl.u8        q1,  d4
126*c0909341SAndroid Build Coastguard Worker        vmovl.u8        q2,  d5
127*c0909341SAndroid Build Coastguard Worker        vmovl.u8        q8,  d18
128*c0909341SAndroid Build Coastguard Worker        vmovl.u8        q9,  d19
129*c0909341SAndroid Build Coastguard Worker
130*c0909341SAndroid Build Coastguard Worker        tst             r7,  #2 // LR_HAVE_RIGHT
131*c0909341SAndroid Build Coastguard Worker        bne             4f
132*c0909341SAndroid Build Coastguard Worker        // If we'll need to pad the right edge, load that byte to pad with
133*c0909341SAndroid Build Coastguard Worker        // here since we can find it pretty easily from here.
134*c0909341SAndroid Build Coastguard Worker        sub             r9,  r5,  #14
135*c0909341SAndroid Build Coastguard Worker        ldrb            r11, [r2, r9]
136*c0909341SAndroid Build Coastguard Worker        ldrb            r9,  [lr, r9]
137*c0909341SAndroid Build Coastguard Worker        // Fill q12/q13 with the right padding pixel
138*c0909341SAndroid Build Coastguard Worker        vdup.16         q12, r11
139*c0909341SAndroid Build Coastguard Worker        vdup.16         q13, r9
140*c0909341SAndroid Build Coastguard Worker3:      // !LR_HAVE_RIGHT
141*c0909341SAndroid Build Coastguard Worker
142*c0909341SAndroid Build Coastguard Worker        // Check whether we need to pad the right edge
143*c0909341SAndroid Build Coastguard Worker        cmp             r5,  #11
144*c0909341SAndroid Build Coastguard Worker        bge             4f   // If w >= 11, all used input pixels are valid
145*c0909341SAndroid Build Coastguard Worker
146*c0909341SAndroid Build Coastguard Worker        // 1 <= w < 11, w+3 pixels valid in q1-q2. For w=9 or w=10,
147*c0909341SAndroid Build Coastguard Worker        // this ends up called again; it's not strictly needed in those
148*c0909341SAndroid Build Coastguard Worker        // cases (we pad enough here), but keeping the code as simple as possible.
149*c0909341SAndroid Build Coastguard Worker
150*c0909341SAndroid Build Coastguard Worker        // Insert padding in q1/2.h[w+3] onwards; fuse the +3 (*2) into the
151*c0909341SAndroid Build Coastguard Worker        // buffer pointer.
152*c0909341SAndroid Build Coastguard Worker        movrel_local    r4,  right_ext_mask, -6
153*c0909341SAndroid Build Coastguard Worker        sub             r4,  r4,  r5,  lsl #1
154*c0909341SAndroid Build Coastguard Worker        vld1.8          {q10, q11}, [r4]
155*c0909341SAndroid Build Coastguard Worker
156*c0909341SAndroid Build Coastguard Worker        vbit            q1,  q12, q10
157*c0909341SAndroid Build Coastguard Worker        vbit            q2,  q12, q11
158*c0909341SAndroid Build Coastguard Worker        vbit            q8,  q13, q10
159*c0909341SAndroid Build Coastguard Worker        vbit            q9,  q13, q11
160*c0909341SAndroid Build Coastguard Worker
161*c0909341SAndroid Build Coastguard Worker4:      // Loop horizontally
162*c0909341SAndroid Build Coastguard Worker        vext.8          q11, q1,  q2,  #4
163*c0909341SAndroid Build Coastguard Worker        vext.8          q5,  q1,  q2,  #8
164*c0909341SAndroid Build Coastguard Worker        vext.8          q10, q1,  q2,  #2
165*c0909341SAndroid Build Coastguard Worker        vext.8          q6,  q1,  q2,  #10
166*c0909341SAndroid Build Coastguard Worker        vext.8          q7,  q1,  q2,  #12
167*c0909341SAndroid Build Coastguard Worker        vext.8          q4,  q1,  q2,  #6
168*c0909341SAndroid Build Coastguard Worker        vadd.i16        q5,  q5,  q11
169*c0909341SAndroid Build Coastguard Worker        vadd.i16        q6,  q6,  q10
170*c0909341SAndroid Build Coastguard Worker        vadd.i16        q7,  q7,  q1
171*c0909341SAndroid Build Coastguard Worker        vmul.s16        q3,  q4,  d0[3]
172*c0909341SAndroid Build Coastguard Worker        vmla.s16        q3,  q5,  d1[0]
173*c0909341SAndroid Build Coastguard Worker        vmla.s16        q3,  q6,  d1[1]
174*c0909341SAndroid Build Coastguard Worker        vmla.s16        q3,  q7,  d1[2]
175*c0909341SAndroid Build Coastguard Worker
176*c0909341SAndroid Build Coastguard Worker        vext.8          q4,  q8,  q9,  #4
177*c0909341SAndroid Build Coastguard Worker        vext.8          q6,  q8,  q9,  #8
178*c0909341SAndroid Build Coastguard Worker        vext.8          q11, q8,  q9,  #2
179*c0909341SAndroid Build Coastguard Worker        vext.8          q7,  q8,  q9,  #10
180*c0909341SAndroid Build Coastguard Worker        vadd.i16        q6,  q6,  q4
181*c0909341SAndroid Build Coastguard Worker        vext.8          q4,  q8,  q9,  #12
182*c0909341SAndroid Build Coastguard Worker        vext.8          q5,  q8,  q9,  #6
183*c0909341SAndroid Build Coastguard Worker        vadd.i16        q7,  q7,  q11
184*c0909341SAndroid Build Coastguard Worker        vadd.i16        q4,  q4,  q8
185*c0909341SAndroid Build Coastguard Worker        vmul.s16        q10, q5,  d0[3]
186*c0909341SAndroid Build Coastguard Worker        vmla.s16        q10, q6,  d1[0]
187*c0909341SAndroid Build Coastguard Worker        vmla.s16        q10, q7,  d1[1]
188*c0909341SAndroid Build Coastguard Worker        vmla.s16        q10, q4,  d1[2]
189*c0909341SAndroid Build Coastguard Worker
190*c0909341SAndroid Build Coastguard Worker        vext.8          q1,  q1,  q2,  #6
191*c0909341SAndroid Build Coastguard Worker        vext.8          q8,  q8,  q9,  #6
192*c0909341SAndroid Build Coastguard Worker        vshl.s16        q1,  q1,  #7
193*c0909341SAndroid Build Coastguard Worker        vshl.s16        q8,  q8,  #7
194*c0909341SAndroid Build Coastguard Worker        vsub.s16        q1,  q1,  q14
195*c0909341SAndroid Build Coastguard Worker        vsub.s16        q8,  q8,  q14
196*c0909341SAndroid Build Coastguard Worker        vqadd.s16       q3,  q3,  q1
197*c0909341SAndroid Build Coastguard Worker        vqadd.s16       q10, q10, q8
198*c0909341SAndroid Build Coastguard Worker        vshr.s16        q3,  q3,  #3
199*c0909341SAndroid Build Coastguard Worker        vshr.s16        q10, q10, #3
200*c0909341SAndroid Build Coastguard Worker        vadd.s16        q3,  q3,  q15
201*c0909341SAndroid Build Coastguard Worker        vadd.s16        q10, q10, q15
202*c0909341SAndroid Build Coastguard Worker        subs            r5,  r5,  #8
203*c0909341SAndroid Build Coastguard Worker        vst1.16         {q3},  [r0,  :128]!
204*c0909341SAndroid Build Coastguard Worker        vst1.16         {q10}, [r12, :128]!
205*c0909341SAndroid Build Coastguard Worker
206*c0909341SAndroid Build Coastguard Worker        ble             9f
207*c0909341SAndroid Build Coastguard Worker        tst             r7,  #2 // LR_HAVE_RIGHT
208*c0909341SAndroid Build Coastguard Worker        vmov            q1,  q2
209*c0909341SAndroid Build Coastguard Worker        vmov            q8,  q9
210*c0909341SAndroid Build Coastguard Worker        vld1.8          {d4},  [r2]!
211*c0909341SAndroid Build Coastguard Worker        vld1.8          {d18}, [lr]!
212*c0909341SAndroid Build Coastguard Worker        vmovl.u8        q2,  d4
213*c0909341SAndroid Build Coastguard Worker        vmovl.u8        q9,  d18
214*c0909341SAndroid Build Coastguard Worker        bne             4b // If we don't need to pad, just keep filtering.
215*c0909341SAndroid Build Coastguard Worker        b               3b // If we need to pad, check how many pixels we have left.
216*c0909341SAndroid Build Coastguard Worker
217*c0909341SAndroid Build Coastguard Worker9:
218*c0909341SAndroid Build Coastguard Worker        subs            r6,  r6,  #2
219*c0909341SAndroid Build Coastguard Worker        ble             0f
220*c0909341SAndroid Build Coastguard Worker        // Jump to the next row and loop horizontally
221*c0909341SAndroid Build Coastguard Worker        add             r0,  r0,  r10
222*c0909341SAndroid Build Coastguard Worker        add             r12, r12, r10
223*c0909341SAndroid Build Coastguard Worker        add             r2,  r2,  r3
224*c0909341SAndroid Build Coastguard Worker        add             lr,  lr,  r3
225*c0909341SAndroid Build Coastguard Worker        mov             r5,  r8
226*c0909341SAndroid Build Coastguard Worker        b               1b
227*c0909341SAndroid Build Coastguard Worker0:
228*c0909341SAndroid Build Coastguard Worker        vpop            {q4-q7}
229*c0909341SAndroid Build Coastguard Worker        pop             {r4-r11,pc}
230*c0909341SAndroid Build Coastguard Workerendfunc
231*c0909341SAndroid Build Coastguard Worker
232*c0909341SAndroid Build Coastguard Worker// void dav1d_wiener_filter_v_8bpc_neon(pixel *dst, ptrdiff_t stride,
233*c0909341SAndroid Build Coastguard Worker//                                      const int16_t *mid, int w, int h,
234*c0909341SAndroid Build Coastguard Worker//                                      const int16_t fv[8], enum LrEdgeFlags edges,
235*c0909341SAndroid Build Coastguard Worker//                                      ptrdiff_t mid_stride);
236*c0909341SAndroid Build Coastguard Workerfunction wiener_filter_v_8bpc_neon, export=1
237*c0909341SAndroid Build Coastguard Worker        push            {r4-r7,lr}
238*c0909341SAndroid Build Coastguard Worker        vpush           {q4-q6}
239*c0909341SAndroid Build Coastguard Worker        ldrd            r4,  r5,  [sp, #68]
240*c0909341SAndroid Build Coastguard Worker        ldrd            r6,  r7,  [sp, #76]
241*c0909341SAndroid Build Coastguard Worker        mov             lr,  r4
242*c0909341SAndroid Build Coastguard Worker        vld1.16         {q0},  [r5, :128]
243*c0909341SAndroid Build Coastguard Worker
244*c0909341SAndroid Build Coastguard Worker        // Calculate the number of rows to move back when looping vertically
245*c0909341SAndroid Build Coastguard Worker        mov             r12, r4
246*c0909341SAndroid Build Coastguard Worker        tst             r6,  #4 // LR_HAVE_TOP
247*c0909341SAndroid Build Coastguard Worker        beq             0f
248*c0909341SAndroid Build Coastguard Worker        sub             r2,  r2,  r7,  lsl #1
249*c0909341SAndroid Build Coastguard Worker        add             r12, r12, #2
250*c0909341SAndroid Build Coastguard Worker0:
251*c0909341SAndroid Build Coastguard Worker        tst             r6,  #8 // LR_HAVE_BOTTOM
252*c0909341SAndroid Build Coastguard Worker        beq             1f
253*c0909341SAndroid Build Coastguard Worker        add             r12, r12, #2
254*c0909341SAndroid Build Coastguard Worker
255*c0909341SAndroid Build Coastguard Worker1:      // Start of horizontal loop; start one vertical filter slice.
256*c0909341SAndroid Build Coastguard Worker        // Load rows into q8-q11 and pad properly.
257*c0909341SAndroid Build Coastguard Worker        tst             r6,  #4 // LR_HAVE_TOP
258*c0909341SAndroid Build Coastguard Worker        vld1.16         {q8},  [r2, :128], r7
259*c0909341SAndroid Build Coastguard Worker        beq             2f
260*c0909341SAndroid Build Coastguard Worker        // LR_HAVE_TOP
261*c0909341SAndroid Build Coastguard Worker        vld1.16         {q10}, [r2, :128], r7
262*c0909341SAndroid Build Coastguard Worker        vmov            q9,  q8
263*c0909341SAndroid Build Coastguard Worker        vld1.16         {q11}, [r2, :128], r7
264*c0909341SAndroid Build Coastguard Worker        b               3f
265*c0909341SAndroid Build Coastguard Worker2:      // !LR_HAVE_TOP
266*c0909341SAndroid Build Coastguard Worker        vmov            q9,  q8
267*c0909341SAndroid Build Coastguard Worker        vmov            q10, q8
268*c0909341SAndroid Build Coastguard Worker        vmov            q11, q8
269*c0909341SAndroid Build Coastguard Worker
270*c0909341SAndroid Build Coastguard Worker3:
271*c0909341SAndroid Build Coastguard Worker        cmp             r4,  #4
272*c0909341SAndroid Build Coastguard Worker        blt             5f
273*c0909341SAndroid Build Coastguard Worker        // Start filtering normally; fill in q12-q14 with unique rows.
274*c0909341SAndroid Build Coastguard Worker        vld1.16         {q12}, [r2, :128], r7
275*c0909341SAndroid Build Coastguard Worker        vld1.16         {q13}, [r2, :128], r7
276*c0909341SAndroid Build Coastguard Worker        vld1.16         {q14}, [r2, :128], r7
277*c0909341SAndroid Build Coastguard Worker
278*c0909341SAndroid Build Coastguard Worker4:
279*c0909341SAndroid Build Coastguard Worker.macro filter compare
280*c0909341SAndroid Build Coastguard Worker        subs            r4,  r4,  #1
281*c0909341SAndroid Build Coastguard Worker        // Interleaving the mul/mla chains actually hurts performance
282*c0909341SAndroid Build Coastguard Worker        // significantly on Cortex A53, thus keeping mul/mla tightly
283*c0909341SAndroid Build Coastguard Worker        // chained like this.
284*c0909341SAndroid Build Coastguard Worker        vadd.i16        q4,  q10, q12
285*c0909341SAndroid Build Coastguard Worker        vadd.i16        q5,  q9,  q13
286*c0909341SAndroid Build Coastguard Worker        vadd.i16        q6,  q8,  q14
287*c0909341SAndroid Build Coastguard Worker        vmull.s16       q2,  d22, d0[3]
288*c0909341SAndroid Build Coastguard Worker        vmlal.s16       q2,  d8,  d1[0]
289*c0909341SAndroid Build Coastguard Worker        vmlal.s16       q2,  d10, d1[1]
290*c0909341SAndroid Build Coastguard Worker        vmlal.s16       q2,  d12, d1[2]
291*c0909341SAndroid Build Coastguard Worker        vmull.s16       q3,  d23, d0[3]
292*c0909341SAndroid Build Coastguard Worker        vmlal.s16       q3,  d9,  d1[0]
293*c0909341SAndroid Build Coastguard Worker        vmlal.s16       q3,  d11, d1[1]
294*c0909341SAndroid Build Coastguard Worker        vmlal.s16       q3,  d13, d1[2]
295*c0909341SAndroid Build Coastguard Worker        vqrshrun.s32    d4,  q2,  #11
296*c0909341SAndroid Build Coastguard Worker        vqrshrun.s32    d5,  q3,  #11
297*c0909341SAndroid Build Coastguard Worker        vqmovun.s16     d4,  q2
298*c0909341SAndroid Build Coastguard Worker        vst1.8          {d4}, [r0, :64], r1
299*c0909341SAndroid Build Coastguard Worker.if \compare
300*c0909341SAndroid Build Coastguard Worker        cmp             r4,  #4
301*c0909341SAndroid Build Coastguard Worker.else
302*c0909341SAndroid Build Coastguard Worker        ble             9f
303*c0909341SAndroid Build Coastguard Worker.endif
304*c0909341SAndroid Build Coastguard Worker        vmov            q8,  q9
305*c0909341SAndroid Build Coastguard Worker        vmov            q9,  q10
306*c0909341SAndroid Build Coastguard Worker        vmov            q10, q11
307*c0909341SAndroid Build Coastguard Worker        vmov            q11, q12
308*c0909341SAndroid Build Coastguard Worker        vmov            q12, q13
309*c0909341SAndroid Build Coastguard Worker        vmov            q13, q14
310*c0909341SAndroid Build Coastguard Worker.endm
311*c0909341SAndroid Build Coastguard Worker        filter          1
312*c0909341SAndroid Build Coastguard Worker        blt             7f
313*c0909341SAndroid Build Coastguard Worker        vld1.16         {q14}, [r2, :128], r7
314*c0909341SAndroid Build Coastguard Worker        b               4b
315*c0909341SAndroid Build Coastguard Worker
316*c0909341SAndroid Build Coastguard Worker5:      // Less than 4 rows in total; not all of q12-q13 are filled yet.
317*c0909341SAndroid Build Coastguard Worker        tst             r6,  #8 // LR_HAVE_BOTTOM
318*c0909341SAndroid Build Coastguard Worker        beq             6f
319*c0909341SAndroid Build Coastguard Worker        // LR_HAVE_BOTTOM
320*c0909341SAndroid Build Coastguard Worker        cmp             r4,  #2
321*c0909341SAndroid Build Coastguard Worker        // We load at least 2 rows in all cases.
322*c0909341SAndroid Build Coastguard Worker        vld1.16         {q12}, [r2, :128], r7
323*c0909341SAndroid Build Coastguard Worker        vld1.16         {q13}, [r2, :128], r7
324*c0909341SAndroid Build Coastguard Worker        bgt             53f // 3 rows in total
325*c0909341SAndroid Build Coastguard Worker        beq             52f // 2 rows in total
326*c0909341SAndroid Build Coastguard Worker51:     // 1 row in total, q11 already loaded, load edge into q12-q14.
327*c0909341SAndroid Build Coastguard Worker        vmov            q13, q12
328*c0909341SAndroid Build Coastguard Worker        b               8f
329*c0909341SAndroid Build Coastguard Worker52:     // 2 rows in total, q11 already loaded, load q12 with content data
330*c0909341SAndroid Build Coastguard Worker        // and 2 rows of edge.
331*c0909341SAndroid Build Coastguard Worker        vld1.16         {q14}, [r2, :128], r7
332*c0909341SAndroid Build Coastguard Worker        vmov            q15, q14
333*c0909341SAndroid Build Coastguard Worker        b               8f
334*c0909341SAndroid Build Coastguard Worker53:
335*c0909341SAndroid Build Coastguard Worker        // 3 rows in total, q11 already loaded, load q12 and q13 with content
336*c0909341SAndroid Build Coastguard Worker        // and 2 rows of edge.
337*c0909341SAndroid Build Coastguard Worker        vld1.16         {q14}, [r2, :128], r7
338*c0909341SAndroid Build Coastguard Worker        vld1.16         {q15}, [r2, :128], r7
339*c0909341SAndroid Build Coastguard Worker        vmov            q1,  q15
340*c0909341SAndroid Build Coastguard Worker        b               8f
341*c0909341SAndroid Build Coastguard Worker
342*c0909341SAndroid Build Coastguard Worker6:
343*c0909341SAndroid Build Coastguard Worker        // !LR_HAVE_BOTTOM
344*c0909341SAndroid Build Coastguard Worker        cmp             r4,  #2
345*c0909341SAndroid Build Coastguard Worker        bgt             63f // 3 rows in total
346*c0909341SAndroid Build Coastguard Worker        beq             62f // 2 rows in total
347*c0909341SAndroid Build Coastguard Worker61:     // 1 row in total, q11 already loaded, pad that into q12-q14.
348*c0909341SAndroid Build Coastguard Worker        vmov            q12, q11
349*c0909341SAndroid Build Coastguard Worker        vmov            q13, q11
350*c0909341SAndroid Build Coastguard Worker        vmov            q14, q11
351*c0909341SAndroid Build Coastguard Worker        b               8f
352*c0909341SAndroid Build Coastguard Worker62:     // 2 rows in total, q11 already loaded, load q12 and pad that into q12-q15.
353*c0909341SAndroid Build Coastguard Worker        vld1.16         {q12}, [r2, :128], r7
354*c0909341SAndroid Build Coastguard Worker        vmov            q13, q12
355*c0909341SAndroid Build Coastguard Worker        vmov            q14, q12
356*c0909341SAndroid Build Coastguard Worker        vmov            q15, q12
357*c0909341SAndroid Build Coastguard Worker        b               8f
358*c0909341SAndroid Build Coastguard Worker63:
359*c0909341SAndroid Build Coastguard Worker        // 3 rows in total, q11 already loaded, load q12 and q13 and pad q13 into q14-q15,q1.
360*c0909341SAndroid Build Coastguard Worker        vld1.16         {q12}, [r2, :128], r7
361*c0909341SAndroid Build Coastguard Worker        vld1.16         {q13}, [r2, :128], r7
362*c0909341SAndroid Build Coastguard Worker        vmov            q14, q13
363*c0909341SAndroid Build Coastguard Worker        vmov            q15, q13
364*c0909341SAndroid Build Coastguard Worker        vmov            q1,  q13
365*c0909341SAndroid Build Coastguard Worker        b               8f
366*c0909341SAndroid Build Coastguard Worker
367*c0909341SAndroid Build Coastguard Worker7:
368*c0909341SAndroid Build Coastguard Worker        // All registers up to q13 are filled already, 3 valid rows left.
369*c0909341SAndroid Build Coastguard Worker        // < 4 valid rows left; fill in padding and filter the last
370*c0909341SAndroid Build Coastguard Worker        // few rows.
371*c0909341SAndroid Build Coastguard Worker        tst             r6,  #8 // LR_HAVE_BOTTOM
372*c0909341SAndroid Build Coastguard Worker        beq             71f
373*c0909341SAndroid Build Coastguard Worker        // LR_HAVE_BOTTOM; load 2 rows of edge.
374*c0909341SAndroid Build Coastguard Worker        vld1.16         {q14}, [r2, :128], r7
375*c0909341SAndroid Build Coastguard Worker        vld1.16         {q15}, [r2, :128], r7
376*c0909341SAndroid Build Coastguard Worker        vmov            q1,  q15
377*c0909341SAndroid Build Coastguard Worker        b               8f
378*c0909341SAndroid Build Coastguard Worker71:
379*c0909341SAndroid Build Coastguard Worker        // !LR_HAVE_BOTTOM, pad 3 rows
380*c0909341SAndroid Build Coastguard Worker        vmov            q14, q13
381*c0909341SAndroid Build Coastguard Worker        vmov            q15, q13
382*c0909341SAndroid Build Coastguard Worker        vmov            q1,  q13
383*c0909341SAndroid Build Coastguard Worker
384*c0909341SAndroid Build Coastguard Worker8:      // At this point, all registers up to q14-15,q1 are loaded with
385*c0909341SAndroid Build Coastguard Worker        // edge/padding (depending on how many rows are left).
386*c0909341SAndroid Build Coastguard Worker        filter          0 // This branches to 9f when done
387*c0909341SAndroid Build Coastguard Worker        vmov            q14, q15
388*c0909341SAndroid Build Coastguard Worker        vmov            q15, q1
389*c0909341SAndroid Build Coastguard Worker        b               8b
390*c0909341SAndroid Build Coastguard Worker
391*c0909341SAndroid Build Coastguard Worker9:      // End of one vertical slice.
392*c0909341SAndroid Build Coastguard Worker        subs            r3,  r3,  #8
393*c0909341SAndroid Build Coastguard Worker        ble             0f
394*c0909341SAndroid Build Coastguard Worker        // Move pointers back up to the top and loop horizontally.
395*c0909341SAndroid Build Coastguard Worker        mls             r0,  r1,  lr,  r0
396*c0909341SAndroid Build Coastguard Worker        mls             r2,  r7,  r12, r2
397*c0909341SAndroid Build Coastguard Worker        add             r0,  r0,  #8
398*c0909341SAndroid Build Coastguard Worker        add             r2,  r2,  #16
399*c0909341SAndroid Build Coastguard Worker        mov             r4,  lr
400*c0909341SAndroid Build Coastguard Worker        b               1b
401*c0909341SAndroid Build Coastguard Worker
402*c0909341SAndroid Build Coastguard Worker0:
403*c0909341SAndroid Build Coastguard Worker        vpop            {q4-q6}
404*c0909341SAndroid Build Coastguard Worker        pop             {r4-r7,pc}
405*c0909341SAndroid Build Coastguard Worker.purgem filter
406*c0909341SAndroid Build Coastguard Workerendfunc
407*c0909341SAndroid Build Coastguard Worker
408*c0909341SAndroid Build Coastguard Worker#define SUM_STRIDE (384+16)
409*c0909341SAndroid Build Coastguard Worker
410*c0909341SAndroid Build Coastguard Worker#include "looprestoration_tmpl.S"
411*c0909341SAndroid Build Coastguard Worker
412*c0909341SAndroid Build Coastguard Worker// void dav1d_sgr_box3_h_8bpc_neon(int32_t *sumsq, int16_t *sum,
413*c0909341SAndroid Build Coastguard Worker//                                 const pixel (*left)[4],
414*c0909341SAndroid Build Coastguard Worker//                                 const pixel *src, const ptrdiff_t stride,
415*c0909341SAndroid Build Coastguard Worker//                                 const int w, const int h,
416*c0909341SAndroid Build Coastguard Worker//                                 const enum LrEdgeFlags edges);
417*c0909341SAndroid Build Coastguard Workerfunction sgr_box3_h_8bpc_neon, export=1
418*c0909341SAndroid Build Coastguard Worker        push            {r4-r11,lr}
419*c0909341SAndroid Build Coastguard Worker        vpush           {q4-q7}
420*c0909341SAndroid Build Coastguard Worker        ldrd            r4,  r5,  [sp, #100]
421*c0909341SAndroid Build Coastguard Worker        ldrd            r6,  r7,  [sp, #108]
422*c0909341SAndroid Build Coastguard Worker        add             r5,  r5,  #2 // w += 2
423*c0909341SAndroid Build Coastguard Worker
424*c0909341SAndroid Build Coastguard Worker        // Set up pointers for reading/writing alternate rows
425*c0909341SAndroid Build Coastguard Worker        add             r10, r0,  #(4*SUM_STRIDE)   // sumsq
426*c0909341SAndroid Build Coastguard Worker        add             r11, r1,  #(2*SUM_STRIDE)   // sum
427*c0909341SAndroid Build Coastguard Worker        add             r12, r3,  r4                // src
428*c0909341SAndroid Build Coastguard Worker        lsl             r4,  r4,  #1
429*c0909341SAndroid Build Coastguard Worker        mov             r9,       #(2*2*SUM_STRIDE) // double sum stride
430*c0909341SAndroid Build Coastguard Worker
431*c0909341SAndroid Build Coastguard Worker        // Subtract the aligned width from the output stride.
432*c0909341SAndroid Build Coastguard Worker        add             lr,  r5,  #7
433*c0909341SAndroid Build Coastguard Worker        bic             lr,  lr,  #7
434*c0909341SAndroid Build Coastguard Worker        sub             r9,  r9,  lr, lsl #1
435*c0909341SAndroid Build Coastguard Worker
436*c0909341SAndroid Build Coastguard Worker        // Store the width for the vertical loop
437*c0909341SAndroid Build Coastguard Worker        mov             r8,  r5
438*c0909341SAndroid Build Coastguard Worker
439*c0909341SAndroid Build Coastguard Worker        // Subtract the number of pixels read from the input from the stride
440*c0909341SAndroid Build Coastguard Worker        add             lr,  lr,  #8
441*c0909341SAndroid Build Coastguard Worker        sub             r4,  r4,  lr
442*c0909341SAndroid Build Coastguard Worker
443*c0909341SAndroid Build Coastguard Worker        // Set up the src pointers to include the left edge, for LR_HAVE_LEFT, left == NULL
444*c0909341SAndroid Build Coastguard Worker        tst             r7,  #1 // LR_HAVE_LEFT
445*c0909341SAndroid Build Coastguard Worker        beq             2f
446*c0909341SAndroid Build Coastguard Worker        // LR_HAVE_LEFT
447*c0909341SAndroid Build Coastguard Worker        cmp             r2,  #0
448*c0909341SAndroid Build Coastguard Worker        bne             0f
449*c0909341SAndroid Build Coastguard Worker        // left == NULL
450*c0909341SAndroid Build Coastguard Worker        sub             r3,  r3,  #2
451*c0909341SAndroid Build Coastguard Worker        sub             r12, r12, #2
452*c0909341SAndroid Build Coastguard Worker        b               1f
453*c0909341SAndroid Build Coastguard Worker0:      // LR_HAVE_LEFT, left != NULL
454*c0909341SAndroid Build Coastguard Worker2:      // !LR_HAVE_LEFT, increase the stride.
455*c0909341SAndroid Build Coastguard Worker        // For this case we don't read the left 2 pixels from the src pointer,
456*c0909341SAndroid Build Coastguard Worker        // but shift it as if we had done that.
457*c0909341SAndroid Build Coastguard Worker        add             r4,  r4,  #2
458*c0909341SAndroid Build Coastguard Worker
459*c0909341SAndroid Build Coastguard Worker
460*c0909341SAndroid Build Coastguard Worker1:      // Loop vertically
461*c0909341SAndroid Build Coastguard Worker        vld1.8          {q0}, [r3]!
462*c0909341SAndroid Build Coastguard Worker        vld1.8          {q4}, [r12]!
463*c0909341SAndroid Build Coastguard Worker
464*c0909341SAndroid Build Coastguard Worker        tst             r7,  #1 // LR_HAVE_LEFT
465*c0909341SAndroid Build Coastguard Worker        beq             0f
466*c0909341SAndroid Build Coastguard Worker        cmp             r2,  #0
467*c0909341SAndroid Build Coastguard Worker        beq             2f
468*c0909341SAndroid Build Coastguard Worker        // LR_HAVE_LEFT, left != NULL
469*c0909341SAndroid Build Coastguard Worker        vld1.32         {d3[]}, [r2]!
470*c0909341SAndroid Build Coastguard Worker        // Move r3/r12 back to account for the last 2 bytes we loaded earlier,
471*c0909341SAndroid Build Coastguard Worker        // which we'll shift out.
472*c0909341SAndroid Build Coastguard Worker        sub             r3,  r3,  #2
473*c0909341SAndroid Build Coastguard Worker        sub             r12, r12, #2
474*c0909341SAndroid Build Coastguard Worker        vld1.32         {d11[]}, [r2]!
475*c0909341SAndroid Build Coastguard Worker        vext.8          q0,  q1,  q0,  #14
476*c0909341SAndroid Build Coastguard Worker        vext.8          q4,  q5,  q4,  #14
477*c0909341SAndroid Build Coastguard Worker        b               2f
478*c0909341SAndroid Build Coastguard Worker0:
479*c0909341SAndroid Build Coastguard Worker        // !LR_HAVE_LEFT, fill q1 with the leftmost byte
480*c0909341SAndroid Build Coastguard Worker        // and shift q0 to have 2x the first byte at the front.
481*c0909341SAndroid Build Coastguard Worker        vdup.8          q1,  d0[0]
482*c0909341SAndroid Build Coastguard Worker        vdup.8          q5,  d8[0]
483*c0909341SAndroid Build Coastguard Worker        // Move r3 back to account for the last 2 bytes we loaded before,
484*c0909341SAndroid Build Coastguard Worker        // which we shifted out.
485*c0909341SAndroid Build Coastguard Worker        sub             r3,  r3,  #2
486*c0909341SAndroid Build Coastguard Worker        sub             r12, r12, #2
487*c0909341SAndroid Build Coastguard Worker        vext.8          q0,  q1,  q0,  #14
488*c0909341SAndroid Build Coastguard Worker        vext.8          q4,  q5,  q4,  #14
489*c0909341SAndroid Build Coastguard Worker
490*c0909341SAndroid Build Coastguard Worker2:
491*c0909341SAndroid Build Coastguard Worker        vmull.u8        q1,  d0,  d0
492*c0909341SAndroid Build Coastguard Worker        vmull.u8        q2,  d1,  d1
493*c0909341SAndroid Build Coastguard Worker        vmull.u8        q5,  d8,  d8
494*c0909341SAndroid Build Coastguard Worker        vmull.u8        q6,  d9,  d9
495*c0909341SAndroid Build Coastguard Worker
496*c0909341SAndroid Build Coastguard Worker        tst             r7,  #2 // LR_HAVE_RIGHT
497*c0909341SAndroid Build Coastguard Worker        bne             4f
498*c0909341SAndroid Build Coastguard Worker        // If we'll need to pad the right edge, load that byte to pad with
499*c0909341SAndroid Build Coastguard Worker        // here since we can find it pretty easily from here.
500*c0909341SAndroid Build Coastguard Worker        sub             lr,  r5,  #(2 + 16 - 2 + 1)
501*c0909341SAndroid Build Coastguard Worker        ldrb            r11, [r3,  lr]
502*c0909341SAndroid Build Coastguard Worker        ldrb            lr,  [r12, lr]
503*c0909341SAndroid Build Coastguard Worker        // Fill q14/q15 with the right padding pixel
504*c0909341SAndroid Build Coastguard Worker        vdup.8          q14, r11
505*c0909341SAndroid Build Coastguard Worker        vdup.8          q15, lr
506*c0909341SAndroid Build Coastguard Worker        // Restore r11 after using it for a temporary value
507*c0909341SAndroid Build Coastguard Worker        add             r11, r1,  #(2*SUM_STRIDE)
508*c0909341SAndroid Build Coastguard Worker3:      // !LR_HAVE_RIGHT
509*c0909341SAndroid Build Coastguard Worker
510*c0909341SAndroid Build Coastguard Worker        // Check whether we need to pad the right edge
511*c0909341SAndroid Build Coastguard Worker        cmp             r5,  #10
512*c0909341SAndroid Build Coastguard Worker        bge             4f   // If w >= 10, all used input pixels are valid
513*c0909341SAndroid Build Coastguard Worker
514*c0909341SAndroid Build Coastguard Worker        // 1 <= w < 10, w pixels valid in q0. For w=9, this ends up called
515*c0909341SAndroid Build Coastguard Worker        // again; it's not strictly needed in those cases (we pad enough here),
516*c0909341SAndroid Build Coastguard Worker        // but keeping the code as simple as possible.
517*c0909341SAndroid Build Coastguard Worker
518*c0909341SAndroid Build Coastguard Worker        // Insert padding in q0/4.b[w] onwards
519*c0909341SAndroid Build Coastguard Worker        movrel_local    lr,  right_ext_mask
520*c0909341SAndroid Build Coastguard Worker        sub             lr,  lr,  r5
521*c0909341SAndroid Build Coastguard Worker        vld1.8          {q13}, [lr]
522*c0909341SAndroid Build Coastguard Worker
523*c0909341SAndroid Build Coastguard Worker        vbit            q0,  q14, q13
524*c0909341SAndroid Build Coastguard Worker        vbit            q4,  q15, q13
525*c0909341SAndroid Build Coastguard Worker
526*c0909341SAndroid Build Coastguard Worker        // Update the precalculated squares
527*c0909341SAndroid Build Coastguard Worker        vmull.u8        q1,  d0,  d0
528*c0909341SAndroid Build Coastguard Worker        vmull.u8        q2,  d1,  d1
529*c0909341SAndroid Build Coastguard Worker        vmull.u8        q5,  d8,  d8
530*c0909341SAndroid Build Coastguard Worker        vmull.u8        q6,  d9,  d9
531*c0909341SAndroid Build Coastguard Worker
532*c0909341SAndroid Build Coastguard Worker4:      // Loop horizontally
533*c0909341SAndroid Build Coastguard Worker        vext.8          d16, d0,  d1,  #1
534*c0909341SAndroid Build Coastguard Worker        vext.8          d17, d0,  d1,  #2
535*c0909341SAndroid Build Coastguard Worker        vext.8          d18, d8,  d9,  #1
536*c0909341SAndroid Build Coastguard Worker        vext.8          d19, d8,  d9,  #2
537*c0909341SAndroid Build Coastguard Worker        vaddl.u8        q3,  d0,  d16
538*c0909341SAndroid Build Coastguard Worker        vaddw.u8        q3,  q3,  d17
539*c0909341SAndroid Build Coastguard Worker        vaddl.u8        q7,  d8,  d18
540*c0909341SAndroid Build Coastguard Worker        vaddw.u8        q7,  q7,  d19
541*c0909341SAndroid Build Coastguard Worker
542*c0909341SAndroid Build Coastguard Worker        vext.8          q8,  q1,  q2,  #2
543*c0909341SAndroid Build Coastguard Worker        vext.8          q9,  q1,  q2,  #4
544*c0909341SAndroid Build Coastguard Worker        vext.8          q10, q5,  q6,  #2
545*c0909341SAndroid Build Coastguard Worker        vext.8          q11, q5,  q6,  #4
546*c0909341SAndroid Build Coastguard Worker
547*c0909341SAndroid Build Coastguard Worker        vaddl.u16       q12, d2,  d16
548*c0909341SAndroid Build Coastguard Worker        vaddl.u16       q13, d3,  d17
549*c0909341SAndroid Build Coastguard Worker        vaddw.u16       q12, q12, d18
550*c0909341SAndroid Build Coastguard Worker        vaddw.u16       q13, q13, d19
551*c0909341SAndroid Build Coastguard Worker
552*c0909341SAndroid Build Coastguard Worker        vaddl.u16       q8,  d10, d20
553*c0909341SAndroid Build Coastguard Worker        vaddl.u16       q9,  d11, d21
554*c0909341SAndroid Build Coastguard Worker        vaddw.u16       q8,  q8,  d22
555*c0909341SAndroid Build Coastguard Worker        vaddw.u16       q9,  q9,  d23
556*c0909341SAndroid Build Coastguard Worker
557*c0909341SAndroid Build Coastguard Worker        subs            r5,  r5,  #8
558*c0909341SAndroid Build Coastguard Worker        vst1.16         {q3},       [r1,  :128]!
559*c0909341SAndroid Build Coastguard Worker        vst1.16         {q7},       [r11, :128]!
560*c0909341SAndroid Build Coastguard Worker        vst1.32         {q12, q13}, [r0,  :128]!
561*c0909341SAndroid Build Coastguard Worker        vst1.32         {q8,  q9},  [r10, :128]!
562*c0909341SAndroid Build Coastguard Worker
563*c0909341SAndroid Build Coastguard Worker        ble             9f
564*c0909341SAndroid Build Coastguard Worker        tst             r7,  #2 // LR_HAVE_RIGHT
565*c0909341SAndroid Build Coastguard Worker        vld1.8          {d6},  [r3]!
566*c0909341SAndroid Build Coastguard Worker        vld1.8          {d14}, [r12]!
567*c0909341SAndroid Build Coastguard Worker        vmov            q1,  q2
568*c0909341SAndroid Build Coastguard Worker        vmov            q5,  q6
569*c0909341SAndroid Build Coastguard Worker        vext.8          q0,  q0,  q3,  #8
570*c0909341SAndroid Build Coastguard Worker        vext.8          q4,  q4,  q7,  #8
571*c0909341SAndroid Build Coastguard Worker        vmull.u8        q2,  d6,  d6
572*c0909341SAndroid Build Coastguard Worker        vmull.u8        q6,  d14, d14
573*c0909341SAndroid Build Coastguard Worker
574*c0909341SAndroid Build Coastguard Worker        bne             4b // If we don't need to pad, just keep summing.
575*c0909341SAndroid Build Coastguard Worker        b               3b // If we need to pad, check how many pixels we have left.
576*c0909341SAndroid Build Coastguard Worker
577*c0909341SAndroid Build Coastguard Worker9:
578*c0909341SAndroid Build Coastguard Worker        subs            r6,  r6,  #2
579*c0909341SAndroid Build Coastguard Worker        ble             0f
580*c0909341SAndroid Build Coastguard Worker        // Jump to the next row and loop horizontally
581*c0909341SAndroid Build Coastguard Worker        add             r0,  r0,  r9, lsl #1
582*c0909341SAndroid Build Coastguard Worker        add             r10, r10, r9, lsl #1
583*c0909341SAndroid Build Coastguard Worker        add             r1,  r1,  r9
584*c0909341SAndroid Build Coastguard Worker        add             r11, r11, r9
585*c0909341SAndroid Build Coastguard Worker        add             r3,  r3,  r4
586*c0909341SAndroid Build Coastguard Worker        add             r12, r12, r4
587*c0909341SAndroid Build Coastguard Worker        mov             r5,  r8
588*c0909341SAndroid Build Coastguard Worker        b               1b
589*c0909341SAndroid Build Coastguard Worker0:
590*c0909341SAndroid Build Coastguard Worker        vpop            {q4-q7}
591*c0909341SAndroid Build Coastguard Worker        pop             {r4-r11,pc}
592*c0909341SAndroid Build Coastguard Workerendfunc
593*c0909341SAndroid Build Coastguard Worker
594*c0909341SAndroid Build Coastguard Worker// void dav1d_sgr_box5_h_8bpc_neon(int32_t *sumsq, int16_t *sum,
595*c0909341SAndroid Build Coastguard Worker//                                 const pixel (*left)[4],
596*c0909341SAndroid Build Coastguard Worker//                                 const pixel *src, const ptrdiff_t stride,
597*c0909341SAndroid Build Coastguard Worker//                                 const int w, const int h,
598*c0909341SAndroid Build Coastguard Worker//                                 const enum LrEdgeFlags edges);
599*c0909341SAndroid Build Coastguard Workerfunction sgr_box5_h_8bpc_neon, export=1
600*c0909341SAndroid Build Coastguard Worker        push            {r4-r11,lr}
601*c0909341SAndroid Build Coastguard Worker        vpush           {q4-q7}
602*c0909341SAndroid Build Coastguard Worker        ldrd            r4,  r5,  [sp, #100]
603*c0909341SAndroid Build Coastguard Worker        ldrd            r6,  r7,  [sp, #108]
604*c0909341SAndroid Build Coastguard Worker        add             r5,  r5,  #2 // w += 2
605*c0909341SAndroid Build Coastguard Worker
606*c0909341SAndroid Build Coastguard Worker        // Set up pointers for reading/writing alternate rows
607*c0909341SAndroid Build Coastguard Worker        add             r10, r0,  #(4*SUM_STRIDE)   // sumsq
608*c0909341SAndroid Build Coastguard Worker        add             r11, r1,  #(2*SUM_STRIDE)   // sum
609*c0909341SAndroid Build Coastguard Worker        add             r12, r3,  r4                // src
610*c0909341SAndroid Build Coastguard Worker        lsl             r4,  r4,  #1
611*c0909341SAndroid Build Coastguard Worker        mov             r9,       #(2*2*SUM_STRIDE) // double sum stride
612*c0909341SAndroid Build Coastguard Worker
613*c0909341SAndroid Build Coastguard Worker        // Subtract the aligned width from the output stride.
614*c0909341SAndroid Build Coastguard Worker        add             lr,  r5,  #7
615*c0909341SAndroid Build Coastguard Worker        bic             lr,  lr,  #7
616*c0909341SAndroid Build Coastguard Worker        sub             r9,  r9,  lr, lsl #1
617*c0909341SAndroid Build Coastguard Worker        add             lr,  lr,  #8
618*c0909341SAndroid Build Coastguard Worker        sub             r4,  r4,  lr
619*c0909341SAndroid Build Coastguard Worker
620*c0909341SAndroid Build Coastguard Worker        // Store the width for the vertical loop
621*c0909341SAndroid Build Coastguard Worker        mov             r8,  r5
622*c0909341SAndroid Build Coastguard Worker
623*c0909341SAndroid Build Coastguard Worker        // Set up the src pointers to include the left edge, for LR_HAVE_LEFT, left == NULL
624*c0909341SAndroid Build Coastguard Worker        tst             r7,  #1 // LR_HAVE_LEFT
625*c0909341SAndroid Build Coastguard Worker        beq             2f
626*c0909341SAndroid Build Coastguard Worker        // LR_HAVE_LEFT
627*c0909341SAndroid Build Coastguard Worker        cmp             r2,  #0
628*c0909341SAndroid Build Coastguard Worker        bne             0f
629*c0909341SAndroid Build Coastguard Worker        // left == NULL
630*c0909341SAndroid Build Coastguard Worker        sub             r3,  r3,  #3
631*c0909341SAndroid Build Coastguard Worker        sub             r12, r12, #3
632*c0909341SAndroid Build Coastguard Worker        b               1f
633*c0909341SAndroid Build Coastguard Worker0:      // LR_HAVE_LEFT, left != NULL
634*c0909341SAndroid Build Coastguard Worker2:      // !LR_HAVE_LEFT, increase the stride.
635*c0909341SAndroid Build Coastguard Worker        // For this case we don't read the left 3 pixels from the src pointer,
636*c0909341SAndroid Build Coastguard Worker        // but shift it as if we had done that.
637*c0909341SAndroid Build Coastguard Worker        add             r4,  r4,  #3
638*c0909341SAndroid Build Coastguard Worker
639*c0909341SAndroid Build Coastguard Worker1:      // Loop vertically
640*c0909341SAndroid Build Coastguard Worker        vld1.8          {q0}, [r3]!
641*c0909341SAndroid Build Coastguard Worker        vld1.8          {q4}, [r12]!
642*c0909341SAndroid Build Coastguard Worker
643*c0909341SAndroid Build Coastguard Worker        tst             r7,  #1 // LR_HAVE_LEFT
644*c0909341SAndroid Build Coastguard Worker        beq             0f
645*c0909341SAndroid Build Coastguard Worker        cmp             r2,  #0
646*c0909341SAndroid Build Coastguard Worker        beq             2f
647*c0909341SAndroid Build Coastguard Worker        // LR_HAVE_LEFT, left != NULL
648*c0909341SAndroid Build Coastguard Worker        vld1.32         {d3[]}, [r2]!
649*c0909341SAndroid Build Coastguard Worker        // Move r3/r12 back to account for the last 3 bytes we loaded earlier,
650*c0909341SAndroid Build Coastguard Worker        // which we'll shift out.
651*c0909341SAndroid Build Coastguard Worker        sub             r3,  r3,  #3
652*c0909341SAndroid Build Coastguard Worker        sub             r12, r12, #3
653*c0909341SAndroid Build Coastguard Worker        vld1.32         {d11[]}, [r2]!
654*c0909341SAndroid Build Coastguard Worker        vext.8          q0,  q1,  q0,  #13
655*c0909341SAndroid Build Coastguard Worker        vext.8          q4,  q5,  q4,  #13
656*c0909341SAndroid Build Coastguard Worker        b               2f
657*c0909341SAndroid Build Coastguard Worker0:
658*c0909341SAndroid Build Coastguard Worker        // !LR_HAVE_LEFT, fill q1 with the leftmost byte
659*c0909341SAndroid Build Coastguard Worker        // and shift q0 to have 3x the first byte at the front.
660*c0909341SAndroid Build Coastguard Worker        vdup.8          q1,  d0[0]
661*c0909341SAndroid Build Coastguard Worker        vdup.8          q5,  d8[0]
662*c0909341SAndroid Build Coastguard Worker        // Move r3 back to account for the last 3 bytes we loaded before,
663*c0909341SAndroid Build Coastguard Worker        // which we shifted out.
664*c0909341SAndroid Build Coastguard Worker        sub             r3,  r3,  #3
665*c0909341SAndroid Build Coastguard Worker        sub             r12, r12, #3
666*c0909341SAndroid Build Coastguard Worker        vext.8          q0,  q1,  q0,  #13
667*c0909341SAndroid Build Coastguard Worker        vext.8          q4,  q5,  q4,  #13
668*c0909341SAndroid Build Coastguard Worker
669*c0909341SAndroid Build Coastguard Worker2:
670*c0909341SAndroid Build Coastguard Worker        vmull.u8        q1,  d0,  d0
671*c0909341SAndroid Build Coastguard Worker        vmull.u8        q2,  d1,  d1
672*c0909341SAndroid Build Coastguard Worker        vmull.u8        q5,  d8,  d8
673*c0909341SAndroid Build Coastguard Worker        vmull.u8        q6,  d9,  d9
674*c0909341SAndroid Build Coastguard Worker
675*c0909341SAndroid Build Coastguard Worker        tst             r7,  #2 // LR_HAVE_RIGHT
676*c0909341SAndroid Build Coastguard Worker        bne             4f
677*c0909341SAndroid Build Coastguard Worker        // If we'll need to pad the right edge, load that byte to pad with
678*c0909341SAndroid Build Coastguard Worker        // here since we can find it pretty easily from here.
679*c0909341SAndroid Build Coastguard Worker        sub             lr,  r5,  #(2 + 16 - 3 + 1)
680*c0909341SAndroid Build Coastguard Worker        ldrb            r11, [r3,  lr]
681*c0909341SAndroid Build Coastguard Worker        ldrb            lr,  [r12, lr]
682*c0909341SAndroid Build Coastguard Worker        // Fill q14/q15 with the right padding pixel
683*c0909341SAndroid Build Coastguard Worker        vdup.8          q14, r11
684*c0909341SAndroid Build Coastguard Worker        vdup.8          q15, lr
685*c0909341SAndroid Build Coastguard Worker        // Restore r11 after using it for a temporary value
686*c0909341SAndroid Build Coastguard Worker        add             r11, r1,  #(2*SUM_STRIDE)
687*c0909341SAndroid Build Coastguard Worker3:      // !LR_HAVE_RIGHT
688*c0909341SAndroid Build Coastguard Worker
689*c0909341SAndroid Build Coastguard Worker        // Check whether we need to pad the right edge
690*c0909341SAndroid Build Coastguard Worker        cmp             r5,  #11
691*c0909341SAndroid Build Coastguard Worker        bge             4f   // If w >= 11, all used input pixels are valid
692*c0909341SAndroid Build Coastguard Worker
693*c0909341SAndroid Build Coastguard Worker        // 1 <= w < 11, w+1 pixels valid in q0. For w=9 or w=10,
694*c0909341SAndroid Build Coastguard Worker        // this ends up called again; it's not strictly needed in those
695*c0909341SAndroid Build Coastguard Worker        // cases (we pad enough here), but keeping the code as simple as possible.
696*c0909341SAndroid Build Coastguard Worker
697*c0909341SAndroid Build Coastguard Worker        // Insert padding in q0/4.b[w+1] onwards; fuse the +1 into the
698*c0909341SAndroid Build Coastguard Worker        // buffer pointer.
699*c0909341SAndroid Build Coastguard Worker        movrel_local    lr,  right_ext_mask, -1
700*c0909341SAndroid Build Coastguard Worker        sub             lr,  lr,  r5
701*c0909341SAndroid Build Coastguard Worker        vld1.8          {q13}, [lr]
702*c0909341SAndroid Build Coastguard Worker
703*c0909341SAndroid Build Coastguard Worker        vbit            q0,  q14, q13
704*c0909341SAndroid Build Coastguard Worker        vbit            q4,  q15, q13
705*c0909341SAndroid Build Coastguard Worker
706*c0909341SAndroid Build Coastguard Worker        // Update the precalculated squares
707*c0909341SAndroid Build Coastguard Worker        vmull.u8        q1,  d0,  d0
708*c0909341SAndroid Build Coastguard Worker        vmull.u8        q2,  d1,  d1
709*c0909341SAndroid Build Coastguard Worker        vmull.u8        q5,  d8,  d8
710*c0909341SAndroid Build Coastguard Worker        vmull.u8        q6,  d9,  d9
711*c0909341SAndroid Build Coastguard Worker
712*c0909341SAndroid Build Coastguard Worker4:      // Loop horizontally
713*c0909341SAndroid Build Coastguard Worker        vext.8          d16, d0,  d1,  #1
714*c0909341SAndroid Build Coastguard Worker        vext.8          d17, d0,  d1,  #2
715*c0909341SAndroid Build Coastguard Worker        vext.8          d18, d0,  d1,  #3
716*c0909341SAndroid Build Coastguard Worker        vext.8          d19, d0,  d1,  #4
717*c0909341SAndroid Build Coastguard Worker        vext.8          d20, d8,  d9,  #1
718*c0909341SAndroid Build Coastguard Worker        vext.8          d21, d8,  d9,  #2
719*c0909341SAndroid Build Coastguard Worker        vext.8          d22, d8,  d9,  #3
720*c0909341SAndroid Build Coastguard Worker        vext.8          d23, d8,  d9,  #4
721*c0909341SAndroid Build Coastguard Worker        vaddl.u8        q3,  d0,  d16
722*c0909341SAndroid Build Coastguard Worker        vaddl.u8        q12, d17, d18
723*c0909341SAndroid Build Coastguard Worker        vaddl.u8        q7,  d8,  d20
724*c0909341SAndroid Build Coastguard Worker        vaddl.u8        q13, d21, d22
725*c0909341SAndroid Build Coastguard Worker        vaddw.u8        q3,  q3,  d19
726*c0909341SAndroid Build Coastguard Worker        vaddw.u8        q7,  q7,  d23
727*c0909341SAndroid Build Coastguard Worker        vadd.u16        q3,  q3,  q12
728*c0909341SAndroid Build Coastguard Worker        vadd.u16        q7,  q7,  q13
729*c0909341SAndroid Build Coastguard Worker
730*c0909341SAndroid Build Coastguard Worker        vext.8          q8,  q1,  q2,  #2
731*c0909341SAndroid Build Coastguard Worker        vext.8          q9,  q1,  q2,  #4
732*c0909341SAndroid Build Coastguard Worker        vext.8          q10, q1,  q2,  #6
733*c0909341SAndroid Build Coastguard Worker        vext.8          q11, q1,  q2,  #8
734*c0909341SAndroid Build Coastguard Worker        vaddl.u16       q12, d2,  d16
735*c0909341SAndroid Build Coastguard Worker        vaddl.u16       q13, d3,  d17
736*c0909341SAndroid Build Coastguard Worker        vaddl.u16       q8,  d18, d20
737*c0909341SAndroid Build Coastguard Worker        vaddl.u16       q9,  d19, d21
738*c0909341SAndroid Build Coastguard Worker        vaddw.u16       q12, q12, d22
739*c0909341SAndroid Build Coastguard Worker        vaddw.u16       q13, q13, d23
740*c0909341SAndroid Build Coastguard Worker        vadd.i32        q12, q12, q8
741*c0909341SAndroid Build Coastguard Worker        vadd.i32        q13, q13, q9
742*c0909341SAndroid Build Coastguard Worker        vext.8          q8,  q5,  q6,  #2
743*c0909341SAndroid Build Coastguard Worker        vext.8          q9,  q5,  q6,  #4
744*c0909341SAndroid Build Coastguard Worker        vext.8          q10, q5,  q6,  #6
745*c0909341SAndroid Build Coastguard Worker        vext.8          q11, q5,  q6,  #8
746*c0909341SAndroid Build Coastguard Worker        vaddl.u16       q1,  d10, d16
747*c0909341SAndroid Build Coastguard Worker        vaddl.u16       q5,  d11, d17
748*c0909341SAndroid Build Coastguard Worker        vaddl.u16       q8,  d18, d20
749*c0909341SAndroid Build Coastguard Worker        vaddl.u16       q9,  d19, d21
750*c0909341SAndroid Build Coastguard Worker        vaddw.u16       q1,  q1,  d22
751*c0909341SAndroid Build Coastguard Worker        vaddw.u16       q5,  q5,  d23
752*c0909341SAndroid Build Coastguard Worker        vadd.i32        q10, q1,  q8
753*c0909341SAndroid Build Coastguard Worker        vadd.i32        q11, q5,  q9
754*c0909341SAndroid Build Coastguard Worker
755*c0909341SAndroid Build Coastguard Worker        subs            r5,  r5,  #8
756*c0909341SAndroid Build Coastguard Worker        vst1.16         {q3},       [r1,  :128]!
757*c0909341SAndroid Build Coastguard Worker        vst1.16         {q7},       [r11, :128]!
758*c0909341SAndroid Build Coastguard Worker        vst1.32         {q12, q13}, [r0,  :128]!
759*c0909341SAndroid Build Coastguard Worker        vst1.32         {q10, q11}, [r10, :128]!
760*c0909341SAndroid Build Coastguard Worker
761*c0909341SAndroid Build Coastguard Worker        ble             9f
762*c0909341SAndroid Build Coastguard Worker        tst             r7,  #2 // LR_HAVE_RIGHT
763*c0909341SAndroid Build Coastguard Worker        vld1.8          {d6},  [r3]!
764*c0909341SAndroid Build Coastguard Worker        vld1.8          {d14}, [r12]!
765*c0909341SAndroid Build Coastguard Worker        vmov            q1,  q2
766*c0909341SAndroid Build Coastguard Worker        vmov            q5,  q6
767*c0909341SAndroid Build Coastguard Worker        vext.8          q0,  q0,  q3,  #8
768*c0909341SAndroid Build Coastguard Worker        vext.8          q4,  q4,  q7,  #8
769*c0909341SAndroid Build Coastguard Worker        vmull.u8        q2,  d6,  d6
770*c0909341SAndroid Build Coastguard Worker        vmull.u8        q6,  d14, d14
771*c0909341SAndroid Build Coastguard Worker        bne             4b // If we don't need to pad, just keep summing.
772*c0909341SAndroid Build Coastguard Worker        b               3b // If we need to pad, check how many pixels we have left.
773*c0909341SAndroid Build Coastguard Worker
774*c0909341SAndroid Build Coastguard Worker9:
775*c0909341SAndroid Build Coastguard Worker        subs            r6,  r6,  #2
776*c0909341SAndroid Build Coastguard Worker        ble             0f
777*c0909341SAndroid Build Coastguard Worker        // Jump to the next row and loop horizontally
778*c0909341SAndroid Build Coastguard Worker        add             r0,  r0,  r9, lsl #1
779*c0909341SAndroid Build Coastguard Worker        add             r10, r10, r9, lsl #1
780*c0909341SAndroid Build Coastguard Worker        add             r1,  r1,  r9
781*c0909341SAndroid Build Coastguard Worker        add             r11, r11, r9
782*c0909341SAndroid Build Coastguard Worker        add             r3,  r3,  r4
783*c0909341SAndroid Build Coastguard Worker        add             r12, r12, r4
784*c0909341SAndroid Build Coastguard Worker        mov             r5,  r8
785*c0909341SAndroid Build Coastguard Worker        b               1b
786*c0909341SAndroid Build Coastguard Worker0:
787*c0909341SAndroid Build Coastguard Worker        vpop            {q4-q7}
788*c0909341SAndroid Build Coastguard Worker        pop             {r4-r11,pc}
789*c0909341SAndroid Build Coastguard Workerendfunc
790*c0909341SAndroid Build Coastguard Worker
791*c0909341SAndroid Build Coastguard Workersgr_funcs 8
792