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