Bump dates to 2011
[x262.git] / common / arm / dct-a.S
1 /****************************************************************************
2  * dct-a.S: arm transform and zigzag
3  *****************************************************************************
4  * Copyright (C) 2009-2011 x264 project
5  *
6  * Authors: David Conrad <lessen42@gmail.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
21  *
22  * This program is also available under a commercial proprietary license.
23  * For more information, contact us at licensing@x264.com.
24  *****************************************************************************/
25
26 #include "asm.S"
27
28 .fpu neon
29
30 .section .rodata
31 .align 4
32
33 scan4x4_frame:
34 .byte    0,1,   8,9,   2,3,   4,5
35 .byte    2,3,   8,9,  16,17, 10,11
36 .byte   12,13,  6,7,  14,15, 20,21
37 .byte   10,11, 12,13,  6,7,  14,15
38
39 .text
40
41 // sum = a + (b>>shift)   sub = (a>>shift) - b
42 .macro SUMSUB_SHR shift sum sub a b t0 t1
43     vshr.s16    \t0,  \b, #\shift
44     vshr.s16    \t1,  \a, #\shift
45     vadd.s16    \sum, \a, \t0
46     vsub.s16    \sub, \t1, \b
47 .endm
48
49 // sum = (a>>shift) + b   sub = a - (b>>shift)
50 .macro SUMSUB_SHR2 shift sum sub a b t0 t1
51     vshr.s16    \t0,  \a, #\shift
52     vshr.s16    \t1,  \b, #\shift
53     vadd.s16    \sum, \t0, \b
54     vsub.s16    \sub, \a, \t1
55 .endm
56
57 // a += 1.5*ma   b -= 1.5*mb
58 .macro SUMSUB_15 a b ma mb t0 t1
59     vshr.s16    \t0, \ma, #1
60     vshr.s16    \t1, \mb, #1
61     vadd.s16    \t0, \t0, \ma
62     vadd.s16    \t1, \t1, \mb
63     vadd.s16    \a,  \a,  \t0
64     vsub.s16    \b,  \b,  \t1
65 .endm
66
67
68 function x264_dct4x4dc_neon
69     vld1.64         {d0-d3}, [r0,:128]
70     SUMSUB_ABCD     d4, d5, d6, d7, d0, d1, d2, d3
71     SUMSUB_ABCD     d0, d2, d3, d1, d4, d6, d5, d7
72
73     vmov.s16        d31, #1
74     HADAMARD        1, sumsub, q2, q3, q0, q1
75     vtrn.32         d4,  d5
76     vadd.s16        d16, d4,  d31
77     vtrn.32         d6,  d7
78     vadd.s16        d17, d6,  d31
79     vrhadd.s16      d0,  d4,  d5
80     vhsub.s16       d1,  d16, d5
81     vhsub.s16       d2,  d17, d7
82     vrhadd.s16      d3,  d6,  d7
83     vst1.64         {d0-d3}, [r0,:128]
84     bx              lr
85 .endfunc
86
87 function x264_idct4x4dc_neon
88     vld1.64         {d0-d3}, [r0,:128]
89     SUMSUB_ABCD     d4, d5, d6, d7, d0, d1, d2, d3
90     SUMSUB_ABCD     d0, d2, d3, d1, d4, d6, d5, d7
91
92     HADAMARD        1, sumsub, q2, q3, q0, q1
93     HADAMARD        2, sumsub, d0, d1, d4, d5
94     HADAMARD        2, sumsub, d3, d2, d6, d7
95     vst1.64         {d0-d3}, [r0,:128]
96     bx              lr
97 .endfunc
98
99
100 .macro DCT_1D d0 d1 d2 d3  d4 d5 d6 d7
101     SUMSUB_AB       \d1, \d6, \d5, \d6
102     SUMSUB_AB       \d3, \d7, \d4, \d7
103     vadd.s16        \d0, \d3, \d1
104     vadd.s16        \d4, \d7, \d7
105     vadd.s16        \d5, \d6, \d6
106     vsub.s16        \d2, \d3, \d1
107     vadd.s16        \d1, \d4, \d6
108     vsub.s16        \d3, \d7, \d5
109 .endm
110
111 function x264_sub4x4_dct_neon
112     mov             r3, #FENC_STRIDE
113     mov             ip, #FDEC_STRIDE
114     vld1.32         {d0[]}, [r1,:32], r3
115     vld1.32         {d1[]}, [r2,:32], ip
116     vld1.32         {d2[]}, [r1,:32], r3
117     vsubl.u8        q8,  d0,  d1
118     vld1.32         {d3[]}, [r2,:32], ip
119     vld1.32         {d4[]}, [r1,:32], r3
120     vsubl.u8        q9,  d2,  d3
121     vld1.32         {d5[]}, [r2,:32], ip
122     vld1.32         {d6[]}, [r1,:32], r3
123     vsubl.u8        q10, d4,  d5
124     vld1.32         {d7[]}, [r2,:32], ip
125     vsubl.u8        q11, d6,  d7
126
127     DCT_1D          d0, d1, d2, d3, d16, d18, d20, d22
128     TRANSPOSE4x4_16 d0, d1, d2, d3
129     DCT_1D          d4, d5, d6, d7, d0, d1, d2, d3
130     vst1.64         {d4-d7}, [r0,:128]
131     bx              lr
132 .endfunc
133
134 function x264_sub8x4_dct_neon
135     vld1.64         {d0}, [r1,:64], r3
136     vld1.64         {d1}, [r2,:64], ip
137     vsubl.u8        q8,  d0,  d1
138     vld1.64         {d2}, [r1,:64], r3
139     vld1.64         {d3}, [r2,:64], ip
140     vsubl.u8        q9,  d2,  d3
141     vld1.64         {d4}, [r1,:64], r3
142     vld1.64         {d5}, [r2,:64], ip
143     vsubl.u8        q10, d4,  d5
144     vld1.64         {d6}, [r1,:64], r3
145     vld1.64         {d7}, [r2,:64], ip
146     vsubl.u8        q11, d6,  d7
147
148     DCT_1D          q0, q1, q2, q3,  q8, q9, q10, q11
149     TRANSPOSE4x4_16 q0, q1, q2, q3
150
151     SUMSUB_AB       q8,  q12, q0,  q3
152     SUMSUB_AB       q9,  q10, q1,  q2
153     vadd.i16        q13, q12, q12
154     vadd.i16        q11, q10, q10
155     vadd.i16        d0,  d16, d18
156     vadd.i16        d1,  d26, d20
157     vsub.i16        d2,  d16, d18
158     vsub.i16        d3,  d24, d22
159     vst1.64         {d0-d1}, [r0,:128]!
160     vadd.i16        d4,  d17, d19
161     vadd.i16        d5,  d27, d21
162     vst1.64         {d2-d3}, [r0,:128]!
163     vsub.i16        d6,  d17, d19
164     vsub.i16        d7,  d25, d23
165     vst1.64         {d4-d5}, [r0,:128]!
166     vst1.64         {d6-d7}, [r0,:128]!
167     bx              lr
168 .endfunc
169
170 function x264_sub8x8_dct_neon
171     push            {lr}
172     mov             r3, #FENC_STRIDE
173     mov             ip, #FDEC_STRIDE
174     bl              x264_sub8x4_dct_neon
175     pop             {lr}
176     b               x264_sub8x4_dct_neon
177 .endfunc
178
179 function x264_sub16x16_dct_neon
180     push            {lr}
181     mov             r3, #FENC_STRIDE
182     mov             ip, #FDEC_STRIDE
183     bl              x264_sub8x4_dct_neon
184     bl              x264_sub8x4_dct_neon
185     sub             r1, r1, #8*FENC_STRIDE-8
186     sub             r2, r2, #8*FDEC_STRIDE-8
187     bl              x264_sub8x4_dct_neon
188     bl              x264_sub8x4_dct_neon
189     sub             r1, r1, #8
190     sub             r2, r2, #8
191     bl              x264_sub8x4_dct_neon
192     bl              x264_sub8x4_dct_neon
193     sub             r1, r1, #8*FENC_STRIDE-8
194     sub             r2, r2, #8*FDEC_STRIDE-8
195     bl              x264_sub8x4_dct_neon
196     pop             {lr}
197     b               x264_sub8x4_dct_neon
198 .endfunc
199
200
201 .macro DCT8_1D type
202     SUMSUB_AB       q2,  q1,  q11, q12  // s34/d34
203     SUMSUB_AB       q3,  q11, q10, q13  // s25/d25
204     SUMSUB_AB       q13, q10, q9,  q14  // s16/d16
205     SUMSUB_AB       q14, q8,  q8,  q15  // s07/d07
206
207     SUMSUB_AB       q9,  q2,  q14, q2   // a0/a2
208     SUMSUB_AB       q12, q14, q13, q3   // a1/a3
209
210     SUMSUB_AB       q3,  q13, q8,  q1   // a6/a5
211     vshr.s16        q0,  q10, #1
212     vshr.s16        q15, q11, #1
213     vadd.s16        q0,  q0,  q10
214     vadd.s16        q15, q15, q11
215     vsub.s16        q3,  q3,  q0
216     vsub.s16        q13, q13, q15
217
218     SUMSUB_AB       q0,  q15, q10, q11  // a4/a7
219     vshr.s16        q10, q8,  #1
220     vshr.s16        q11, q1,  #1
221     vadd.s16        q10, q10, q8
222     vadd.s16        q11, q11, q1
223     vadd.s16        q10, q0,  q10
224     vadd.s16        q15, q15, q11
225
226     SUMSUB_AB       q8,  q12, q9,  q12
227     SUMSUB_SHR   2, q9,  q15, q10, q15,  q0, q1
228     SUMSUB_SHR   1, q10, q14, q2,  q14,  q0, q1
229     SUMSUB_SHR2  2, q11, q13, q3,  q13,  q0, q1
230 .endm
231
232 function x264_sub8x8_dct8_neon
233     mov             r3, #FENC_STRIDE
234     mov             ip, #FDEC_STRIDE
235     vld1.64         {d16}, [r1,:64], r3
236     vld1.64         {d17}, [r2,:64], ip
237     vsubl.u8        q8,  d16, d17
238     vld1.64         {d18}, [r1,:64], r3
239     vld1.64         {d19}, [r2,:64], ip
240     vsubl.u8        q9,  d18, d19
241     vld1.64         {d20}, [r1,:64], r3
242     vld1.64         {d21}, [r2,:64], ip
243     vsubl.u8        q10, d20, d21
244     vld1.64         {d22}, [r1,:64], r3
245     vld1.64         {d23}, [r2,:64], ip
246     vsubl.u8        q11, d22, d23
247     vld1.64         {d24}, [r1,:64], r3
248     vld1.64         {d25}, [r2,:64], ip
249     vsubl.u8        q12, d24, d25
250     vld1.64         {d26}, [r1,:64], r3
251     vld1.64         {d27}, [r2,:64], ip
252     vsubl.u8        q13, d26, d27
253     vld1.64         {d28}, [r1,:64], r3
254     vld1.64         {d29}, [r2,:64], ip
255     vsubl.u8        q14, d28, d29
256     vld1.64         {d30}, [r1,:64], r3
257     vld1.64         {d31}, [r2,:64], ip
258     vsubl.u8        q15, d30, d31
259
260     DCT8_1D row
261     vswp            d17, d24    // 8, 12
262     vswp            d21, d28    // 10,14
263     vtrn.32         q8,  q10
264     vtrn.32         q12, q14
265
266     vswp            d19, d26    // 9, 13
267     vswp            d23, d30    // 11,15
268     vtrn.32         q9,  q11
269     vtrn.32         q13, q15
270
271     vtrn.16         q10, q11
272     vtrn.16         q12, q13
273     vtrn.16         q8,  q9
274     vtrn.16         q14, q15
275     DCT8_1D col
276
277     vst1.64         {d16-d19}, [r0,:128]!
278     vst1.64         {d20-d23}, [r0,:128]!
279     vst1.64         {d24-d27}, [r0,:128]!
280     vst1.64         {d28-d31}, [r0,:128]!
281     bx              lr
282 .endfunc
283
284 function x264_sub16x16_dct8_neon
285     push            {lr}
286     bl              x264_sub8x8_dct8_neon
287     sub             r1,  r1,  #FENC_STRIDE*8 - 8
288     sub             r2,  r2,  #FDEC_STRIDE*8 - 8
289     bl              x264_sub8x8_dct8_neon
290     sub             r1,  r1,  #8
291     sub             r2,  r2,  #8
292     bl              x264_sub8x8_dct8_neon
293     pop             {lr}
294     sub             r1,  r1,  #FENC_STRIDE*8 - 8
295     sub             r2,  r2,  #FDEC_STRIDE*8 - 8
296     b               x264_sub8x8_dct8_neon
297 .endfunc
298
299
300 // First part of IDCT (minus final SUMSUB_BA)
301 .macro IDCT_1D d4 d5 d6 d7 d0 d1 d2 d3
302     SUMSUB_AB       \d4, \d5, \d0, \d2
303     vshr.s16        \d7, \d1, #1
304     vshr.s16        \d6, \d3, #1
305     vsub.s16        \d7, \d7, \d3
306     vadd.s16        \d6, \d6, \d1
307 .endm
308
309 function x264_add4x4_idct_neon
310     mov             r2, #FDEC_STRIDE
311     vld1.64         {d0-d3}, [r1,:128]
312
313     IDCT_1D         d4, d5, d6, d7, d0, d1, d2, d3
314     vld1.32         {d30[0]}, [r0,:32], r2
315     SUMSUB_AB       q0, q1, q2, q3
316
317     TRANSPOSE4x4_16 d0, d1, d3, d2
318
319     IDCT_1D         d4, d5, d6, d7, d0, d1, d3, d2
320     vld1.32         {d30[1]}, [r0,:32], r2
321     SUMSUB_AB       q0, q1, q2, q3
322
323     vrshr.s16       q0, q0, #6
324     vld1.32         {d31[1]}, [r0,:32], r2
325     vrshr.s16       q1, q1, #6
326     vld1.32         {d31[0]}, [r0,:32], r2
327
328     sub             r0, r0, r2, lsl #2
329     vaddw.u8        q0, q0, d30
330     vaddw.u8        q1, q1, d31
331     vqmovun.s16     d0, q0
332     vqmovun.s16     d2, q1
333
334     vst1.32         {d0[0]}, [r0,:32], r2
335     vst1.32         {d0[1]}, [r0,:32], r2
336     vst1.32         {d2[1]}, [r0,:32], r2
337     vst1.32         {d2[0]}, [r0,:32], r2
338     bx              lr
339 .endfunc
340
341 function x264_add8x4_idct_neon
342     vld1.64         {d0-d3}, [r1,:128]!
343     IDCT_1D         d16, d18, d20, d22, d0, d1, d2, d3
344     vld1.64         {d4-d7}, [r1,:128]!
345     IDCT_1D         d17, d19, d21, d23, d4, d5, d6, d7
346     SUMSUB_AB       q0,  q3,  q8,  q10
347     SUMSUB_AB       q1,  q2,  q9,  q11
348
349     TRANSPOSE4x4_16 q0,  q1,  q2,  q3
350
351     IDCT_1D         q8,  q9,  q10, q11, q0, q1, q2, q3
352     SUMSUB_AB       q0,  q3,  q8,  q10
353     SUMSUB_AB       q1,  q2,  q9,  q11
354
355     vrshr.s16       q0,  q0,  #6
356     vld1.32         {d28}, [r0,:64], r2
357     vrshr.s16       q1,  q1,  #6
358     vld1.32         {d29}, [r0,:64], r2
359     vrshr.s16       q2,  q2,  #6
360     vld1.32         {d30}, [r0,:64], r2
361     vrshr.s16       q3,  q3,  #6
362     vld1.32         {d31}, [r0,:64], r2
363
364     sub             r0,  r0,  r2,  lsl #2
365     vaddw.u8        q0,  q0,  d28
366     vaddw.u8        q1,  q1,  d29
367     vaddw.u8        q2,  q2,  d30
368     vaddw.u8        q3,  q3,  d31
369
370     vqmovun.s16     d0,  q0
371     vqmovun.s16     d1,  q1
372     vst1.32         {d0}, [r0,:64], r2
373     vqmovun.s16     d2,  q2
374     vst1.32         {d1}, [r0,:64], r2
375     vqmovun.s16     d3,  q3
376     vst1.32         {d2}, [r0,:64], r2
377     vst1.32         {d3}, [r0,:64], r2
378     bx              lr
379 .endfunc
380
381 function x264_add8x8_idct_neon
382     mov             r2, #FDEC_STRIDE
383     mov             ip, lr
384     bl              x264_add8x4_idct_neon
385     mov             lr, ip
386     b               x264_add8x4_idct_neon
387 .endfunc
388
389 function x264_add16x16_idct_neon
390     mov             r2, #FDEC_STRIDE
391     mov             ip, lr
392     bl              x264_add8x4_idct_neon
393     bl              x264_add8x4_idct_neon
394     sub             r0, r0, #8*FDEC_STRIDE-8
395     bl              x264_add8x4_idct_neon
396     bl              x264_add8x4_idct_neon
397     sub             r0, r0, #8
398     bl              x264_add8x4_idct_neon
399     bl              x264_add8x4_idct_neon
400     sub             r0, r0, #8*FDEC_STRIDE-8
401     bl              x264_add8x4_idct_neon
402     mov             lr, ip
403     b               x264_add8x4_idct_neon
404 .endfunc
405
406
407 .macro IDCT8_1D type
408 .ifc \type, col
409     vswp            d21, d28
410 .endif
411     SUMSUB_AB       q0,  q1,  q8,  q12              // a0/a2
412 .ifc \type, row
413     vld1.64         {d28-d31}, [r1,:128]!
414 .else
415     vswp            d19, d26
416 .endif
417     SUMSUB_SHR   1, q2,  q3,  q10, q14,  q8, q12    // a6/a4
418 .ifc \type, col
419     vswp            d23, d30
420 .endif
421     SUMSUB_AB       q8,  q10, q13, q11
422     SUMSUB_15       q8,  q10, q9,  q15,  q12, q14   // a7/a1
423     SUMSUB_AB       q14, q15, q15, q9
424     SUMSUB_15       q15, q14, q13, q11,  q12, q9    // a5/a3
425
426     SUMSUB_SHR   2, q13, q14, q14, q15,  q11, q9    // b3/b5
427     SUMSUB_SHR2  2, q12, q15, q8,  q10,  q11, q9    // b1/b7
428
429     SUMSUB_AB       q10, q2,  q0,  q2               // b0/b6
430     SUMSUB_AB       q11, q3,  q1,  q3               // b2/b4
431
432     SUMSUB_AB       q8,  q15, q10, q15
433     SUMSUB_AB       q9,  q14, q11, q14
434     SUMSUB_AB       q10, q13, q3,  q13
435 .ifc \type, row
436     vtrn.16         q8,  q9
437 .endif
438     SUMSUB_AB       q11, q12, q2,  q12
439 .endm
440
441 function x264_add8x8_idct8_neon
442     mov             r2,  #FDEC_STRIDE
443     vld1.64         {d16-d19}, [r1,:128]!
444     vld1.64         {d20-d23}, [r1,:128]!
445     vld1.64         {d24-d27}, [r1,:128]!
446
447     IDCT8_1D row
448     vtrn.16         q10, q11
449     vtrn.16         q12, q13
450     vtrn.16         q14, q15
451     vtrn.32         q8,  q10
452     vtrn.32         q9,  q11
453     vtrn.32         q12, q14
454     vtrn.32         q13, q15
455     vswp            d17, d24
456     IDCT8_1D col
457
458     vld1.64         {d0}, [r0,:64], r2
459     vrshr.s16       q8,  q8,  #6
460     vld1.64         {d1}, [r0,:64], r2
461     vrshr.s16       q9,  q9,  #6
462     vld1.64         {d2}, [r0,:64], r2
463     vrshr.s16       q10, q10, #6
464     vld1.64         {d3}, [r0,:64], r2
465     vrshr.s16       q11, q11, #6
466     vld1.64         {d4}, [r0,:64], r2
467     vrshr.s16       q12, q12, #6
468     vld1.64         {d5}, [r0,:64], r2
469     vrshr.s16       q13, q13, #6
470     vld1.64         {d6}, [r0,:64], r2
471     vrshr.s16       q14, q14, #6
472     vld1.64         {d7}, [r0,:64], r2
473     vrshr.s16       q15, q15, #6
474     sub             r0,  r0,  r2,  lsl #3
475
476     vaddw.u8        q8,  q8,  d0
477     vaddw.u8        q9,  q9,  d1
478     vaddw.u8        q10, q10, d2
479     vqmovun.s16     d0,  q8
480     vqmovun.s16     d1,  q9
481     vqmovun.s16     d2,  q10
482     vaddw.u8        q11, q11, d3
483     vst1.64         {d0}, [r0,:64], r2
484     vaddw.u8        q12, q12, d4
485     vst1.64         {d1}, [r0,:64], r2
486     vaddw.u8        q13, q13, d5
487     vst1.64         {d2}, [r0,:64], r2
488     vqmovun.s16     d3,  q11
489     vqmovun.s16     d4,  q12
490     vaddw.u8        q14, q14, d6
491     vaddw.u8        q15, q15, d7
492     vst1.64         {d3}, [r0,:64], r2
493     vqmovun.s16     d5,  q13
494     vst1.64         {d4}, [r0,:64], r2
495     vqmovun.s16     d6,  q14
496     vqmovun.s16     d7,  q15
497     vst1.64         {d5}, [r0,:64], r2
498     vst1.64         {d6}, [r0,:64], r2
499     vst1.64         {d7}, [r0,:64], r2
500     bx              lr
501 .endfunc
502
503 function x264_add16x16_idct8_neon
504     mov             ip,  lr
505     bl              x264_add8x8_idct8_neon
506     sub             r0,  r0,  #8*FDEC_STRIDE-8
507     bl              x264_add8x8_idct8_neon
508     sub             r0,  r0,  #8
509     bl              x264_add8x8_idct8_neon
510     sub             r0,  r0,  #8*FDEC_STRIDE-8
511     mov             lr,  ip
512     b               x264_add8x8_idct8_neon
513 .endfunc
514
515
516 function x264_add8x8_idct_dc_neon
517     mov             r2,  #FDEC_STRIDE
518     vld1.64         {d16}, [r1,:64]
519     vrshr.s16       d16, d16, #6
520     vld1.64         {d0}, [r0,:64], r2
521     vmov.i16        q15, #0
522     vld1.64         {d1}, [r0,:64], r2
523     vld1.64         {d2}, [r0,:64], r2
524     vdup.16         d20, d16[0]
525     vld1.64         {d3}, [r0,:64], r2
526     vdup.16         d21, d16[1]
527     vld1.64         {d4}, [r0,:64], r2
528     vdup.16         d22, d16[2]
529     vld1.64         {d5}, [r0,:64], r2
530     vdup.16         d23, d16[3]
531     vld1.64         {d6}, [r0,:64], r2
532     vsub.s16        q12, q15, q10
533     vld1.64         {d7}, [r0,:64], r2
534     vsub.s16        q13, q15, q11
535
536     sub             r0,  r0,  #8*FDEC_STRIDE
537
538     vqmovun.s16     d20, q10
539     vqmovun.s16     d22, q11
540     vqmovun.s16     d24, q12
541     vqmovun.s16     d26, q13
542
543     vmov            d21, d20
544     vqadd.u8        q0,  q0,  q10
545     vmov            d23, d22
546     vqadd.u8        q1,  q1,  q10
547     vmov            d25, d24
548     vqadd.u8        q2,  q2,  q11
549     vmov            d27, d26
550     vqadd.u8        q3,  q3,  q11
551     vqsub.u8        q0,  q0,  q12
552     vqsub.u8        q1,  q1,  q12
553     vqsub.u8        q2,  q2,  q13
554
555     vst1.64         {d0}, [r0,:64], r2
556     vqsub.u8        q3,  q3,  q13
557     vst1.64         {d1}, [r0,:64], r2
558     vst1.64         {d2}, [r0,:64], r2
559     vst1.64         {d3}, [r0,:64], r2
560     vst1.64         {d4}, [r0,:64], r2
561     vst1.64         {d5}, [r0,:64], r2
562     vst1.64         {d6}, [r0,:64], r2
563     vst1.64         {d7}, [r0,:64], r2
564     bx              lr
565 .endfunc
566
567 .macro ADD16x4_IDCT_DC dc
568     vld1.64         {d16-d17}, [r0,:128], r3
569     vld1.64         {d18-d19}, [r0,:128], r3
570     vdup.16         d4,  \dc[0]
571     vdup.16         d5,  \dc[1]
572     vld1.64         {d20-d21}, [r0,:128], r3
573     vdup.16         d6,  \dc[2]
574     vdup.16         d7,  \dc[3]
575     vld1.64         {d22-d23}, [r0,:128], r3
576     vsub.s16        q12, q15, q2
577     vsub.s16        q13, q15, q3
578
579     vqmovun.s16     d4,  q2
580     vqmovun.s16     d5,  q3
581     vqmovun.s16     d6,  q12
582     vqmovun.s16     d7,  q13
583
584     vqadd.u8        q8,  q8,  q2
585     vqadd.u8        q9,  q9,  q2
586     vqadd.u8        q10, q10, q2
587     vqadd.u8        q11, q11, q2
588
589     vqsub.u8        q8,  q8,  q3
590     vqsub.u8        q9,  q9,  q3
591     vqsub.u8        q10, q10, q3
592     vst1.64         {d16-d17}, [r2,:128], r3
593     vqsub.u8        q11, q11, q3
594     vst1.64         {d18-d19}, [r2,:128], r3
595     vst1.64         {d20-d21}, [r2,:128], r3
596     vst1.64         {d22-d23}, [r2,:128], r3
597 .endm
598
599 function x264_add16x16_idct_dc_neon
600     mov             r2,  r0
601     mov             r3,  #FDEC_STRIDE
602     vmov.i16        q15, #0
603
604     vld1.64         {d0-d3}, [r1,:64]
605     vrshr.s16       q0, #6
606     vrshr.s16       q1, #6
607
608     ADD16x4_IDCT_DC d0
609     ADD16x4_IDCT_DC d1
610     ADD16x4_IDCT_DC d2
611     ADD16x4_IDCT_DC d3
612     bx              lr
613 .endfunc
614
615 function x264_sub8x8_dct_dc_neon
616     mov             r3,  #FENC_STRIDE
617     mov             ip,  #FDEC_STRIDE
618     vld1.64         {d16}, [r1,:64], r3
619     vld1.64         {d17}, [r2,:64], ip
620     vsubl.u8        q8,  d16, d17
621     vld1.64         {d18}, [r1,:64], r3
622     vld1.64         {d19}, [r2,:64], ip
623     vsubl.u8        q9,  d18, d19
624     vld1.64         {d20}, [r1,:64], r3
625     vld1.64         {d21}, [r2,:64], ip
626     vsubl.u8        q10, d20, d21
627     vld1.64         {d22}, [r1,:64], r3
628     vadd.s16        q0,  q8,  q9
629     vld1.64         {d23}, [r2,:64], ip
630     vsubl.u8        q11, d22, d23
631     vld1.64         {d24}, [r1,:64], r3
632     vadd.s16        q0,  q0,  q10
633     vld1.64         {d25}, [r2,:64], ip
634     vsubl.u8        q12, d24, d25
635     vld1.64         {d26}, [r1,:64], r3
636     vadd.s16        q0,  q0,  q11
637     vld1.64         {d27}, [r2,:64], ip
638     vsubl.u8        q13, d26, d27
639     vld1.64         {d28}, [r1,:64], r3
640     vld1.64         {d29}, [r2,:64], ip
641     vsubl.u8        q14, d28, d29
642     vld1.64         {d30}, [r1,:64], r3
643     vadd.s16        q1,  q12, q13
644     vld1.64         {d31}, [r2,:64], ip
645     vsubl.u8        q15, d30, d31
646     vadd.s16        q1,  q1,  q14
647
648     vadd.s16        d4,  d0,  d1
649     vadd.s16        q1,  q1,  q15
650     vsub.s16        d5,  d0,  d1
651     vadd.s16        d6,  d2,  d3
652     vsub.s16        d7,  d2,  d3
653     vadd.s16        q0,  q2,  q3
654     vsub.s16        q1,  q2,  q3
655
656     vpadd.s16       d0,  d0,  d2
657     vpadd.s16       d1,  d1,  d3
658     vpadd.s16       d0,  d0,  d1
659     vst1.64         {d0}, [r0,:64]
660     bx              lr
661 .endfunc
662
663
664 function x264_zigzag_scan_4x4_frame_neon
665     movrel      r2, scan4x4_frame
666     vld1.64     {d0-d3},   [r1,:128]
667     vld1.64     {d16-d19}, [r2,:128]
668     vtbl.8      d4, {d0-d1}, d16
669     vtbl.8      d5, {d1-d3}, d17
670     vtbl.8      d6, {d0-d2}, d18
671     vtbl.8      d7, {d2-d3}, d19
672     vst1.64     {d4-d7},   [r0,:128]
673     bx          lr
674 .endfunc