1 /****************************************************************************
2 * dct-a.S: arm transform and zigzag
3 *****************************************************************************
4 * Copyright (C) 2009-2016 x264 project
6 * Authors: David Conrad <lessen42@gmail.com>
7 * Martin Storsjo <martin@martin.st>
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.
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.
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.
23 * This program is also available under a commercial proprietary license.
24 * For more information, contact us at licensing@x264.com.
25 *****************************************************************************/
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
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
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
56 // a += 1.5*ma b -= 1.5*mb
57 .macro SUMSUB_15 a b ma mb t0 t1
60 vadd.s16 \t0, \t0, \ma
61 vadd.s16 \t1, \t1, \mb
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
73 HADAMARD 1, sumsub, q2, q3, q0, q1
82 vst1.64 {d0-d3}, [r0,:128]
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
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]
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
110 function x264_sub4x4_dct_neon
113 vld1.32 {d0[]}, [r1,:32], r3
114 vld1.32 {d1[]}, [r2,:32], ip
115 vld1.32 {d2[]}, [r1,:32], r3
117 vld1.32 {d3[]}, [r2,:32], ip
118 vld1.32 {d4[]}, [r1,:32], r3
120 vld1.32 {d5[]}, [r2,:32], ip
121 vld1.32 {d6[]}, [r1,:32], r3
123 vld1.32 {d7[]}, [r2,:32], ip
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]
133 function x264_sub8x4_dct_neon, export=0
134 vld1.64 {d0}, [r1,:64], r3
135 vld1.64 {d1}, [r2,:64], ip
137 vld1.64 {d2}, [r1,:64], r3
138 vld1.64 {d3}, [r2,:64], ip
140 vld1.64 {d4}, [r1,:64], r3
141 vld1.64 {d5}, [r2,:64], ip
143 vld1.64 {d6}, [r1,:64], r3
144 vld1.64 {d7}, [r2,:64], ip
147 DCT_1D q0, q1, q2, q3, q8, q9, q10, q11
148 TRANSPOSE4x4_16 q0, q1, q2, q3
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]!
169 function x264_sub8x8_dct_neon
173 bl x264_sub8x4_dct_neon
175 b x264_sub8x4_dct_neon
178 function x264_sub16x16_dct_neon
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
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
196 b x264_sub8x4_dct_neon
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
206 SUMSUB_AB q9, q2, q14, q2 // a0/a2
207 SUMSUB_AB q12, q14, q13, q3 // a1/a3
209 SUMSUB_AB q3, q13, q8, q1 // a6/a5
211 vshr.s16 q15, q11, #1
213 vadd.s16 q15, q15, q11
215 vsub.s16 q13, q13, q15
217 SUMSUB_AB q0, q15, q10, q11 // a4/a7
220 vadd.s16 q10, q10, q8
221 vadd.s16 q11, q11, q1
222 vadd.s16 q10, q0, q10
223 vadd.s16 q15, q15, q11
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
231 function x264_sub8x8_dct8_neon
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
260 vswp d17, d24 // 8, 12
261 vswp d21, d28 // 10,14
265 vswp d19, d26 // 9, 13
266 vswp d23, d30 // 11,15
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]!
283 function x264_sub16x16_dct8_neon
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)
291 bl X(x264_sub8x8_dct8_neon)
293 sub r1, r1, #FENC_STRIDE*8 - 8
294 sub r2, r2, #FDEC_STRIDE*8 - 8
295 b X(x264_sub8x8_dct8_neon)
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
308 function x264_add4x4_idct_neon
310 vld1.64 {d0-d3}, [r1,:128]
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
316 TRANSPOSE4x4_16 d0, d1, d3, d2
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
323 vld1.32 {d31[1]}, [r0,:32], r2
325 vld1.32 {d31[0]}, [r0,:32], r2
327 sub r0, r0, r2, lsl #2
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
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
348 TRANSPOSE4x4_16 q0, q1, q2, q3
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
355 vld1.32 {d28}, [r0,:64], r2
357 vld1.32 {d29}, [r0,:64], r2
359 vld1.32 {d30}, [r0,:64], r2
361 vld1.32 {d31}, [r0,:64], r2
363 sub r0, r0, r2, lsl #2
371 vst1.32 {d0}, [r0,:64], r2
373 vst1.32 {d1}, [r0,:64], r2
375 vst1.32 {d2}, [r0,:64], r2
376 vst1.32 {d3}, [r0,:64], r2
380 function x264_add8x8_idct_neon
383 bl x264_add8x4_idct_neon
385 b x264_add8x4_idct_neon
388 function x264_add16x16_idct_neon
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
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
402 b x264_add8x4_idct_neon
410 SUMSUB_AB q0, q1, q8, q12 // a0/a2
412 vld1.64 {d28-d31}, [r1,:128]!
416 SUMSUB_SHR 1, q2, q3, q10, q14, q8, q12 // a6/a4
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
425 SUMSUB_SHR 2, q13, q14, q14, q15, q11, q9 // b3/b5
426 SUMSUB_SHR2 2, q12, q15, q8, q10, q11, q9 // b1/b7
428 SUMSUB_AB q10, q2, q0, q2 // b0/b6
429 SUMSUB_AB q11, q3, q1, q3 // b2/b4
431 SUMSUB_AB q8, q15, q10, q15
432 SUMSUB_AB q9, q14, q11, q14
433 SUMSUB_AB q10, q13, q3, q13
437 SUMSUB_AB q11, q12, q2, q12
440 function x264_add8x8_idct8_neon
442 vld1.64 {d16-d19}, [r1,:128]!
443 vld1.64 {d20-d23}, [r1,:128]!
444 vld1.64 {d24-d27}, [r1,:128]!
457 vld1.64 {d0}, [r0,:64], r2
459 vld1.64 {d1}, [r0,:64], r2
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
477 vaddw.u8 q10, q10, d2
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
489 vaddw.u8 q14, q14, d6
490 vaddw.u8 q15, q15, d7
491 vst1.64 {d3}, [r0,:64], r2
493 vst1.64 {d4}, [r0,:64], r2
496 vst1.64 {d5}, [r0,:64], r2
497 vst1.64 {d6}, [r0,:64], r2
498 vst1.64 {d7}, [r0,:64], r2
502 function x264_add16x16_idct8_neon
504 bl X(x264_add8x8_idct8_neon)
505 sub r0, r0, #8*FDEC_STRIDE-8
506 bl X(x264_add8x8_idct8_neon)
508 bl X(x264_add8x8_idct8_neon)
509 sub r0, r0, #8*FDEC_STRIDE-8
511 b X(x264_add8x8_idct8_neon)
515 function x264_add8x8_idct_dc_neon
517 vld1.64 {d16}, [r1,:64]
518 vrshr.s16 d16, d16, #6
519 vld1.64 {d0}, [r0,:64], r2
521 vld1.64 {d1}, [r0,:64], r2
522 vld1.64 {d2}, [r0,:64], r2
524 vld1.64 {d3}, [r0,:64], r2
526 vld1.64 {d4}, [r0,:64], r2
528 vld1.64 {d5}, [r0,:64], r2
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
535 sub r0, r0, #8*FDEC_STRIDE
554 vst1.64 {d0}, [r0,:64], r2
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
566 .macro ADD16x4_IDCT_DC dc
567 vld1.64 {d16-d17}, [r0,:128], r3
568 vld1.64 {d18-d19}, [r0,:128], r3
571 vld1.64 {d20-d21}, [r0,:128], r3
574 vld1.64 {d22-d23}, [r0,:128], r3
575 vsub.s16 q12, q15, q2
576 vsub.s16 q13, q15, q3
585 vqadd.u8 q10, q10, q2
586 vqadd.u8 q11, q11, q2
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
598 function x264_add16x16_idct_dc_neon
603 vld1.64 {d0-d3}, [r1,:64]
614 function x264_sub8x8_dct_dc_neon
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
628 vld1.64 {d23}, [r2,:64], ip
629 vsubl.u8 q11, d22, d23
630 vld1.64 {d24}, [r1,:64], r3
632 vld1.64 {d25}, [r2,:64], ip
633 vsubl.u8 q12, d24, d25
634 vld1.64 {d26}, [r1,:64], r3
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
658 vst1.64 {d0}, [r0,:64]
662 function x264_sub8x16_dct_dc_neon
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
676 vld1.64 {d23}, [r2,:64], ip
677 vsubl.u8 q11, d22, d23
678 vld1.64 {d24}, [r1,:64], r3
680 vld1.64 {d25}, [r2,:64], ip
681 vsubl.u8 q12, d24, d25
682 vld1.64 {d26}, [r1,:64], r3
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
694 vld1.64 {d16}, [r1,:64], r3
696 vld1.64 {d17}, [r2,:64], ip
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
707 vld1.64 {d23}, [r2,:64], ip
708 vsubl.u8 q11, d22, d23
709 vld1.64 {d24}, [r1,:64], r3
711 vld1.64 {d25}, [r2,:64], ip
712 vsubl.u8 q12, d24, d25
713 vld1.64 {d26}, [r1,:64], r3
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
726 vadd.s16 d16, d0, d1 @ b0
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
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
745 vpadd.s16 d0, d16, d17
746 vpadd.s16 d1, d18, d19
747 vpadd.s16 d2, d20, d21
748 vpadd.s16 d3, d22, d23
751 vst1.64 {q0}, [r0,:64]
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]