c2bf08171c7b0cfdcbb4038eb3bb93297c2331de
[x262.git] / common / arm / predict-a.S
1 /*****************************************************************************
2  * predict.S: arm intra prediction
3  *****************************************************************************
4  * Copyright (C) 2009-2013 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_dc_armv6
83     mov     ip, #0
84     ldr     r1, [r0, #-FDEC_STRIDE]
85     ldrb    r2, [r0, #0*FDEC_STRIDE-1]
86     ldrb    r3, [r0, #1*FDEC_STRIDE-1]
87     usad8   r1, r1, ip
88     add     r2, r2, #4
89     ldrb    ip, [r0, #2*FDEC_STRIDE-1]
90     add     r2, r2, r3
91     ldrb    r3, [r0, #3*FDEC_STRIDE-1]
92     add     r2, r2, ip
93     add     r2, r2, r3
94     add     r1, r1, r2
95     lsr     r1, r1, #3
96     add     r1, r1, r1, lsl #8
97     add     r1, r1, r1, lsl #16
98     str     r1, [r0, #0*FDEC_STRIDE]
99     str     r1, [r0, #1*FDEC_STRIDE]
100     str     r1, [r0, #2*FDEC_STRIDE]
101     str     r1, [r0, #3*FDEC_STRIDE]
102     bx      lr
103 .endfunc
104
105 function x264_predict_4x4_dc_top_neon
106     mov         r12, #FDEC_STRIDE
107     sub         r1, r0, #FDEC_STRIDE
108     vld1.32     d1[], [r1,:32]
109     vpaddl.u8   d1, d1
110     vpadd.u16   d1, d1, d1
111     vrshr.u16   d1, d1, #2
112     vdup.8      d1, d1[0]
113     vst1.32     d1[0], [r0,:32], r12
114     vst1.32     d1[0], [r0,:32], r12
115     vst1.32     d1[0], [r0,:32], r12
116     vst1.32     d1[0], [r0,:32], r12
117     bx          lr
118 .endfunc
119
120 // return a1 = (a1+2*b1+c1+2)>>2  a2 = (a2+2*b2+c2+2)>>2
121 .macro PRED4x4_LOWPASS a1 b1 c1 a2 b2 c2 pb_1
122     uhadd8  \a1, \a1, \c1
123     uhadd8  \a2, \a2, \c2
124     uhadd8  \c1, \a1, \b1
125     uhadd8  \c2, \a2, \b2
126     eor     \a1, \a1, \b1
127     eor     \a2, \a2, \b2
128     and     \a1, \a1, \pb_1
129     and     \a2, \a2, \pb_1
130     uadd8   \a1, \a1, \c1
131     uadd8   \a2, \a2, \c2
132 .endm
133
134 function x264_predict_4x4_ddr_armv6
135     ldr     r1, [r0, # -FDEC_STRIDE]
136     ldrb    r2, [r0, # -FDEC_STRIDE-1]
137     ldrb    r3, [r0, #0*FDEC_STRIDE-1]
138     push    {r4-r6,lr}
139     add     r2, r2, r1, lsl #8
140     ldrb    r4, [r0, #1*FDEC_STRIDE-1]
141     add     r3, r3, r2, lsl #8
142     ldrb    r5, [r0, #2*FDEC_STRIDE-1]
143     ldrb    r6, [r0, #3*FDEC_STRIDE-1]
144     add     r4, r4, r3, lsl #8
145     add     r5, r5, r4, lsl #8
146     add     r6, r6, r5, lsl #8
147     ldr     ip, =0x01010101
148     PRED4x4_LOWPASS r1, r2, r3, r4, r5, r6, ip
149     str     r1, [r0, #0*FDEC_STRIDE]
150     lsl     r2, r1, #8
151     lsl     r3, r1, #16
152     lsl     r4, r4, #8
153     lsl     r5, r1, #24
154     add     r2, r2, r4, lsr #24
155     str     r2, [r0, #1*FDEC_STRIDE]
156     add     r3, r3, r4, lsr #16
157     str     r3, [r0, #2*FDEC_STRIDE]
158     add     r5, r5, r4, lsr #8
159     str     r5, [r0, #3*FDEC_STRIDE]
160     pop     {r4-r6,pc}
161 .endfunc
162
163 function x264_predict_4x4_ddl_neon
164     sub         r0, #FDEC_STRIDE
165     mov         ip, #FDEC_STRIDE
166     vld1.64     {d0}, [r0], ip
167     vdup.8      d3, d0[7]
168     vext.8      d1, d0, d0, #1
169     vext.8      d2, d0, d3, #2
170     vhadd.u8    d0, d0, d2
171     vrhadd.u8   d0, d0, d1
172     vst1.32     {d0[0]}, [r0,:32], ip
173     vext.8      d1, d0, d0, #1
174     vext.8      d2, d0, d0, #2
175     vst1.32     {d1[0]}, [r0,:32], ip
176     vext.8      d3, d0, d0, #3
177     vst1.32     {d2[0]}, [r0,:32], ip
178     vst1.32     {d3[0]}, [r0,:32], ip
179     bx          lr
180 .endfunc
181
182 function x264_predict_8x8_dc_neon
183     mov     ip, #0
184     ldrd    r2, r3, [r1, #8]
185     push    {r4-r5,lr}
186     ldrd    r4, r5, [r1, #16]
187     lsl     r3, r3, #8
188     ldrb    lr, [r1, #7]
189     usad8   r2, r2, ip
190     usad8   r3, r3, ip
191     usada8  r2, r4, ip, r2
192     add     lr, lr, #8
193     usada8  r3, r5, ip, r3
194     add     r2, r2, lr
195     mov     ip, #FDEC_STRIDE
196     add     r2, r2, r3
197     lsr     r2, r2, #4
198
199     vdup.8   d0, r2
200 .rept 8
201     vst1.64 {d0}, [r0,:64], ip
202 .endr
203     pop    {r4-r5,pc}
204 .endfunc
205
206 function x264_predict_8x8_h_neon
207     add         r1, r1, #7
208     mov         ip, #FDEC_STRIDE
209     vld1.64     {d16}, [r1]
210     vdup.8      d0, d16[7]
211     vdup.8      d1, d16[6]
212     vst1.64     {d0}, [r0,:64], ip
213     vdup.8      d2, d16[5]
214     vst1.64     {d1}, [r0,:64], ip
215     vdup.8      d3, d16[4]
216     vst1.64     {d2}, [r0,:64], ip
217     vdup.8      d4, d16[3]
218     vst1.64     {d3}, [r0,:64], ip
219     vdup.8      d5, d16[2]
220     vst1.64     {d4}, [r0,:64], ip
221     vdup.8      d6, d16[1]
222     vst1.64     {d5}, [r0,:64], ip
223     vdup.8      d7, d16[0]
224     vst1.64     {d6}, [r0,:64], ip
225     vst1.64     {d7}, [r0,:64], ip
226     bx          lr
227 .endfunc
228
229 function x264_predict_8x8_v_neon
230     add         r1, r1, #16
231     mov         r12, #FDEC_STRIDE
232     vld1.8      {d0}, [r1,:64]
233 .rept 8
234     vst1.8      {d0}, [r0,:64], r12
235 .endr
236     bx          lr
237 .endfunc
238
239 function x264_predict_8x8_ddl_neon
240     add         r1, #16
241     vld1.8      {d0, d1}, [r1,:128]
242     vmov.i8     q3, #0
243     vrev64.8    d2, d1
244     vext.8      q8, q3, q0, #15
245     vext.8      q2, q0, q1, #1
246     vhadd.u8    q8, q2
247     mov         r12, #FDEC_STRIDE
248     vrhadd.u8   q0, q8
249     vext.8      d2, d0, d1, #1
250     vext.8      d3, d0, d1, #2
251     vst1.8      d2, [r0,:64], r12
252     vext.8      d2, d0, d1, #3
253     vst1.8      d3, [r0,:64], r12
254     vext.8      d3, d0, d1, #4
255     vst1.8      d2, [r0,:64], r12
256     vext.8      d2, d0, d1, #5
257     vst1.8      d3, [r0,:64], r12
258     vext.8      d3, d0, d1, #6
259     vst1.8      d2, [r0,:64], r12
260     vext.8      d2, d0, d1, #7
261     vst1.8      d3, [r0,:64], r12
262     vst1.8      d2, [r0,:64], r12
263     vst1.8      d1, [r0,:64], r12
264     bx          lr
265 .endfunc
266
267 function x264_predict_8x8_ddr_neon
268     vld1.8      {d0-d3}, [r1,:128]
269     vext.8      q2, q0, q1, #7
270     vext.8      q3, q0, q1, #9
271
272     vhadd.u8    q2, q2, q3
273     vrhadd.u8   d0, d1, d4
274     vrhadd.u8   d1, d2, d5
275
276     add         r0, #7*FDEC_STRIDE
277     mov         r12, #-1*FDEC_STRIDE
278
279     vext.8      d2, d0, d1, #1
280     vst1.8      {d0}, [r0,:64], r12
281     vext.8      d4, d0, d1, #2
282     vst1.8      {d2}, [r0,:64], r12
283     vext.8      d5, d0, d1, #3
284     vst1.8      {d4}, [r0,:64], r12
285     vext.8      d4, d0, d1, #4
286     vst1.8      {d5}, [r0,:64], r12
287     vext.8      d5, d0, d1, #5
288     vst1.8      {d4}, [r0,:64], r12
289     vext.8      d4, d0, d1, #6
290     vst1.8      {d5}, [r0,:64], r12
291     vext.8      d5, d0, d1, #7
292     vst1.8      {d4}, [r0,:64], r12
293     vst1.8      {d5}, [r0,:64], r12
294     bx          lr
295 .endfunc
296
297 function x264_predict_8x8_vl_neon
298     add         r1, #16
299     mov         r12, #FDEC_STRIDE
300
301     vld1.8      {d0, d1}, [r1,:128]
302     vext.8      q1, q1, q0, #15
303     vext.8      q2, q0, q2, #1
304
305     vrhadd.u8   q3, q0, q2
306
307     vhadd.u8    q1, q1, q2
308     vrhadd.u8   q0, q0, q1
309
310     vext.8      d2, d0, d1, #1
311     vst1.8      {d6}, [r0,:64], r12
312     vext.8      d3, d6, d7, #1
313     vst1.8      {d2}, [r0,:64], r12
314     vext.8      d2, d0, d1, #2
315     vst1.8      {d3}, [r0,:64], r12
316     vext.8      d3, d6, d7, #2
317     vst1.8      {d2}, [r0,:64], r12
318     vext.8      d2, d0, d1, #3
319     vst1.8      {d3}, [r0,:64], r12
320     vext.8      d3, d6, d7, #3
321     vst1.8      {d2}, [r0,:64], r12
322     vext.8      d2, d0, d1, #4
323     vst1.8      {d3}, [r0,:64], r12
324     vst1.8      {d2}, [r0,:64], r12
325     bx          lr
326 .endfunc
327
328 function x264_predict_8x8_vr_neon
329     add         r1, #8
330     mov         r12, #FDEC_STRIDE
331     vld1.8      {d4,d5}, [r1,:64]
332
333     vext.8      q1, q2, q2, #14
334     vext.8      q0, q2, q2, #15
335
336     vhadd.u8    q3, q2, q1
337     vrhadd.u8   q2, q2, q0
338     vrhadd.u8   q0, q0, q3
339
340     vmov        d2, d0
341
342     vst1.8      {d5}, [r0,:64], r12
343     vuzp.8      d2, d0
344     vst1.8      {d1}, [r0,:64], r12
345     vext.8      d6, d0, d5, #7
346     vext.8      d3, d2, d1, #7
347     vst1.8      {d6}, [r0,:64], r12
348     vst1.8      {d3}, [r0,:64], r12
349     vext.8      d6, d0, d5, #6
350     vext.8      d3, d2, d1, #6
351     vst1.8      {d6}, [r0,:64], r12
352     vst1.8      {d3}, [r0,:64], r12
353     vext.8      d6, d0, d5, #5
354     vext.8      d3, d2, d1, #5
355     vst1.8      {d6}, [r0,:64], r12
356     vst1.8      {d3}, [r0,:64], r12
357     bx          lr
358 .endfunc
359
360 function x264_predict_8x8_hd_neon
361     mov         r12, #FDEC_STRIDE
362     add         r1, #7
363
364     vld1.8      {d2,d3}, [r1]
365     vext.8      q3, q1, q1, #1
366     vext.8      q2, q1, q1, #2
367
368     vrhadd.u8   q8, q1, q3
369
370     vhadd.u8    q1, q2
371     vrhadd.u8   q0, q1, q3
372
373     vzip.8      d16, d0
374
375     vext.8      d2, d0, d1, #6
376     vext.8      d3, d0, d1, #4
377     vst1.8      {d2}, [r0,:64], r12
378     vext.8      d2, d0, d1, #2
379     vst1.8      {d3}, [r0,:64], r12
380     vst1.8      {d2}, [r0,:64], r12
381     vext.8      d2, d16, d0, #6
382     vst1.8      {d0}, [r0,:64], r12
383     vext.8      d3, d16, d0, #4
384     vst1.8      {d2}, [r0,:64], r12
385     vext.8      d2, d16, d0, #2
386     vst1.8      {d3}, [r0,:64], r12
387     vst1.8      {d2}, [r0,:64], r12
388     vst1.8      {d16}, [r0,:64], r12
389
390     bx          lr
391 .endfunc
392
393 function x264_predict_8x8_hu_neon
394     mov         r12, #FDEC_STRIDE
395     add         r1, #7
396     vld1.8      {d7}, [r1]
397     vdup.8      d6, d7[0]
398     vrev64.8    d7, d7
399
400     vext.8      d4, d7, d6, #2
401     vext.8      d2, d7, d6, #1
402
403     vhadd.u8    d16, d7, d4
404     vrhadd.u8   d0, d2, d7
405     vrhadd.u8   d1, d16, d2
406
407     vzip.8      d0, d1
408
409     vdup.16     q1, d1[3]
410
411     vext.8      q2, q0, q1, #2
412     vext.8      q3, q0, q1, #4
413     vext.8      q8, q0, q1, #6
414     vst1.8      {d0}, [r0,:64], r12
415     vst1.8      {d4}, [r0,:64], r12
416     vst1.8      {d6}, [r0,:64], r12
417     vst1.8      {d16}, [r0,:64], r12
418
419     vst1.8      {d1}, [r0,:64], r12
420     vst1.8      {d5}, [r0,:64], r12
421     vst1.8      {d7}, [r0,:64], r12
422     vst1.8      {d17}, [r0,:64]
423     bx          lr
424 .endfunc
425
426 function x264_predict_8x8c_dc_top_neon
427     sub         r2,  r0,  #FDEC_STRIDE
428     mov         r1,  #FDEC_STRIDE
429     vld1.8      {d0}, [r2,:64]
430     vpaddl.u8   d0,  d0
431     vpadd.u16   d0,  d0,  d0
432     vrshrn.u16  d0,  q0,  #2
433     vdup.8      d1,  d0[1]
434     vdup.8      d0,  d0[0]
435     vtrn.32     d0,  d1
436     b           pred8x8_dc_end
437 .endfunc
438
439 function x264_predict_8x8c_dc_left_neon
440     mov         r1,  #FDEC_STRIDE
441     sub         r2,  r0,  #1
442     ldcol.8     d0,  r2,  r1
443     vpaddl.u8   d0,  d0
444     vpadd.u16   d0,  d0,  d0
445     vrshrn.u16  d0,  q0,  #2
446     vdup.8      d1,  d0[1]
447     vdup.8      d0,  d0[0]
448     b           pred8x8_dc_end
449 .endfunc
450
451 function x264_predict_8x8c_dc_neon
452     sub         r2,  r0,  #FDEC_STRIDE
453     mov         r1,  #FDEC_STRIDE
454     vld1.8      {d0}, [r2,:64]
455     sub         r2,  r0,  #1
456     ldcol.8     d1,  r2,  r1
457     vtrn.32     d0,  d1
458     vpaddl.u8   q0,  q0
459     vpadd.u16   d0,  d0,  d1
460     vpadd.u16   d1,  d0,  d0
461     vrshrn.u16  d2,  q0,  #3
462     vrshrn.u16  d3,  q0,  #2
463     vdup.8      d0,  d2[4]
464     vdup.8      d1,  d3[3]
465     vdup.8      d4,  d3[2]
466     vdup.8      d5,  d2[5]
467     vtrn.32     q0,  q2
468 pred8x8_dc_end:
469     add         r2,  r0,  r1,  lsl #2
470 .rept 4
471     vst1.8      {d0}, [r0,:64], r1
472     vst1.8      {d1}, [r2,:64], r1
473 .endr
474     bx          lr
475 .endfunc
476
477 function x264_predict_8x8c_h_neon
478     sub         r1, r0, #1
479     mov         ip, #FDEC_STRIDE
480 .rept 4
481     vld1.8      {d0[]}, [r1], ip
482     vld1.8      {d2[]}, [r1], ip
483     vst1.64     {d0}, [r0,:64], ip
484     vst1.64     {d2}, [r0,:64], ip
485 .endr
486     bx          lr
487 .endfunc
488
489 function x264_predict_8x8c_v_neon
490     sub         r0, r0, #FDEC_STRIDE
491     mov         ip, #FDEC_STRIDE
492     vld1.64     {d0}, [r0,:64], ip
493 .rept 8
494     vst1.64     {d0}, [r0,:64], ip
495 .endr
496     bx          lr
497 .endfunc
498
499 function x264_predict_8x8c_p_neon
500     sub         r3,  r0,  #FDEC_STRIDE
501     mov         r1,  #FDEC_STRIDE
502     add         r2,  r3,  #4
503     sub         r3,  r3,  #1
504     vld1.32     {d0[0]}, [r3]
505     vld1.32     {d2[0]}, [r2,:32], r1
506     ldcol.8     d0,  r3,  r1,  4,  hi=1
507     add         r3,  r3,  r1
508     ldcol.8     d3,  r3,  r1,  4
509     vaddl.u8    q8,  d2,  d3
510     vrev32.8    d0,  d0
511     vtrn.32     d2,  d3
512     vsubl.u8    q2,  d2,  d0
513     movrel      r3,  p16weight
514     vld1.16     {q0}, [r3,:128]
515     vmul.s16    d4,  d4,  d0
516     vmul.s16    d5,  d5,  d0
517     vpadd.i16   d4,  d4,  d5
518     vpaddl.s16  d4,  d4
519     vshl.i32    d5,  d4,  #4
520     vadd.s32    d4,  d4,  d5
521     vrshrn.s32  d4,  q2,  #5
522     mov         r3,  #0
523     vtrn.16     d4,  d5
524     vadd.i16    d2,  d4,  d5
525     vshl.i16    d3,  d2,  #2
526     vrev64.16   d16, d16
527     vsub.i16    d3,  d3,  d2
528     vadd.i16    d16, d16, d0
529     vshl.i16    d2,  d16, #4
530     vsub.i16    d2,  d2,  d3
531     vshl.i16    d3,  d4,  #3
532     vext.16     q0,  q0,  q0,  #7
533     vsub.i16    d6,  d5,  d3
534     vmov.16     d0[0], r3
535     vmul.i16    q0,  q0,  d4[0]
536     vdup.16     q1,  d2[0]
537     vdup.16     q2,  d4[0]
538     vdup.16     q3,  d6[0]
539     vshl.i16    q2,  q2,  #3
540     vadd.i16    q1,  q1,  q0
541     vadd.i16    q3,  q3,  q2
542     mov         r3,  #8
543 1:
544     vqshrun.s16 d0,  q1,  #5
545     vadd.i16    q1,  q1,  q3
546     vst1.8      {d0}, [r0,:64], r1
547     subs        r3,  r3,  #1
548     bne         1b
549     bx          lr
550 .endfunc
551
552
553 function x264_predict_16x16_dc_top_neon
554     sub         r2,  r0,  #FDEC_STRIDE
555     mov         r1,  #FDEC_STRIDE
556     vld1.8      {q0}, [r2,:128]
557     add16x8     q0,  d0,  d1,  d0,  d1
558     vrshrn.u16  d0,  q0,  #4
559     vdup.8      q0,  d0[0]
560     b           pred16x16_dc_end
561 .endfunc
562
563 function x264_predict_16x16_dc_left_neon
564     mov         r1,  #FDEC_STRIDE
565     sub         r2,  r0,  #1
566     ldcol.8     d0,  r2,  r1
567     ldcol.8     d1,  r2,  r1
568     add16x8     q0,  d0,  d1,  d0,  d1
569     vrshrn.u16  d0,  q0,  #4
570     vdup.8      q0,  d0[0]
571     b           pred16x16_dc_end
572 .endfunc
573
574 function x264_predict_16x16_dc_neon
575     sub         r3, r0, #FDEC_STRIDE
576     sub         r0, r0, #1
577     vld1.64     {d0-d1}, [r3,:128]
578     ldrb        ip, [r0], #FDEC_STRIDE
579     vaddl.u8    q0, d0, d1
580     ldrb        r1, [r0], #FDEC_STRIDE
581     vadd.u16    d0, d0, d1
582     vpadd.u16   d0, d0, d0
583     vpadd.u16   d0, d0, d0
584 .rept 4
585     ldrb        r2, [r0], #FDEC_STRIDE
586     add         ip, ip, r1
587     ldrb        r3, [r0], #FDEC_STRIDE
588     add         ip, ip, r2
589     ldrb        r1, [r0], #FDEC_STRIDE
590     add         ip, ip, r3
591 .endr
592     ldrb        r2, [r0], #FDEC_STRIDE
593     add         ip, ip, r1
594     ldrb        r3, [r0], #FDEC_STRIDE
595     add         ip, ip, r2
596
597     sub         r0, r0, #FDEC_STRIDE*16
598     add         ip, ip, r3
599     vdup.16     d1, ip
600     vadd.u16    d0, d0, d1
601     mov         r1, #FDEC_STRIDE
602     add         r0, r0, #1
603     vrshr.u16   d0, d0, #5
604     vdup.8      q0, d0[0]
605 pred16x16_dc_end:
606 .rept 16
607     vst1.64     {d0-d1}, [r0,:128], r1
608 .endr
609     bx          lr
610 .endfunc
611
612 function x264_predict_16x16_h_neon
613     sub         r1, r0, #1
614     mov         ip, #FDEC_STRIDE
615 .rept 8
616     vld1.8      {d0[]}, [r1], ip
617     vmov        d1, d0
618     vld1.8      {d2[]}, [r1], ip
619     vmov        d3, d2
620     vst1.64     {d0-d1}, [r0,:128], ip
621     vst1.64     {d2-d3}, [r0,:128], ip
622 .endr
623     bx          lr
624 .endfunc
625
626 function x264_predict_16x16_v_neon
627     sub         r0, r0, #FDEC_STRIDE
628     mov         ip, #FDEC_STRIDE
629     vld1.64     {d0-d1}, [r0,:128], ip
630 .rept 16
631     vst1.64     {d0-d1}, [r0,:128], ip
632 .endr
633     bx          lr
634 .endfunc
635
636 function x264_predict_16x16_p_neon
637     sub         r3,  r0,  #FDEC_STRIDE
638     mov         r1,  #FDEC_STRIDE
639     add         r2,  r3,  #8
640     sub         r3,  r3,  #1
641     vld1.8      {d0}, [r3]
642     vld1.8      {d2}, [r2,:64], r1
643     ldcol.8     d1,  r3,  r1
644     add         r3,  r3,  r1
645     ldcol.8     d3,  r3,  r1
646     vrev64.8    q0,  q0
647     vaddl.u8    q8,  d2,  d3
648     vsubl.u8    q2,  d2,  d0
649     vsubl.u8    q3,  d3,  d1
650     movrel      r3,  p16weight
651     vld1.8      {q0}, [r3,:128]
652     vmul.s16    q2,  q2,  q0
653     vmul.s16    q3,  q3,  q0
654     vadd.i16    d4,  d4,  d5
655     vadd.i16    d5,  d6,  d7
656     vpadd.i16   d4,  d4,  d5
657     vpadd.i16   d4,  d4,  d4
658     vshll.s16   q3,  d4,  #2
659     vaddw.s16   q2,  q3,  d4
660     vrshrn.s32  d4,  q2,  #6
661     mov         r3,  #0
662     vtrn.16     d4,  d5
663     vadd.i16    d2,  d4,  d5
664     vshl.i16    d3,  d2,  #3
665     vrev64.16   d16, d17
666     vsub.i16    d3,  d3,  d2
667     vadd.i16    d16, d16, d0
668     vshl.i16    d2,  d16, #4
669     vsub.i16    d2,  d2,  d3
670     vshl.i16    d3,  d4,  #4
671     vext.16     q0,  q0,  q0,  #7
672     vsub.i16    d6,  d5,  d3
673     vmov.16     d0[0], r3
674     vmul.i16    q0,  q0,  d4[0]
675     vdup.16     q1,  d2[0]
676     vdup.16     q2,  d4[0]
677     vdup.16     q3,  d6[0]
678     vshl.i16    q2,  q2,  #3
679     vadd.i16    q1,  q1,  q0
680     vadd.i16    q3,  q3,  q2
681     mov         r3,  #16
682 1:
683     vqshrun.s16 d0,  q1,  #5
684     vadd.i16    q1,  q1,  q2
685     vqshrun.s16 d1,  q1,  #5
686     vadd.i16    q1,  q1,  q3
687     vst1.8      {q0}, [r0,:128], r1
688     subs        r3,  r3,  #1
689     bne         1b
690     bx          lr
691 .endfunc