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