]> git.sesse.net Git - x264/blob - common/arm/predict-a.S
ca28ff8f3573c61849875eebf6b84ccafba5b6ea
[x264] / common / arm / predict-a.S
1 /*****************************************************************************
2  * predict.S: arm 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  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
22  *
23  * This program is also available under a commercial proprietary license.
24  * For more information, contact us at licensing@x264.com.
25  *****************************************************************************/
26
27 #include "asm.S"
28
29 .fpu neon
30
31 .section .rodata
32 .align 4
33
34 p16weight: .short 1,2,3,4,5,6,7,8
35
36 .text
37
38 .macro ldcol.8  rd,  rs,  rt,  n=8,  hi=0
39 .if \n == 8 || \hi == 0
40     vld1.8          {\rd[0]}, [\rs], \rt
41     vld1.8          {\rd[1]}, [\rs], \rt
42     vld1.8          {\rd[2]}, [\rs], \rt
43     vld1.8          {\rd[3]}, [\rs], \rt
44 .endif
45 .if \n == 8 || \hi == 1
46     vld1.8          {\rd[4]}, [\rs], \rt
47     vld1.8          {\rd[5]}, [\rs], \rt
48     vld1.8          {\rd[6]}, [\rs], \rt
49     vld1.8          {\rd[7]}, [\rs], \rt
50 .endif
51 .endm
52
53 .macro add16x8  dq,  dl,  dh,  rl,  rh
54     vaddl.u8        \dq, \rl, \rh
55     vadd.u16        \dl, \dl, \dh
56     vpadd.u16       \dl, \dl, \dl
57     vpadd.u16       \dl, \dl, \dl
58 .endm
59
60
61 // because gcc doesn't believe in using the free shift in add
62 function x264_predict_4x4_h_armv6
63     ldrb    r1, [r0, #0*FDEC_STRIDE-1]
64     ldrb    r2, [r0, #1*FDEC_STRIDE-1]
65     ldrb    r3, [r0, #2*FDEC_STRIDE-1]
66     ldrb    ip, [r0, #3*FDEC_STRIDE-1]
67     add     r1, r1, r1, lsl #8
68     add     r2, r2, r2, lsl #8
69     add     r3, r3, r3, lsl #8
70     add     ip, ip, ip, lsl #8
71     add     r1, r1, r1, lsl #16
72     str     r1, [r0, #0*FDEC_STRIDE]
73     add     r2, r2, r2, lsl #16
74     str     r2, [r0, #1*FDEC_STRIDE]
75     add     r3, r3, r3, lsl #16
76     str     r3, [r0, #2*FDEC_STRIDE]
77     add     ip, ip, ip, lsl #16
78     str     ip, [r0, #3*FDEC_STRIDE]
79     bx      lr
80 .endfunc
81
82 function x264_predict_4x4_v_armv6
83     ldr     r1,  [r0, #0 - 1 * FDEC_STRIDE]
84     str     r1,  [r0, #0 + 0 * FDEC_STRIDE]
85     str     r1,  [r0, #0 + 1 * FDEC_STRIDE]
86     str     r1,  [r0, #0 + 2 * FDEC_STRIDE]
87     str     r1,  [r0, #0 + 3 * FDEC_STRIDE]
88     bx      lr
89 .endfunc
90
91 function x264_predict_4x4_dc_armv6
92     mov     ip, #0
93     ldr     r1, [r0, #-FDEC_STRIDE]
94     ldrb    r2, [r0, #0*FDEC_STRIDE-1]
95     ldrb    r3, [r0, #1*FDEC_STRIDE-1]
96     usad8   r1, r1, ip
97     add     r2, r2, #4
98     ldrb    ip, [r0, #2*FDEC_STRIDE-1]
99     add     r2, r2, r3
100     ldrb    r3, [r0, #3*FDEC_STRIDE-1]
101     add     r2, r2, ip
102     add     r2, r2, r3
103     add     r1, r1, r2
104     lsr     r1, r1, #3
105     add     r1, r1, r1, lsl #8
106     add     r1, r1, r1, lsl #16
107     str     r1, [r0, #0*FDEC_STRIDE]
108     str     r1, [r0, #1*FDEC_STRIDE]
109     str     r1, [r0, #2*FDEC_STRIDE]
110     str     r1, [r0, #3*FDEC_STRIDE]
111     bx      lr
112 .endfunc
113
114 function x264_predict_4x4_dc_top_neon
115     mov         r12, #FDEC_STRIDE
116     sub         r1, r0, #FDEC_STRIDE
117     vld1.32     d1[], [r1,:32]
118     vpaddl.u8   d1, d1
119     vpadd.u16   d1, d1, d1
120     vrshr.u16   d1, d1, #2
121     vdup.8      d1, d1[0]
122     vst1.32     d1[0], [r0,:32], r12
123     vst1.32     d1[0], [r0,:32], r12
124     vst1.32     d1[0], [r0,:32], r12
125     vst1.32     d1[0], [r0,:32], r12
126     bx          lr
127 .endfunc
128
129 // return a1 = (a1+2*b1+c1+2)>>2  a2 = (a2+2*b2+c2+2)>>2
130 .macro PRED4x4_LOWPASS a1 b1 c1 a2 b2 c2 pb_1
131     uhadd8  \a1, \a1, \c1
132     uhadd8  \a2, \a2, \c2
133     uhadd8  \c1, \a1, \b1
134     uhadd8  \c2, \a2, \b2
135     eor     \a1, \a1, \b1
136     eor     \a2, \a2, \b2
137     and     \a1, \a1, \pb_1
138     and     \a2, \a2, \pb_1
139     uadd8   \a1, \a1, \c1
140     uadd8   \a2, \a2, \c2
141 .endm
142
143 function x264_predict_4x4_ddr_armv6
144     ldr     r1, [r0, # -FDEC_STRIDE]
145     ldrb    r2, [r0, # -FDEC_STRIDE-1]
146     ldrb    r3, [r0, #0*FDEC_STRIDE-1]
147     push    {r4-r6,lr}
148     add     r2, r2, r1, lsl #8
149     ldrb    r4, [r0, #1*FDEC_STRIDE-1]
150     add     r3, r3, r2, lsl #8
151     ldrb    r5, [r0, #2*FDEC_STRIDE-1]
152     ldrb    r6, [r0, #3*FDEC_STRIDE-1]
153     add     r4, r4, r3, lsl #8
154     add     r5, r5, r4, lsl #8
155     add     r6, r6, r5, lsl #8
156     ldr     ip, =0x01010101
157     PRED4x4_LOWPASS r1, r2, r3, r4, r5, r6, ip
158     str     r1, [r0, #0*FDEC_STRIDE]
159     lsl     r2, r1, #8
160     lsl     r3, r1, #16
161     lsl     r4, r4, #8
162     lsl     r5, r1, #24
163     add     r2, r2, r4, lsr #24
164     str     r2, [r0, #1*FDEC_STRIDE]
165     add     r3, r3, r4, lsr #16
166     str     r3, [r0, #2*FDEC_STRIDE]
167     add     r5, r5, r4, lsr #8
168     str     r5, [r0, #3*FDEC_STRIDE]
169     pop     {r4-r6,pc}
170 .endfunc
171
172 function x264_predict_4x4_ddl_neon
173     sub         r0, #FDEC_STRIDE
174     mov         ip, #FDEC_STRIDE
175     vld1.64     {d0}, [r0], ip
176     vdup.8      d3, d0[7]
177     vext.8      d1, d0, d0, #1
178     vext.8      d2, d0, d3, #2
179     vhadd.u8    d0, d0, d2
180     vrhadd.u8   d0, d0, d1
181     vst1.32     {d0[0]}, [r0,:32], ip
182     vext.8      d1, d0, d0, #1
183     vext.8      d2, d0, d0, #2
184     vst1.32     {d1[0]}, [r0,:32], ip
185     vext.8      d3, d0, d0, #3
186     vst1.32     {d2[0]}, [r0,:32], ip
187     vst1.32     {d3[0]}, [r0,:32], ip
188     bx          lr
189 .endfunc
190
191 function x264_predict_8x8_dc_neon
192     mov     ip, #0
193     ldrd    r2, r3, [r1, #8]
194     push    {r4-r5,lr}
195     ldrd    r4, r5, [r1, #16]
196     lsl     r3, r3, #8
197     ldrb    lr, [r1, #7]
198     usad8   r2, r2, ip
199     usad8   r3, r3, ip
200     usada8  r2, r4, ip, r2
201     add     lr, lr, #8
202     usada8  r3, r5, ip, r3
203     add     r2, r2, lr
204     mov     ip, #FDEC_STRIDE
205     add     r2, r2, r3
206     lsr     r2, r2, #4
207
208     vdup.8   d0, r2
209 .rept 8
210     vst1.64 {d0}, [r0,:64], ip
211 .endr
212     pop    {r4-r5,pc}
213 .endfunc
214
215 function x264_predict_8x8_h_neon
216     add         r1, r1, #7
217     mov         ip, #FDEC_STRIDE
218     vld1.64     {d16}, [r1]
219     vdup.8      d0, d16[7]
220     vdup.8      d1, d16[6]
221     vst1.64     {d0}, [r0,:64], ip
222     vdup.8      d2, d16[5]
223     vst1.64     {d1}, [r0,:64], ip
224     vdup.8      d3, d16[4]
225     vst1.64     {d2}, [r0,:64], ip
226     vdup.8      d4, d16[3]
227     vst1.64     {d3}, [r0,:64], ip
228     vdup.8      d5, d16[2]
229     vst1.64     {d4}, [r0,:64], ip
230     vdup.8      d6, d16[1]
231     vst1.64     {d5}, [r0,:64], ip
232     vdup.8      d7, d16[0]
233     vst1.64     {d6}, [r0,:64], ip
234     vst1.64     {d7}, [r0,:64], ip
235     bx          lr
236 .endfunc
237
238 function x264_predict_8x8_v_neon
239     add         r1, r1, #16
240     mov         r12, #FDEC_STRIDE
241     vld1.8      {d0}, [r1,:64]
242 .rept 8
243     vst1.8      {d0}, [r0,:64], r12
244 .endr
245     bx          lr
246 .endfunc
247
248 function x264_predict_8x8_ddl_neon
249     add         r1, #16
250     vld1.8      {d0, d1}, [r1,:128]
251     vmov.i8     q3, #0
252     vrev64.8    d2, d1
253     vext.8      q8, q3, q0, #15
254     vext.8      q2, q0, q1, #1
255     vhadd.u8    q8, q2
256     mov         r12, #FDEC_STRIDE
257     vrhadd.u8   q0, q8
258     vext.8      d2, d0, d1, #1
259     vext.8      d3, d0, d1, #2
260     vst1.8      d2, [r0,:64], r12
261     vext.8      d2, d0, d1, #3
262     vst1.8      d3, [r0,:64], r12
263     vext.8      d3, d0, d1, #4
264     vst1.8      d2, [r0,:64], r12
265     vext.8      d2, d0, d1, #5
266     vst1.8      d3, [r0,:64], r12
267     vext.8      d3, d0, d1, #6
268     vst1.8      d2, [r0,:64], r12
269     vext.8      d2, d0, d1, #7
270     vst1.8      d3, [r0,:64], r12
271     vst1.8      d2, [r0,:64], r12
272     vst1.8      d1, [r0,:64], r12
273     bx          lr
274 .endfunc
275
276 function x264_predict_8x8_ddr_neon
277     vld1.8      {d0-d3}, [r1,:128]
278     vext.8      q2, q0, q1, #7
279     vext.8      q3, q0, q1, #9
280
281     vhadd.u8    q2, q2, q3
282     vrhadd.u8   d0, d1, d4
283     vrhadd.u8   d1, d2, d5
284
285     add         r0, #7*FDEC_STRIDE
286     mov         r12, #-1*FDEC_STRIDE
287
288     vext.8      d2, d0, d1, #1
289     vst1.8      {d0}, [r0,:64], r12
290     vext.8      d4, d0, d1, #2
291     vst1.8      {d2}, [r0,:64], r12
292     vext.8      d5, d0, d1, #3
293     vst1.8      {d4}, [r0,:64], r12
294     vext.8      d4, d0, d1, #4
295     vst1.8      {d5}, [r0,:64], r12
296     vext.8      d5, d0, d1, #5
297     vst1.8      {d4}, [r0,:64], r12
298     vext.8      d4, d0, d1, #6
299     vst1.8      {d5}, [r0,:64], r12
300     vext.8      d5, d0, d1, #7
301     vst1.8      {d4}, [r0,:64], r12
302     vst1.8      {d5}, [r0,:64], r12
303     bx          lr
304 .endfunc
305
306 function x264_predict_8x8_vl_neon
307     add         r1, #16
308     mov         r12, #FDEC_STRIDE
309
310     vld1.8      {d0, d1}, [r1,:128]
311     vext.8      q1, q1, q0, #15
312     vext.8      q2, q0, q2, #1
313
314     vrhadd.u8   q3, q0, q2
315
316     vhadd.u8    q1, q1, q2
317     vrhadd.u8   q0, q0, q1
318
319     vext.8      d2, d0, d1, #1
320     vst1.8      {d6}, [r0,:64], r12
321     vext.8      d3, d6, d7, #1
322     vst1.8      {d2}, [r0,:64], r12
323     vext.8      d2, d0, d1, #2
324     vst1.8      {d3}, [r0,:64], r12
325     vext.8      d3, d6, d7, #2
326     vst1.8      {d2}, [r0,:64], r12
327     vext.8      d2, d0, d1, #3
328     vst1.8      {d3}, [r0,:64], r12
329     vext.8      d3, d6, d7, #3
330     vst1.8      {d2}, [r0,:64], r12
331     vext.8      d2, d0, d1, #4
332     vst1.8      {d3}, [r0,:64], r12
333     vst1.8      {d2}, [r0,:64], r12
334     bx          lr
335 .endfunc
336
337 function x264_predict_8x8_vr_neon
338     add         r1, #8
339     mov         r12, #FDEC_STRIDE
340     vld1.8      {d4,d5}, [r1,:64]
341
342     vext.8      q1, q2, q2, #14
343     vext.8      q0, q2, q2, #15
344
345     vhadd.u8    q3, q2, q1
346     vrhadd.u8   q2, q2, q0
347     vrhadd.u8   q0, q0, q3
348
349     vmov        d2, d0
350
351     vst1.8      {d5}, [r0,:64], r12
352     vuzp.8      d2, d0
353     vst1.8      {d1}, [r0,:64], r12
354     vext.8      d6, d0, d5, #7
355     vext.8      d3, d2, d1, #7
356     vst1.8      {d6}, [r0,:64], r12
357     vst1.8      {d3}, [r0,:64], r12
358     vext.8      d6, d0, d5, #6
359     vext.8      d3, d2, d1, #6
360     vst1.8      {d6}, [r0,:64], r12
361     vst1.8      {d3}, [r0,:64], r12
362     vext.8      d6, d0, d5, #5
363     vext.8      d3, d2, d1, #5
364     vst1.8      {d6}, [r0,:64], r12
365     vst1.8      {d3}, [r0,:64], r12
366     bx          lr
367 .endfunc
368
369 function x264_predict_8x8_hd_neon
370     mov         r12, #FDEC_STRIDE
371     add         r1, #7
372
373     vld1.8      {d2,d3}, [r1]
374     vext.8      q3, q1, q1, #1
375     vext.8      q2, q1, q1, #2
376
377     vrhadd.u8   q8, q1, q3
378
379     vhadd.u8    q1, q2
380     vrhadd.u8   q0, q1, q3
381
382     vzip.8      d16, d0
383
384     vext.8      d2, d0, d1, #6
385     vext.8      d3, d0, d1, #4
386     vst1.8      {d2}, [r0,:64], r12
387     vext.8      d2, d0, d1, #2
388     vst1.8      {d3}, [r0,:64], r12
389     vst1.8      {d2}, [r0,:64], r12
390     vext.8      d2, d16, d0, #6
391     vst1.8      {d0}, [r0,:64], r12
392     vext.8      d3, d16, d0, #4
393     vst1.8      {d2}, [r0,:64], r12
394     vext.8      d2, d16, d0, #2
395     vst1.8      {d3}, [r0,:64], r12
396     vst1.8      {d2}, [r0,:64], r12
397     vst1.8      {d16}, [r0,:64], r12
398
399     bx          lr
400 .endfunc
401
402 function x264_predict_8x8_hu_neon
403     mov         r12, #FDEC_STRIDE
404     add         r1, #7
405     vld1.8      {d7}, [r1]
406     vdup.8      d6, d7[0]
407     vrev64.8    d7, d7
408
409     vext.8      d4, d7, d6, #2
410     vext.8      d2, d7, d6, #1
411
412     vhadd.u8    d16, d7, d4
413     vrhadd.u8   d0, d2, d7
414     vrhadd.u8   d1, d16, d2
415
416     vzip.8      d0, d1
417
418     vdup.16     q1, d1[3]
419
420     vext.8      q2, q0, q1, #2
421     vext.8      q3, q0, q1, #4
422     vext.8      q8, q0, q1, #6
423     vst1.8      {d0}, [r0,:64], r12
424     vst1.8      {d4}, [r0,:64], r12
425     vst1.8      {d6}, [r0,:64], r12
426     vst1.8      {d16}, [r0,:64], r12
427
428     vst1.8      {d1}, [r0,:64], r12
429     vst1.8      {d5}, [r0,:64], r12
430     vst1.8      {d7}, [r0,:64], r12
431     vst1.8      {d17}, [r0,:64]
432     bx          lr
433 .endfunc
434
435 function x264_predict_8x8c_dc_top_neon
436     sub         r2,  r0,  #FDEC_STRIDE
437     mov         r1,  #FDEC_STRIDE
438     vld1.8      {d0}, [r2,:64]
439     vpaddl.u8   d0,  d0
440     vpadd.u16   d0,  d0,  d0
441     vrshrn.u16  d0,  q0,  #2
442     vdup.8      d1,  d0[1]
443     vdup.8      d0,  d0[0]
444     vtrn.32     d0,  d1
445     b           pred8x8_dc_end
446 .endfunc
447
448 function x264_predict_8x8c_dc_left_neon
449     mov         r1,  #FDEC_STRIDE
450     sub         r2,  r0,  #1
451     ldcol.8     d0,  r2,  r1
452     vpaddl.u8   d0,  d0
453     vpadd.u16   d0,  d0,  d0
454     vrshrn.u16  d0,  q0,  #2
455     vdup.8      d1,  d0[1]
456     vdup.8      d0,  d0[0]
457     b           pred8x8_dc_end
458 .endfunc
459
460 function x264_predict_8x8c_dc_neon
461     sub         r2,  r0,  #FDEC_STRIDE
462     mov         r1,  #FDEC_STRIDE
463     vld1.8      {d0}, [r2,:64]
464     sub         r2,  r0,  #1
465     ldcol.8     d1,  r2,  r1
466     vtrn.32     d0,  d1
467     vpaddl.u8   q0,  q0
468     vpadd.u16   d0,  d0,  d1
469     vpadd.u16   d1,  d0,  d0
470     vrshrn.u16  d2,  q0,  #3
471     vrshrn.u16  d3,  q0,  #2
472     vdup.8      d0,  d2[4]
473     vdup.8      d1,  d3[3]
474     vdup.8      d4,  d3[2]
475     vdup.8      d5,  d2[5]
476     vtrn.32     q0,  q2
477 pred8x8_dc_end:
478     add         r2,  r0,  r1,  lsl #2
479 .rept 4
480     vst1.8      {d0}, [r0,:64], r1
481     vst1.8      {d1}, [r2,:64], r1
482 .endr
483     bx          lr
484 .endfunc
485
486 function x264_predict_8x8c_h_neon
487     sub         r1, r0, #1
488     mov         ip, #FDEC_STRIDE
489 .rept 4
490     vld1.8      {d0[]}, [r1], ip
491     vld1.8      {d2[]}, [r1], ip
492     vst1.64     {d0}, [r0,:64], ip
493     vst1.64     {d2}, [r0,:64], ip
494 .endr
495     bx          lr
496 .endfunc
497
498 function x264_predict_8x8c_v_neon
499     sub         r0, r0, #FDEC_STRIDE
500     mov         ip, #FDEC_STRIDE
501     vld1.64     {d0}, [r0,:64], ip
502 .rept 8
503     vst1.64     {d0}, [r0,:64], ip
504 .endr
505     bx          lr
506 .endfunc
507
508 function x264_predict_8x8c_p_neon
509     sub         r3,  r0,  #FDEC_STRIDE
510     mov         r1,  #FDEC_STRIDE
511     add         r2,  r3,  #4
512     sub         r3,  r3,  #1
513     vld1.32     {d0[0]}, [r3]
514     vld1.32     {d2[0]}, [r2,:32], r1
515     ldcol.8     d0,  r3,  r1,  4,  hi=1
516     add         r3,  r3,  r1
517     ldcol.8     d3,  r3,  r1,  4
518     vaddl.u8    q8,  d2,  d3
519     vrev32.8    d0,  d0
520     vtrn.32     d2,  d3
521     vsubl.u8    q2,  d2,  d0
522     movrel      r3,  p16weight
523     vld1.16     {q0}, [r3,:128]
524     vmul.s16    d4,  d4,  d0
525     vmul.s16    d5,  d5,  d0
526     vpadd.i16   d4,  d4,  d5
527     vpaddl.s16  d4,  d4
528     vshl.i32    d5,  d4,  #4
529     vadd.s32    d4,  d4,  d5
530     vrshrn.s32  d4,  q2,  #5
531     mov         r3,  #0
532     vtrn.16     d4,  d5
533     vadd.i16    d2,  d4,  d5
534     vshl.i16    d3,  d2,  #2
535     vrev64.16   d16, d16
536     vsub.i16    d3,  d3,  d2
537     vadd.i16    d16, d16, d0
538     vshl.i16    d2,  d16, #4
539     vsub.i16    d2,  d2,  d3
540     vshl.i16    d3,  d4,  #3
541     vext.16     q0,  q0,  q0,  #7
542     vsub.i16    d6,  d5,  d3
543     vmov.16     d0[0], r3
544     vmul.i16    q0,  q0,  d4[0]
545     vdup.16     q1,  d2[0]
546     vdup.16     q2,  d4[0]
547     vdup.16     q3,  d6[0]
548     vshl.i16    q2,  q2,  #3
549     vadd.i16    q1,  q1,  q0
550     vadd.i16    q3,  q3,  q2
551     mov         r3,  #8
552 1:
553     vqshrun.s16 d0,  q1,  #5
554     vadd.i16    q1,  q1,  q3
555     vst1.8      {d0}, [r0,:64], r1
556     subs        r3,  r3,  #1
557     bne         1b
558     bx          lr
559 .endfunc
560
561
562 function x264_predict_16x16_dc_top_neon
563     sub         r2,  r0,  #FDEC_STRIDE
564     mov         r1,  #FDEC_STRIDE
565     vld1.8      {q0}, [r2,:128]
566     add16x8     q0,  d0,  d1,  d0,  d1
567     vrshrn.u16  d0,  q0,  #4
568     vdup.8      q0,  d0[0]
569     b           pred16x16_dc_end
570 .endfunc
571
572 function x264_predict_16x16_dc_left_neon
573     mov         r1,  #FDEC_STRIDE
574     sub         r2,  r0,  #1
575     ldcol.8     d0,  r2,  r1
576     ldcol.8     d1,  r2,  r1
577     add16x8     q0,  d0,  d1,  d0,  d1
578     vrshrn.u16  d0,  q0,  #4
579     vdup.8      q0,  d0[0]
580     b           pred16x16_dc_end
581 .endfunc
582
583 function x264_predict_16x16_dc_neon
584     sub         r3, r0, #FDEC_STRIDE
585     sub         r0, r0, #1
586     vld1.64     {d0-d1}, [r3,:128]
587     ldrb        ip, [r0], #FDEC_STRIDE
588     vaddl.u8    q0, d0, d1
589     ldrb        r1, [r0], #FDEC_STRIDE
590     vadd.u16    d0, d0, d1
591     vpadd.u16   d0, d0, d0
592     vpadd.u16   d0, d0, d0
593 .rept 4
594     ldrb        r2, [r0], #FDEC_STRIDE
595     add         ip, ip, r1
596     ldrb        r3, [r0], #FDEC_STRIDE
597     add         ip, ip, r2
598     ldrb        r1, [r0], #FDEC_STRIDE
599     add         ip, ip, r3
600 .endr
601     ldrb        r2, [r0], #FDEC_STRIDE
602     add         ip, ip, r1
603     ldrb        r3, [r0], #FDEC_STRIDE
604     add         ip, ip, r2
605
606     sub         r0, r0, #FDEC_STRIDE*16
607     add         ip, ip, r3
608     vdup.16     d1, ip
609     vadd.u16    d0, d0, d1
610     mov         r1, #FDEC_STRIDE
611     add         r0, r0, #1
612     vrshr.u16   d0, d0, #5
613     vdup.8      q0, d0[0]
614 pred16x16_dc_end:
615 .rept 16
616     vst1.64     {d0-d1}, [r0,:128], r1
617 .endr
618     bx          lr
619 .endfunc
620
621 function x264_predict_16x16_h_neon
622     sub         r1, r0, #1
623     mov         ip, #FDEC_STRIDE
624 .rept 8
625     vld1.8      {d0[]}, [r1], ip
626     vmov        d1, d0
627     vld1.8      {d2[]}, [r1], ip
628     vmov        d3, d2
629     vst1.64     {d0-d1}, [r0,:128], ip
630     vst1.64     {d2-d3}, [r0,:128], ip
631 .endr
632     bx          lr
633 .endfunc
634
635 function x264_predict_16x16_v_neon
636     sub         r0, r0, #FDEC_STRIDE
637     mov         ip, #FDEC_STRIDE
638     vld1.64     {d0-d1}, [r0,:128], ip
639 .rept 16
640     vst1.64     {d0-d1}, [r0,:128], ip
641 .endr
642     bx          lr
643 .endfunc
644
645 function x264_predict_16x16_p_neon
646     sub         r3,  r0,  #FDEC_STRIDE
647     mov         r1,  #FDEC_STRIDE
648     add         r2,  r3,  #8
649     sub         r3,  r3,  #1
650     vld1.8      {d0}, [r3]
651     vld1.8      {d2}, [r2,:64], r1
652     ldcol.8     d1,  r3,  r1
653     add         r3,  r3,  r1
654     ldcol.8     d3,  r3,  r1
655     vrev64.8    q0,  q0
656     vaddl.u8    q8,  d2,  d3
657     vsubl.u8    q2,  d2,  d0
658     vsubl.u8    q3,  d3,  d1
659     movrel      r3,  p16weight
660     vld1.8      {q0}, [r3,:128]
661     vmul.s16    q2,  q2,  q0
662     vmul.s16    q3,  q3,  q0
663     vadd.i16    d4,  d4,  d5
664     vadd.i16    d5,  d6,  d7
665     vpadd.i16   d4,  d4,  d5
666     vpadd.i16   d4,  d4,  d4
667     vshll.s16   q3,  d4,  #2
668     vaddw.s16   q2,  q3,  d4
669     vrshrn.s32  d4,  q2,  #6
670     mov         r3,  #0
671     vtrn.16     d4,  d5
672     vadd.i16    d2,  d4,  d5
673     vshl.i16    d3,  d2,  #3
674     vrev64.16   d16, d17
675     vsub.i16    d3,  d3,  d2
676     vadd.i16    d16, d16, d0
677     vshl.i16    d2,  d16, #4
678     vsub.i16    d2,  d2,  d3
679     vshl.i16    d3,  d4,  #4
680     vext.16     q0,  q0,  q0,  #7
681     vsub.i16    d6,  d5,  d3
682     vmov.16     d0[0], r3
683     vmul.i16    q0,  q0,  d4[0]
684     vdup.16     q1,  d2[0]
685     vdup.16     q2,  d4[0]
686     vdup.16     q3,  d6[0]
687     vshl.i16    q2,  q2,  #3
688     vadd.i16    q1,  q1,  q0
689     vadd.i16    q3,  q3,  q2
690     mov         r3,  #16
691 1:
692     vqshrun.s16 d0,  q1,  #5
693     vadd.i16    q1,  q1,  q2
694     vqshrun.s16 d1,  q1,  #5
695     vadd.i16    q1,  q1,  q3
696     vst1.8      {q0}, [r0,:128], r1
697     subs        r3,  r3,  #1
698     bne         1b
699     bx          lr
700 .endfunc