]> git.sesse.net Git - x264/blob - common/aarch64/predict-a.S
aarch64: NEON asm for 8x16c intra prediction
[x264] / common / aarch64 / predict-a.S
1 /*****************************************************************************
2  * predict.S: aarch64 intra prediction
3  *****************************************************************************
4  * Copyright (C) 2009-2014 x264 project
5  *
6  * Authors: David Conrad <lessen42@gmail.com>
7  *          Mans Rullgard <mans@mansr.com>
8  *          Janne Grunau <janne-x264@jannau.net>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
23  *
24  * This program is also available under a commercial proprietary license.
25  * For more information, contact us at licensing@x264.com.
26  *****************************************************************************/
27
28 #include "asm.S"
29
30 const p8weight, align=4
31     .short      1, 2, 3, 4, 1, 2, 3, 4
32 endconst
33 const p16weight, align=4
34     .short      1, 2, 3, 4, 5, 6, 7, 8
35 endconst
36
37 .macro ldcol.8  vd,  xn,  xm,  n=8,  hi=0
38 .if \n == 8 || \hi == 0
39     ld1        {\vd\().b}[0], [\xn], \xm
40     ld1        {\vd\().b}[1], [\xn], \xm
41     ld1        {\vd\().b}[2], [\xn], \xm
42     ld1        {\vd\().b}[3], [\xn], \xm
43 .endif
44 .if \n == 8 || \hi == 1
45     ld1        {\vd\().b}[4], [\xn], \xm
46     ld1        {\vd\().b}[5], [\xn], \xm
47     ld1        {\vd\().b}[6], [\xn], \xm
48     ld1        {\vd\().b}[7], [\xn], \xm
49 .endif
50 .endm
51
52 .macro ldcol.16  vd,  xn,  xm
53     ldcol.8     \vd, \xn, \xm
54     ld1        {\vd\().b}[ 8], [\xn], \xm
55     ld1        {\vd\().b}[ 9], [\xn], \xm
56     ld1        {\vd\().b}[10], [\xn], \xm
57     ld1        {\vd\().b}[11], [\xn], \xm
58     ld1        {\vd\().b}[12], [\xn], \xm
59     ld1        {\vd\().b}[13], [\xn], \xm
60     ld1        {\vd\().b}[14], [\xn], \xm
61     ld1        {\vd\().b}[15], [\xn], \xm
62 .endm
63
64
65 function x264_predict_4x4_h_aarch64, export=1
66     ldrb    w1, [x0, #0*FDEC_STRIDE-1]
67     ldrb    w2, [x0, #1*FDEC_STRIDE-1]
68     ldrb    w3, [x0, #2*FDEC_STRIDE-1]
69     ldrb    w4, [x0, #3*FDEC_STRIDE-1]
70     add     w1, w1, w1, lsl #8
71     add     w2, w2, w2, lsl #8
72     add     w3, w3, w3, lsl #8
73     add     w4, w4, w4, lsl #8
74     add     w1, w1, w1, lsl #16
75     str     w1, [x0, #0*FDEC_STRIDE]
76     add     w2, w2, w2, lsl #16
77     str     w2, [x0, #1*FDEC_STRIDE]
78     add     w3, w3, w3, lsl #16
79     str     w3, [x0, #2*FDEC_STRIDE]
80     add     w4, w4, w4, lsl #16
81     str     w4, [x0, #3*FDEC_STRIDE]
82     ret
83 endfunc
84
85 function x264_predict_4x4_v_aarch64, export=1
86     ldr     w1,  [x0, #0 - 1 * FDEC_STRIDE]
87     str     w1,  [x0, #0 + 0 * FDEC_STRIDE]
88     str     w1,  [x0, #0 + 1 * FDEC_STRIDE]
89     str     w1,  [x0, #0 + 2 * FDEC_STRIDE]
90     str     w1,  [x0, #0 + 3 * FDEC_STRIDE]
91     ret
92 endfunc
93
94 function x264_predict_4x4_dc_neon, export=1
95     sub         x1,  x0,  #FDEC_STRIDE
96     sub         x2,  x0,  #1
97     mov         x7,  #FDEC_STRIDE
98     ld1        {v0.8b}, [x1]
99     ld1r       {v1.8b}, [x2], x7
100     ld1r       {v2.8b}, [x2], x7
101     ld1r       {v3.8b}, [x2], x7
102     ld1r       {v4.8b}, [x2], x7
103     uaddlp      v0.4h,  v0.8b
104     uaddl       v1.8h,  v1.8b,  v2.8b
105     uaddl       v2.8h,  v3.8b,  v4.8b
106     addp        v0.4h,  v0.4h,  v0.4h
107     add         v1.4h,  v1.4h,  v2.4h
108     dup         v0.4h,  v0.h[0]
109     add         v0.4h,  v0.4h,  v1.4h
110     rshrn       v0.8b,  v0.8h,  #3
111     str         s0,  [x0], #FDEC_STRIDE
112     str         s0,  [x0], #FDEC_STRIDE
113     str         s0,  [x0], #FDEC_STRIDE
114     str         s0,  [x0]
115     ret
116 endfunc
117
118 function x264_predict_4x4_dc_top_neon, export=1
119     sub         x1,  x0,  #FDEC_STRIDE
120     mov         x7,  #FDEC_STRIDE
121     ld1        {v0.8b}, [x1]
122     uaddlp      v0.4h,  v0.8b
123     addp        v0.4h,  v0.4h,  v0.4h
124     dup         v0.4h,  v0.h[0]
125     rshrn       v0.8b,  v0.8h,  #2
126     str         s0,  [x0], #FDEC_STRIDE
127     str         s0,  [x0], #FDEC_STRIDE
128     str         s0,  [x0], #FDEC_STRIDE
129     str         s0,  [x0]
130     ret
131 endfunc
132
133 function x264_predict_4x4_ddr_neon, export=1
134     sub         x1,  x0,  #FDEC_STRIDE+1
135     mov         x7,  #FDEC_STRIDE
136     ld1        {v0.8b}, [x1], x7            // # -FDEC_STRIDE-1
137     ld1r       {v1.8b}, [x1], x7            // #0*FDEC_STRIDE-1
138     ld1r       {v2.8b}, [x1], x7            // #1*FDEC_STRIDE-1
139     ext         v0.8b,  v1.8b,  v0.8b,  #7
140     ld1r       {v3.8b}, [x1], x7            // #2*FDEC_STRIDE-1
141     ext         v0.8b,  v2.8b,  v0.8b,  #7  // a
142     ld1r       {v4.8b}, [x1], x7            // #3*FDEC_STRIDE-1
143     ext         v1.8b,  v3.8b,  v0.8b,  #7  // b
144     ext         v2.8b,  v4.8b,  v1.8b,  #7  // c
145     uaddl       v0.8h,  v0.8b,  v1.8b
146     uaddl       v1.8h,  v1.8b,  v2.8b
147     add         v0.8h,  v0.8h,  v1.8h
148     rshrn       v0.8b,  v0.8h,  #2
149
150     ext         v3.8b,  v0.8b, v0.8b,  #3
151     ext         v2.8b,  v0.8b, v0.8b,  #2
152     ext         v1.8b,  v0.8b, v0.8b,  #1
153
154     str         s3,  [x0], #FDEC_STRIDE
155     str         s2,  [x0], #FDEC_STRIDE
156     str         s1,  [x0], #FDEC_STRIDE
157     str         s0,  [x0]
158     ret
159 endfunc
160
161 function x264_predict_4x4_ddl_neon, export=1
162     sub         x0,  x0,  #FDEC_STRIDE
163     mov         x7,  #FDEC_STRIDE
164     ld1        {v0.8b}, [x0],  x7
165     dup         v3.8b,  v0.b[7]
166     ext         v1.8b,  v0.8b,  v0.8b,  #1
167     ext         v2.8b,  v0.8b,  v3.8b,  #2
168     uhadd       v0.8b,  v0.8b,  v2.8b
169     urhadd      v0.8b,  v0.8b,  v1.8b
170     str         s0,  [x0], #FDEC_STRIDE
171     ext         v1.8b,  v0.8b,  v0.8b,  #1
172     ext         v2.8b,  v0.8b,  v0.8b,  #2
173     str         s1,  [x0], #FDEC_STRIDE
174     ext         v3.8b,  v0.8b,  v0.8b,  #3
175     str         s2,  [x0], #FDEC_STRIDE
176     str         s3,  [x0]
177     ret
178 endfunc
179
180 function x264_predict_8x8_dc_neon, export=1
181     mov         x7,  #FDEC_STRIDE
182     ld1        {v0.16b}, [x1], #16
183     ld1        {v1.8b},  [x1]
184     ext         v0.16b, v0.16b, v0.16b, #7
185     uaddlv      h1,  v1.8b
186     uaddlv      h0,  v0.8b
187     add         v0.8h,  v0.8h,  v1.8h
188     dup         v0.8h,  v0.h[0]
189     rshrn       v0.8b,  v0.8h,  #4
190 .rept 8
191     st1        {v0.8b}, [x0], x7
192 .endr
193     ret
194 endfunc
195
196 function x264_predict_8x8_h_neon, export=1
197     mov         x7,  #FDEC_STRIDE
198     ld1        {v16.16b}, [x1]
199     dup         v0.8b, v16.b[14]
200     dup         v1.8b, v16.b[13]
201     st1        {v0.8b}, [x0], x7
202     dup         v2.8b, v16.b[12]
203     st1        {v1.8b}, [x0], x7
204     dup         v3.8b, v16.b[11]
205     st1        {v2.8b}, [x0], x7
206     dup         v4.8b, v16.b[10]
207     st1        {v3.8b}, [x0], x7
208     dup         v5.8b, v16.b[9]
209     st1        {v4.8b}, [x0], x7
210     dup         v6.8b, v16.b[8]
211     st1        {v5.8b}, [x0], x7
212     dup         v7.8b, v16.b[7]
213     st1        {v6.8b}, [x0], x7
214     st1        {v7.8b}, [x0], x7
215     ret
216 endfunc
217
218 function x264_predict_8x8_v_neon, export=1
219     add         x1,  x1,  #16
220     mov         x7,  #FDEC_STRIDE
221     ld1        {v0.8b}, [x1]
222 .rept 8
223     st1        {v0.8b}, [x0], x7
224 .endr
225     ret
226 endfunc
227
228 function x264_predict_8x8_ddl_neon, export=1
229     add         x1,  x1,  #16
230     mov         x7,  #FDEC_STRIDE
231     ld1        {v0.16b}, [x1]
232     movi        v3.16b, #0
233     dup         v2.16b, v0.b[15]
234     ext         v4.16b, v3.16b, v0.16b, #15
235     ext         v2.16b, v0.16b, v2.16b, #1
236     uhadd       v4.16b, v4.16b, v2.16b
237     urhadd      v0.16b, v0.16b, v4.16b
238     ext         v1.16b, v0.16b, v0.16b, #1
239     ext         v2.16b, v0.16b, v0.16b, #2
240     st1        {v1.8b}, [x0], x7
241     ext         v3.16b, v0.16b, v0.16b, #3
242     st1        {v2.8b}, [x0], x7
243     ext         v4.16b, v0.16b, v0.16b, #4
244     st1        {v3.8b}, [x0], x7
245     ext         v5.16b, v0.16b, v0.16b, #5
246     st1        {v4.8b}, [x0], x7
247     ext         v6.16b, v0.16b, v0.16b, #6
248     st1        {v5.8b}, [x0], x7
249     ext         v7.16b, v0.16b, v0.16b, #7
250     st1        {v6.8b}, [x0], x7
251     ext         v0.16b, v0.16b, v0.16b, #8
252     st1        {v7.8b}, [x0], x7
253     st1        {v0.8b}, [x0], x7
254     ret
255 endfunc
256
257 function x264_predict_8x8_ddr_neon, export=1
258     ld1        {v0.16b,v1.16b}, [x1]
259     ext         v2.16b, v0.16b, v1.16b, #7
260     ext         v4.16b, v0.16b, v1.16b, #9
261     ext         v3.16b, v0.16b, v1.16b, #8
262
263     uhadd       v2.16b, v2.16b, v4.16b
264     urhadd      v7.16b, v3.16b, v2.16b
265
266     add         x0,  x0,  #7*FDEC_STRIDE
267     mov         x7,  #-1*FDEC_STRIDE
268
269     ext         v6.16b, v7.16b, v7.16b, #1
270     st1        {v7.8b},  [x0], x7
271     ext         v5.16b, v7.16b, v7.16b, #2
272     st1        {v6.8b},  [x0], x7
273     ext         v4.16b, v7.16b, v7.16b, #3
274     st1        {v5.8b},  [x0], x7
275     ext         v3.16b, v7.16b, v7.16b, #4
276     st1        {v4.8b},  [x0], x7
277     ext         v2.16b, v7.16b, v7.16b, #5
278     st1        {v3.8b},  [x0], x7
279     ext         v1.16b, v7.16b, v7.16b, #6
280     st1        {v2.8b},  [x0], x7
281     ext         v0.16b, v7.16b, v7.16b, #7
282     st1        {v1.8b},  [x0], x7
283     st1        {v0.8b},  [x0], x7
284     ret
285 endfunc
286
287 function x264_predict_8x8_vl_neon, export=1
288     add         x1,  x1,  #16
289     mov         x7, #FDEC_STRIDE
290
291     ld1        {v0.16b}, [x1]
292     ext         v1.16b, v1.16b, v0.16b, #15
293     ext         v2.16b, v0.16b, v2.16b, #1
294
295     uhadd       v1.16b, v1.16b, v2.16b
296     urhadd      v3.16b, v0.16b, v2.16b
297
298     urhadd      v0.16b, v0.16b, v1.16b
299
300     ext        v4.16b, v0.16b, v0.16b, #1
301     st1        {v3.8b}, [x0], x7
302     ext        v5.16b, v3.16b, v3.16b, #1
303     st1        {v4.8b}, [x0], x7
304     ext        v6.16b, v0.16b, v0.16b, #2
305     st1        {v5.8b}, [x0], x7
306     ext        v7.16b, v3.16b, v3.16b, #2
307     st1        {v6.8b}, [x0], x7
308     ext        v4.16b, v0.16b, v0.16b, #3
309     st1        {v7.8b}, [x0], x7
310     ext        v5.16b, v3.16b, v3.16b, #3
311     st1        {v4.8b}, [x0], x7
312     ext        v6.16b, v0.16b, v0.16b, #4
313     st1        {v5.8b}, [x0], x7
314     st1        {v6.8b}, [x0], x7
315     ret
316 endfunc
317
318 function x264_predict_8x8_vr_neon, export=1
319     add         x1,  x1,  #8
320     mov         x7,  #FDEC_STRIDE
321     ld1        {v2.16b}, [x1]
322
323     ext         v1.16b, v2.16b, v2.16b, #14
324     ext         v0.16b, v2.16b, v2.16b, #15
325
326     uhadd       v3.16b, v2.16b, v1.16b
327     urhadd      v2.16b, v2.16b, v0.16b
328     urhadd      v0.16b, v0.16b, v3.16b
329
330     ext         v1.16b, v2.16b, v2.16b, #8
331     uzp1        v2.8b,  v0.8b,  v0.8b
332     uzp2        v3.8b,  v0.8b,  v0.8b
333     ext         v0.16b, v0.16b, v0.16b, #8
334
335     st1        {v1.8b}, [x0], x7
336     st1        {v0.8b}, [x0], x7
337     ext         v4.8b, v3.8b, v1.8b, #7
338     ext         v5.8b, v2.8b, v0.8b, #7
339     st1        {v4.8b}, [x0], x7
340     st1        {v5.8b}, [x0], x7
341     ext         v6.8b, v3.8b, v1.8b, #6
342     ext         v7.8b, v2.8b, v0.8b, #6
343     st1        {v6.8b}, [x0], x7
344     st1        {v7.8b}, [x0], x7
345     ext         v1.8b, v3.8b, v1.8b, #5
346     ext         v0.8b, v2.8b, v0.8b, #5
347     st1        {v1.8b}, [x0], x7
348     st1        {v0.8b}, [x0], x7
349     ret
350 endfunc
351
352 function x264_predict_8x8_hd_neon, export=1
353     add         x1,  x1,  #7
354     mov         x7, #FDEC_STRIDE
355
356     ld1        {v1.16b}, [x1]
357     ext         v3.16b, v1.16b, v1.16b, #1
358     ext         v2.16b, v1.16b, v1.16b, #2
359
360     urhadd      v4.16b, v1.16b, v3.16b
361
362     uhadd       v1.16b, v1.16b, v2.16b
363     urhadd      v0.16b, v1.16b, v3.16b
364
365     zip1        v16.8b, v4.8b,  v0.8b
366     zip2        v17.8b, v4.8b,  v0.8b
367     ext         v7.16b, v0.16b, v0.16b, #8
368
369     ext         v0.8b,  v17.8b, v7.8b,  #6
370     ext         v1.8b,  v17.8b, v7.8b,  #4
371     st1        {v0.8b},  [x0], x7
372     ext         v2.8b,  v17.8b, v7.8b,  #2
373     st1        {v1.8b},  [x0], x7
374     st1        {v2.8b},  [x0], x7
375     ext         v3.8b,  v16.8b, v17.8b, #6
376     st1        {v17.8b}, [x0], x7
377     ext         v4.8b,  v16.8b, v17.8b, #4
378     st1        {v3.8b},  [x0], x7
379     ext         v5.8b,  v16.8b, v17.8b, #2
380     st1        {v4.8b},  [x0], x7
381     st1        {v5.8b},  [x0], x7
382     st1        {v16.8b}, [x0], x7
383
384     ret
385 endfunc
386
387 function x264_predict_8x8_hu_neon, export=1
388     add         x1,  x1,  #7
389     mov         x7,  #FDEC_STRIDE
390     ld1        {v7.8b}, [x1]
391     dup         v6.8b,  v7.b[0]
392     rev64       v7.8b,  v7.8b
393
394     ext         v4.8b,  v7.8b,  v6.8b,  #2
395     ext         v2.8b,  v7.8b,  v6.8b,  #1
396
397     uhadd       v5.8b,  v7.8b,  v4.8b
398     urhadd      v0.8b,  v2.8b,  v7.8b
399     urhadd      v1.8b,  v5.8b,  v2.8b
400
401     zip1        v16.8b, v0.8b,  v1.8b
402     zip2        v17.8b, v0.8b,  v1.8b
403
404     dup         v18.4h, v17.h[3]
405
406     ext         v0.8b,  v16.8b, v17.8b, #2
407     ext         v1.8b,  v16.8b, v17.8b, #4
408     ext         v2.8b,  v16.8b, v17.8b, #6
409     st1        {v16.8b}, [x0], x7
410     st1        {v0.8b},  [x0], x7
411     st1        {v1.8b},  [x0], x7
412     st1        {v2.8b},  [x0], x7
413
414     ext         v4.8b,  v17.8b, v18.8b, #2
415     ext         v5.8b,  v17.8b, v18.8b, #4
416     ext         v6.8b,  v17.8b, v18.8b, #6
417     st1        {v17.8b}, [x0], x7
418     st1        {v4.8b},  [x0], x7
419     st1        {v5.8b},  [x0], x7
420     st1        {v6.8b},  [x0]
421     ret
422 endfunc
423
424
425 function x264_predict_8x8c_dc_top_neon, export=1
426     sub         x2,  x0,  #FDEC_STRIDE
427     mov         x1,  #FDEC_STRIDE
428     ld1        {v0.8b},  [x2]
429     uaddlp      v0.4h,  v0.8b
430     addp        v0.4h,  v0.4h,  v0.4h
431     rshrn       v0.8b,  v0.8h,  #2
432     dup         v3.8b,  v0.b[1]
433     dup         v2.8b,  v0.b[0]
434     transpose   v0.2s,  v1.2s,  v2.2s,  v3.2s
435     b           pred8x8c_dc_end
436 endfunc
437
438 function x264_predict_8x8c_dc_left_neon, export=1
439     ldrb        w2,  [x0, #0 * FDEC_STRIDE - 1]
440     ldrb        w3,  [x0, #1 * FDEC_STRIDE - 1]
441     ldrb        w4,  [x0, #2 * FDEC_STRIDE - 1]
442     ldrb        w5,  [x0, #3 * FDEC_STRIDE - 1]
443     mov         x1,  #FDEC_STRIDE
444     add         w2,  w2,  w3
445     add         w3,  w4,  w5
446     ldrb        w6,  [x0, #4 * FDEC_STRIDE - 1]
447     ldrb        w7,  [x0, #5 * FDEC_STRIDE - 1]
448     ldrb        w8,  [x0, #6 * FDEC_STRIDE - 1]
449     ldrb        w9,  [x0, #7 * FDEC_STRIDE - 1]
450     add         w6,  w6,  w7
451     add         w7,  w8,  w9
452     add         w2,  w2,  w3
453     add         w6,  w6,  w7
454     dup         v0.8h,  w2
455     dup         v1.8h,  w6
456     rshrn       v0.8b,  v0.8h,  #2
457     rshrn       v1.8b,  v1.8h,  #2
458     b           pred8x8c_dc_end
459 endfunc
460
461 function x264_predict_8x8c_dc_neon, export=1
462     sub         x2,  x0,  #FDEC_STRIDE
463     sub         x3,  x0,  #1
464     mov         x1,  #FDEC_STRIDE
465     ld1        {v2.8b},  [x2]
466     ldcol.8     v3,  x3,  x1
467     transpose   v0.2s,  v1.2s,  v2.2s,  v3.2s
468     uaddlp      v0.4h,  v0.8b  // s0, s2
469     uaddlp      v1.4h,  v1.8b  // s1, s3
470     addp        v0.4h,  v0.4h,  v1.4h // s0, s2, s1, s3
471     addp        v1.4h,  v0.4h,  v0.4h
472     rshrn       v2.8b,  v0.8h,  #2
473     rshrn       v3.8b,  v1.8h,  #3
474     dup         v5.8b,  v2.b[2]  // dc1
475     dup         v6.8b,  v3.b[1]  // dc2
476     dup         v4.8b,  v3.b[0]  // dc0
477     dup         v7.8b,  v2.b[3]  // dc3
478     trn1        v0.2s,  v4.2s,  v5.2s
479     trn1        v1.2s,  v7.2s,  v6.2s
480 pred8x8c_dc_end:
481     add         x2,  x0,  x1,  lsl #2
482 .rept 4
483     st1        {v0.8b}, [x0], x1
484     st1        {v1.8b}, [x2], x1
485 .endr
486     ret
487 endfunc
488
489 function x264_predict_8x8c_h_neon, export=1
490     sub         x1,  x0,  #1
491     mov         x7,  #FDEC_STRIDE
492 .rept 4
493     ld1r       {v0.8b}, [x1], x7
494     ld1r       {v1.8b}, [x1], x7
495     st1        {v0.8b}, [x0], x7
496     st1        {v1.8b}, [x0], x7
497 .endr
498     ret
499 endfunc
500
501 function x264_predict_8x8c_v_neon, export=1
502     sub         x0,  x0,  #FDEC_STRIDE
503     mov         x7,  #FDEC_STRIDE
504     ld1        {v0.8b}, [x0], x7
505 .rept 8
506     st1        {v0.8b}, [x0], x7
507 .endr
508     ret
509 endfunc
510
511 function x264_predict_8x8c_p_neon, export=1
512     sub         x3,  x0,  #FDEC_STRIDE
513     mov         x1,  #FDEC_STRIDE
514     add         x2,  x3,  #4
515     sub         x3,  x3,  #1
516     ld1        {v0.s}[0], [x3]
517     ld1        {v2.s}[0], [x2], x1
518     ldcol.8     v0,  x3,  x1,  4,  hi=1
519     add         x3,  x3,  x1
520     ldcol.8     v3,  x3,  x1,  4
521     movrel      x4,  p8weight
522     movrel      x5,  p16weight
523     uaddl       v4.8h,  v2.8b,  v3.8b
524     rev32       v0.8b,  v0.8b
525     trn1        v2.2s,  v2.2s,  v3.2s
526     ld1        {v7.8h}, [x4]
527     usubl       v2.8h,  v2.8b,  v0.8b
528     mul         v2.8h,  v2.8h,  v7.8h
529     ld1        {v0.8h}, [x5]
530     saddlp      v2.4s,  v2.8h
531     addp        v2.4s,  v2.4s,  v2.4s
532     shl         v3.2s,  v2.2s,  #4
533     add         v2.2s,  v2.2s,  v3.2s
534     rshrn       v5.4h,  v2.4s,  #5    // b, c, x, x
535     addp        v2.4h,  v5.4h,  v5.4h
536     shl         v3.4h,  v2.4h,  #2
537     sub         v3.4h,  v3.4h,  v2.4h // 3 * (b + c)
538     rev64       v4.4h,  v4.4h
539     add         v4.4h,  v4.4h,  v0.4h
540     shl         v2.4h,  v4.4h,  #4              // a
541     sub         v2.4h,  v2.4h,  v3.4h           // a - 3 * (b + c) + 16
542     ext         v0.16b, v0.16b, v0.16b, #14
543     sub         v6.4h,  v5.4h,  v3.4h
544     mov         v0.h[0],  wzr
545     mul         v0.8h,  v0.8h,  v5.h[0]         // 0,1,2,3,4,5,6,7 * b
546     dup         v1.8h,  v2.h[0]                 // pix
547     dup         v2.8h,  v5.h[1]                 // c
548     add         v1.8h,  v1.8h,  v0.8h           // pix + x*b
549     mov         x3,  #8
550 1:
551     subs        x3,  x3,  #1
552     sqshrun     v0.8b,  v1.8h,  #5
553     add         v1.8h,  v1.8h,  v2.8h
554     st1        {v0.8b}, [x0], x1
555     b.ne        1b
556     ret
557 endfunc
558
559
560 .macro loadsum4 wd, t1, t2, t3, x, idx
561     ldrb        \wd,  [\x, #(\idx + 0) * FDEC_STRIDE - 1]
562     ldrb        \t1,  [\x, #(\idx + 1) * FDEC_STRIDE - 1]
563     ldrb        \t2,  [\x, #(\idx + 2) * FDEC_STRIDE - 1]
564     ldrb        \t3,  [\x, #(\idx + 3) * FDEC_STRIDE - 1]
565     add         \wd,  \wd,  \t1
566     add         \t1,  \t2,  \t3
567     add         \wd,  \wd,  \t1
568 .endm
569
570 function x264_predict_8x16c_h_neon, export=1
571     sub         x2,  x0,  #1
572     add         x3,  x0,  #FDEC_STRIDE - 1
573     mov         x7,  #2 * FDEC_STRIDE
574     add         x1,  x0,  #FDEC_STRIDE
575 .rept 4
576     ld1r       {v0.8b}, [x2], x7
577     ld1r       {v1.8b}, [x3], x7
578     ld1r       {v2.8b}, [x2], x7
579     ld1r       {v3.8b}, [x3], x7
580     st1        {v0.8b}, [x0], x7
581     st1        {v1.8b}, [x1], x7
582     st1        {v2.8b}, [x0], x7
583     st1        {v3.8b}, [x1], x7
584 .endr
585     ret
586 endfunc
587
588 function x264_predict_8x16c_v_neon, export=1
589     sub         x1,  x0,  #FDEC_STRIDE
590     mov         x2,  #2 * FDEC_STRIDE
591     ld1        {v0.8b}, [x1], x2
592 .rept 8
593     st1        {v0.8b}, [x0], x2
594     st1        {v0.8b}, [x1], x2
595 .endr
596     ret
597 endfunc
598
599 function x264_predict_8x16c_p_neon, export=1
600     movrel      x4,  p16weight
601     ld1        {v17.8h}, [x4]
602     sub         x3,  x0,  #FDEC_STRIDE
603     mov         x1,  #FDEC_STRIDE
604     add         x2,  x3,  #4
605     sub         x3,  x3,  #1
606
607     ld1        {v0.8b}, [x3]
608     ld1        {v2.8b}, [x2], x1
609     ldcol.8     v1,  x3,  x1
610     add         x3,  x3,  x1
611     ldcol.8     v3,  x3,  x1
612     ext         v4.8b,  v2.8b,  v2.8b,  #3
613     ext         v5.8b,  v3.8b,  v3.8b,  #7
614     rev32       v0.8b,  v0.8b
615     rev64       v1.8b,  v1.8b
616
617     uaddl       v4.8h,  v5.8b,  v4.8b // a * 1/16
618
619     usubl       v2.8h,  v2.8b,  v0.8b
620     mul         v2.8h,  v2.8h,  v17.8h
621     saddlp      v2.4s,  v2.8h
622     addp        v2.4s,  v2.4s,  v2.4s  // H
623
624     usubl       v3.8h,  v3.8b,  v1.8b
625     mul         v3.8h,  v3.8h,  v17.8h
626     saddlp      v3.4s,  v3.8h
627     addp        v3.4s,  v3.4s,  v3.4s
628     addp        v3.4s,  v3.4s,  v3.4s  // V
629
630     ext         v17.16b, v17.16b, v17.16b, #14
631
632     shl         v4.4h,  v4.4h,  #4     // a
633     shl         v6.2s,  v2.2s,  #4     // 16 * H
634     shl         v7.2s,  v3.2s,  #2     // 4 * V
635     add         v2.2s,  v2.2s,  v6.2s  // 17 * H
636     add         v3.2s,  v3.2s,  v7.2s  // 5 * V
637     rshrn       v2.4h,  v2.4s,  #5     // b
638     rshrn       v3.4h,  v3.4s,  #6     // c
639
640     mov         v17.h[0],  wzr
641
642     sub         v4.4h,  v4.4h,  v2.4h  // a - b
643     shl         v6.4h,  v2.4h,  #1     // 2 * b
644     add         v4.4h,  v4.4h,  v3.4h  // a - b + c
645     shl         v7.4h,  v3.4h,  #3     // 8 * c
646     sub         v4.4h,  v4.4h,  v6.4h  // a - 3b + c
647     sub         v4.4h,  v4.4h,  v7.4h  // a - 3b - 7c
648
649     mul         v0.8h,  v17.8h, v2.h[0]         // 0,1,2,3,4,5,6,7 * b
650     dup         v1.8h,  v4.h[0]                 // i00
651     dup         v2.8h,  v3.h[0]                 // c
652     add         v1.8h,  v1.8h,  v0.8h           // pix + {0..7}*b
653     mov         x3,  #16
654 1:
655     subs        x3,  x3,  #2
656     sqrshrun    v4.8b,  v1.8h,  #5
657     add         v1.8h,  v1.8h,  v2.8h
658     sqrshrun    v5.8b,  v1.8h,  #5
659     st1        {v4.8b}, [x0], x1
660     add         v1.8h,  v1.8h,  v2.8h
661     st1        {v5.8b}, [x0], x1
662     b.ne        1b
663     ret
664 endfunc
665
666 function x264_predict_8x16c_dc_neon, export=1
667     sub         x3,  x0,  #FDEC_STRIDE
668     mov         x1,  #FDEC_STRIDE
669     ld1        {v6.8b}, [x3]
670     loadsum4    w2, w3, w4, w5, x0, 0
671     uaddlp      v6.4h,  v6.8b
672     dup         v22.8h, w2              // s2
673     loadsum4    w6, w7, w8, w9, x0, 4
674     addp        v6.4h,  v6.4h,  v6.4h   // s0, s1
675     dup         v23.8h, w6              // s3
676     loadsum4    w2, w3, w4, w5, x0, 8
677     dup         v20.8h, v6.h[0]         // s0
678     dup         v24.8h, w2              // s4
679     loadsum4    w6, w7, w8, w9, x0, 12
680     dup         v21.8h, v6.h[1]         // s1
681     dup         v25.8h, w6              // s5
682
683     ext         v16.16b, v20.16b, v21.16b, #8
684     ext         v17.16b, v22.16b, v21.16b, #8
685     ext         v1.16b,  v23.16b, v21.16b, #8
686     ext         v2.16b,  v24.16b, v21.16b, #8
687     ext         v3.16b,  v25.16b, v21.16b, #8
688
689     add         v0.8h,  v16.8h, v17.8h
690     add         v1.8h,  v1.8h,  v23.8h
691     add         v2.8h,  v2.8h,  v24.8h
692     add         v3.8h,  v3.8h,  v25.8h
693
694     rshrn       v0.8b,  v0.8h,  #3
695     rshrn       v1.8b,  v1.8h,  #3
696     rshrn       v2.8b,  v2.8h,  #3
697     rshrn       v3.8b,  v3.8h,  #3
698 .irp  idx, 0, 1, 2, 3
699 .rept 4
700     st1        {v\idx\().8b}, [x0], x1
701 .endr
702 .endr
703     ret
704 endfunc
705
706 function x264_predict_8x16c_dc_left_neon, export=1
707     mov         x1,  #FDEC_STRIDE
708     ldrb        w2,  [x0, # 0 * FDEC_STRIDE - 1]
709     ldrb        w3,  [x0, # 1 * FDEC_STRIDE - 1]
710     ldrb        w4,  [x0, # 2 * FDEC_STRIDE - 1]
711     ldrb        w5,  [x0, # 3 * FDEC_STRIDE - 1]
712     add         w2,  w2,  w3
713
714     ldrb        w6,  [x0, # 4 * FDEC_STRIDE - 1]
715     add         w4,  w4,  w5
716     ldrb        w7,  [x0, # 5 * FDEC_STRIDE - 1]
717     add         w2,  w2,  w4
718     ldrb        w8,  [x0, # 6 * FDEC_STRIDE - 1]
719     ldrb        w9,  [x0, # 7 * FDEC_STRIDE - 1]
720     dup         v0.8h,  w2
721     add         w6,  w6,  w7
722     rshrn       v0.8b,  v0.8h,  #2
723     add         w8,  w8,  w9
724
725     ldrb        w10, [x0, # 8 * FDEC_STRIDE - 1]
726     ldrb        w11, [x0, # 9 * FDEC_STRIDE - 1]
727     add         w6,  w6,  w8
728     ldrb        w12, [x0, #10 * FDEC_STRIDE - 1]
729     ldrb        w13, [x0, #11 * FDEC_STRIDE - 1]
730     dup         v1.8h,  w6
731     add         w10,  w10,  w11
732     rshrn       v1.8b,  v1.8h,  #2
733     add         w12,  w12,  w13
734
735     ldrb        w2,  [x0, #12 * FDEC_STRIDE - 1]
736     ldrb        w3,  [x0, #13 * FDEC_STRIDE - 1]
737     add         w10,  w10,  w12
738     ldrb        w4,  [x0, #14 * FDEC_STRIDE - 1]
739     ldrb        w5,  [x0, #15 * FDEC_STRIDE - 1]
740     dup         v2.8h,  w10
741     add         w2,  w2,  w3
742     rshrn       v2.8b,  v2.8h,  #2
743     add         w4,  w4,  w5
744     st1        {v0.8b}, [x0], x1
745     st1        {v0.8b}, [x0], x1
746     add         w2,  w2,  w4
747     st1        {v0.8b}, [x0], x1
748     dup         v3.8h,  w2
749     st1        {v0.8b}, [x0], x1
750     rshrn       v3.8b,  v3.8h,  #2
751
752 .irp  idx, 1, 2, 3
753 .rept 4
754     st1        {v\idx\().8b}, [x0], x1
755 .endr
756 .endr
757     ret
758 endfunc
759
760 function x264_predict_8x16c_dc_top_neon, export=1
761     sub         x2,  x0,  #FDEC_STRIDE
762     mov         x1,  #FDEC_STRIDE
763     ld1        {v0.8b}, [x2]
764     uaddlp      v0.4h,  v0.8b
765     addp        v0.4h,  v0.4h,  v0.4h
766     rshrn       v4.8b,  v0.8h,  #2
767     dup         v0.8b,  v4.b[0]
768     dup         v1.8b,  v4.b[1]
769     ext         v0.8b,  v0.8b,  v1.8b,  #4
770 .rept 16
771     st1        {v0.8b}, [x0], x1
772 .endr
773     ret
774 endfunc
775
776
777 function x264_predict_16x16_dc_top_neon, export=1
778     sub         x2,  x0,  #FDEC_STRIDE
779     mov         x1,  #FDEC_STRIDE
780     ld1        {v0.16b}, [x2]
781     uaddlv      h0,     v0.16b
782     rshrn       v0.8b,  v0.8h,  #4
783     dup         v0.16b, v0.b[0]
784     b           pred16x16_dc_end
785 endfunc
786
787 function x264_predict_16x16_dc_left_neon, export=1
788     sub         x2,  x0,  #1
789     mov         x1,  #FDEC_STRIDE
790     ldcol.16    v0,  x2,  x1
791     uaddlv      h0,     v0.16b
792     rshrn       v0.8b,  v0.8h,  #4
793     dup         v0.16b, v0.b[0]
794     b           pred16x16_dc_end
795 endfunc
796
797 function x264_predict_16x16_dc_neon, export=1
798     sub         x3,  x0,  #FDEC_STRIDE
799     sub         x2,  x0,  #1
800     mov         x1,  #FDEC_STRIDE
801     ld1        {v0.16b}, [x3]
802     ldcol.16    v1,  x2,  x1
803     uaddlv      h0,     v0.16b
804     uaddlv      h1,     v1.16b
805     add         v0.4h,  v0.4h,  v1.4h
806     rshrn       v0.8b,  v0.8h,  #5
807     dup         v0.16b, v0.b[0]
808 pred16x16_dc_end:
809 .rept 16
810     st1        {v0.16b}, [x0], x1
811 .endr
812     ret
813 endfunc
814
815 function x264_predict_16x16_h_neon, export=1
816     sub         x1,  x0,  #1
817     mov         x7, #FDEC_STRIDE
818 .rept 8
819     ld1r       {v0.16b}, [x1], x7
820     ld1r       {v1.16b}, [x1], x7
821     st1        {v0.16b}, [x0], x7
822     st1        {v1.16b}, [x0], x7
823 .endr
824     ret
825 endfunc
826
827 function x264_predict_16x16_v_neon, export=1
828     sub         x0,  x0,  #FDEC_STRIDE
829     mov         x7,  #FDEC_STRIDE
830     ld1        {v0.16b}, [x0], x7
831 .rept 16
832     st1        {v0.16b}, [x0], x7
833 .endr
834     ret
835 endfunc
836
837 function x264_predict_16x16_p_neon, export=1
838     sub         x3,  x0,  #FDEC_STRIDE
839     mov         x1,  #FDEC_STRIDE
840     add         x2,  x3,  #8
841     sub         x3,  x3,  #1
842     ld1        {v0.8b}, [x3]
843     ld1        {v2.8b}, [x2], x1
844     ldcol.8     v1,  x3,  x1
845     add         x3,  x3,  x1
846     ldcol.8     v3,  x3,  x1
847     rev64       v0.8b,  v0.8b
848     rev64       v1.8b,  v1.8b
849     movrel      x4,  p16weight
850     uaddl       v4.8h,  v2.8b,  v3.8b
851     ld1        {v7.8h}, [x4]
852     usubl       v2.8h,  v2.8b,  v0.8b
853     usubl       v3.8h,  v3.8b,  v1.8b
854     mul         v2.8h,  v2.8h,  v7.8h
855     mul         v3.8h,  v3.8h,  v7.8h
856     saddlp      v2.4s,  v2.8h
857     saddlp      v3.4s,  v3.8h
858     addp        v2.4s,  v2.4s,  v3.4s
859     addp        v2.4s,  v2.4s,  v2.4s
860     shl         v3.2s,  v2.2s,  #2
861     add         v2.2s,  v2.2s,  v3.2s
862     rshrn       v5.4h,  v2.4s,  #6    // b, c, x, x
863     addp        v2.4h,  v5.4h,  v5.4h
864     shl         v3.4h,  v2.4h,  #3
865     sub         v3.4h,  v3.4h,  v2.4h // 7 * (b + c)
866     ext         v4.16b, v4.16b, v4.16b, #14
867     add         v4.4h,  v4.4h,  v7.4h
868     shl         v2.4h,  v4.4h,  #4              // a
869     sub         v2.4h,  v2.4h,  v3.4h           // a - 7 * (b + c) + 16
870     ext         v7.16b, v7.16b, v7.16b, #14
871     mov         v7.h[0],  wzr
872     dup         v3.8h,  v5.h[0]
873     mul         v0.8h,  v7.8h,  v5.h[0]         // 0,1,2,3,4,5,6,7 * b
874     dup         v1.8h,  v2.h[0]                 // pix
875     dup         v2.8h,  v5.h[1]                 // c
876     shl         v3.8h,  v3.8h,  #3
877     add         v1.8h,  v1.8h,  v0.8h           // pix + x*b
878     add         v3.8h,  v3.8h,  v1.8h           // pix + x{8-15}*b
879     mov         x3,  #16
880 1:
881     subs        x3,  x3,  #1
882     sqshrun     v0.8b,  v1.8h,  #5
883     add         v1.8h,  v1.8h,  v2.8h
884     sqshrun2    v0.16b, v3.8h,  #5
885     add         v3.8h,  v3.8h,  v2.8h
886     st1        {v0.16b}, [x0], x1
887     b.ne        1b
888     ret
889 endfunc