1 /****************************************************************************
2 * dct-a.S: arm transform and zigzag
3 *****************************************************************************
4 * Copyright (C) 2009-2014 x264 project
6 * Authors: David Conrad <lessen42@gmail.com>
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.
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.
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.
22 * This program is also available under a commercial proprietary license.
23 * For more information, contact us at licensing@x264.com.
24 *****************************************************************************/
32 .byte 0,1, 8,9, 2,3, 4,5
33 .byte 2,3, 8,9, 16,17, 10,11
34 .byte 12,13, 6,7, 14,15, 20,21
35 .byte 10,11, 12,13, 6,7, 14,15
39 // sum = a + (b>>shift) sub = (a>>shift) - b
40 .macro SUMSUB_SHR shift sum sub a b t0 t1
41 vshr.s16 \t0, \b, #\shift
42 vshr.s16 \t1, \a, #\shift
43 vadd.s16 \sum, \a, \t0
44 vsub.s16 \sub, \t1, \b
47 // sum = (a>>shift) + b sub = a - (b>>shift)
48 .macro SUMSUB_SHR2 shift sum sub a b t0 t1
49 vshr.s16 \t0, \a, #\shift
50 vshr.s16 \t1, \b, #\shift
51 vadd.s16 \sum, \t0, \b
52 vsub.s16 \sub, \a, \t1
55 // a += 1.5*ma b -= 1.5*mb
56 .macro SUMSUB_15 a b ma mb t0 t1
59 vadd.s16 \t0, \t0, \ma
60 vadd.s16 \t1, \t1, \mb
66 function x264_dct4x4dc_neon
67 vld1.64 {d0-d3}, [r0,:128]
68 SUMSUB_ABCD d4, d5, d6, d7, d0, d1, d2, d3
69 SUMSUB_ABCD d0, d2, d3, d1, d4, d6, d5, d7
72 HADAMARD 1, sumsub, q2, q3, q0, q1
81 vst1.64 {d0-d3}, [r0,:128]
85 function x264_idct4x4dc_neon
86 vld1.64 {d0-d3}, [r0,:128]
87 SUMSUB_ABCD d4, d5, d6, d7, d0, d1, d2, d3
88 SUMSUB_ABCD d0, d2, d3, d1, d4, d6, d5, d7
90 HADAMARD 1, sumsub, q2, q3, q0, q1
91 HADAMARD 2, sumsub, d0, d1, d4, d5
92 HADAMARD 2, sumsub, d3, d2, d6, d7
93 vst1.64 {d0-d3}, [r0,:128]
98 .macro DCT_1D d0 d1 d2 d3 d4 d5 d6 d7
99 SUMSUB_AB \d1, \d6, \d5, \d6
100 SUMSUB_AB \d3, \d7, \d4, \d7
101 vadd.s16 \d0, \d3, \d1
102 vadd.s16 \d4, \d7, \d7
103 vadd.s16 \d5, \d6, \d6
104 vsub.s16 \d2, \d3, \d1
105 vadd.s16 \d1, \d4, \d6
106 vsub.s16 \d3, \d7, \d5
109 function x264_sub4x4_dct_neon
112 vld1.32 {d0[]}, [r1,:32], r3
113 vld1.32 {d1[]}, [r2,:32], ip
114 vld1.32 {d2[]}, [r1,:32], r3
116 vld1.32 {d3[]}, [r2,:32], ip
117 vld1.32 {d4[]}, [r1,:32], r3
119 vld1.32 {d5[]}, [r2,:32], ip
120 vld1.32 {d6[]}, [r1,:32], r3
122 vld1.32 {d7[]}, [r2,:32], ip
125 DCT_1D d0, d1, d2, d3, d16, d18, d20, d22
126 TRANSPOSE4x4_16 d0, d1, d2, d3
127 DCT_1D d4, d5, d6, d7, d0, d1, d2, d3
128 vst1.64 {d4-d7}, [r0,:128]
132 function x264_sub8x4_dct_neon, export=0
133 vld1.64 {d0}, [r1,:64], r3
134 vld1.64 {d1}, [r2,:64], ip
136 vld1.64 {d2}, [r1,:64], r3
137 vld1.64 {d3}, [r2,:64], ip
139 vld1.64 {d4}, [r1,:64], r3
140 vld1.64 {d5}, [r2,:64], ip
142 vld1.64 {d6}, [r1,:64], r3
143 vld1.64 {d7}, [r2,:64], ip
146 DCT_1D q0, q1, q2, q3, q8, q9, q10, q11
147 TRANSPOSE4x4_16 q0, q1, q2, q3
149 SUMSUB_AB q8, q12, q0, q3
150 SUMSUB_AB q9, q10, q1, q2
151 vadd.i16 q13, q12, q12
152 vadd.i16 q11, q10, q10
153 vadd.i16 d0, d16, d18
154 vadd.i16 d1, d26, d20
155 vsub.i16 d2, d16, d18
156 vsub.i16 d3, d24, d22
157 vst1.64 {d0-d1}, [r0,:128]!
158 vadd.i16 d4, d17, d19
159 vadd.i16 d5, d27, d21
160 vst1.64 {d2-d3}, [r0,:128]!
161 vsub.i16 d6, d17, d19
162 vsub.i16 d7, d25, d23
163 vst1.64 {d4-d5}, [r0,:128]!
164 vst1.64 {d6-d7}, [r0,:128]!
168 function x264_sub8x8_dct_neon
172 bl x264_sub8x4_dct_neon
174 b x264_sub8x4_dct_neon
177 function x264_sub16x16_dct_neon
181 bl x264_sub8x4_dct_neon
182 bl x264_sub8x4_dct_neon
183 sub r1, r1, #8*FENC_STRIDE-8
184 sub r2, r2, #8*FDEC_STRIDE-8
185 bl x264_sub8x4_dct_neon
186 bl x264_sub8x4_dct_neon
189 bl x264_sub8x4_dct_neon
190 bl x264_sub8x4_dct_neon
191 sub r1, r1, #8*FENC_STRIDE-8
192 sub r2, r2, #8*FDEC_STRIDE-8
193 bl x264_sub8x4_dct_neon
195 b x264_sub8x4_dct_neon
200 SUMSUB_AB q2, q1, q11, q12 // s34/d34
201 SUMSUB_AB q3, q11, q10, q13 // s25/d25
202 SUMSUB_AB q13, q10, q9, q14 // s16/d16
203 SUMSUB_AB q14, q8, q8, q15 // s07/d07
205 SUMSUB_AB q9, q2, q14, q2 // a0/a2
206 SUMSUB_AB q12, q14, q13, q3 // a1/a3
208 SUMSUB_AB q3, q13, q8, q1 // a6/a5
210 vshr.s16 q15, q11, #1
212 vadd.s16 q15, q15, q11
214 vsub.s16 q13, q13, q15
216 SUMSUB_AB q0, q15, q10, q11 // a4/a7
219 vadd.s16 q10, q10, q8
220 vadd.s16 q11, q11, q1
221 vadd.s16 q10, q0, q10
222 vadd.s16 q15, q15, q11
224 SUMSUB_AB q8, q12, q9, q12
225 SUMSUB_SHR 2, q9, q15, q10, q15, q0, q1
226 SUMSUB_SHR 1, q10, q14, q2, q14, q0, q1
227 SUMSUB_SHR2 2, q11, q13, q3, q13, q0, q1
230 function x264_sub8x8_dct8_neon
233 vld1.64 {d16}, [r1,:64], r3
234 vld1.64 {d17}, [r2,:64], ip
235 vsubl.u8 q8, d16, d17
236 vld1.64 {d18}, [r1,:64], r3
237 vld1.64 {d19}, [r2,:64], ip
238 vsubl.u8 q9, d18, d19
239 vld1.64 {d20}, [r1,:64], r3
240 vld1.64 {d21}, [r2,:64], ip
241 vsubl.u8 q10, d20, d21
242 vld1.64 {d22}, [r1,:64], r3
243 vld1.64 {d23}, [r2,:64], ip
244 vsubl.u8 q11, d22, d23
245 vld1.64 {d24}, [r1,:64], r3
246 vld1.64 {d25}, [r2,:64], ip
247 vsubl.u8 q12, d24, d25
248 vld1.64 {d26}, [r1,:64], r3
249 vld1.64 {d27}, [r2,:64], ip
250 vsubl.u8 q13, d26, d27
251 vld1.64 {d28}, [r1,:64], r3
252 vld1.64 {d29}, [r2,:64], ip
253 vsubl.u8 q14, d28, d29
254 vld1.64 {d30}, [r1,:64], r3
255 vld1.64 {d31}, [r2,:64], ip
256 vsubl.u8 q15, d30, d31
259 vswp d17, d24 // 8, 12
260 vswp d21, d28 // 10,14
264 vswp d19, d26 // 9, 13
265 vswp d23, d30 // 11,15
275 vst1.64 {d16-d19}, [r0,:128]!
276 vst1.64 {d20-d23}, [r0,:128]!
277 vst1.64 {d24-d27}, [r0,:128]!
278 vst1.64 {d28-d31}, [r0,:128]!
282 function x264_sub16x16_dct8_neon
284 bl X(x264_sub8x8_dct8_neon)
285 sub r1, r1, #FENC_STRIDE*8 - 8
286 sub r2, r2, #FDEC_STRIDE*8 - 8
287 bl X(x264_sub8x8_dct8_neon)
290 bl X(x264_sub8x8_dct8_neon)
292 sub r1, r1, #FENC_STRIDE*8 - 8
293 sub r2, r2, #FDEC_STRIDE*8 - 8
294 b X(x264_sub8x8_dct8_neon)
298 // First part of IDCT (minus final SUMSUB_BA)
299 .macro IDCT_1D d4 d5 d6 d7 d0 d1 d2 d3
300 SUMSUB_AB \d4, \d5, \d0, \d2
301 vshr.s16 \d7, \d1, #1
302 vshr.s16 \d6, \d3, #1
303 vsub.s16 \d7, \d7, \d3
304 vadd.s16 \d6, \d6, \d1
307 function x264_add4x4_idct_neon
309 vld1.64 {d0-d3}, [r1,:128]
311 IDCT_1D d4, d5, d6, d7, d0, d1, d2, d3
312 vld1.32 {d30[0]}, [r0,:32], r2
313 SUMSUB_AB q0, q1, q2, q3
315 TRANSPOSE4x4_16 d0, d1, d3, d2
317 IDCT_1D d4, d5, d6, d7, d0, d1, d3, d2
318 vld1.32 {d30[1]}, [r0,:32], r2
319 SUMSUB_AB q0, q1, q2, q3
322 vld1.32 {d31[1]}, [r0,:32], r2
324 vld1.32 {d31[0]}, [r0,:32], r2
326 sub r0, r0, r2, lsl #2
332 vst1.32 {d0[0]}, [r0,:32], r2
333 vst1.32 {d0[1]}, [r0,:32], r2
334 vst1.32 {d2[1]}, [r0,:32], r2
335 vst1.32 {d2[0]}, [r0,:32], r2
339 function x264_add8x4_idct_neon, export=0
340 vld1.64 {d0-d3}, [r1,:128]!
341 IDCT_1D d16, d18, d20, d22, d0, d1, d2, d3
342 vld1.64 {d4-d7}, [r1,:128]!
343 IDCT_1D d17, d19, d21, d23, d4, d5, d6, d7
344 SUMSUB_AB q0, q3, q8, q10
345 SUMSUB_AB q1, q2, q9, q11
347 TRANSPOSE4x4_16 q0, q1, q2, q3
349 IDCT_1D q8, q9, q10, q11, q0, q1, q2, q3
350 SUMSUB_AB q0, q3, q8, q10
351 SUMSUB_AB q1, q2, q9, q11
354 vld1.32 {d28}, [r0,:64], r2
356 vld1.32 {d29}, [r0,:64], r2
358 vld1.32 {d30}, [r0,:64], r2
360 vld1.32 {d31}, [r0,:64], r2
362 sub r0, r0, r2, lsl #2
370 vst1.32 {d0}, [r0,:64], r2
372 vst1.32 {d1}, [r0,:64], r2
374 vst1.32 {d2}, [r0,:64], r2
375 vst1.32 {d3}, [r0,:64], r2
379 function x264_add8x8_idct_neon
382 bl x264_add8x4_idct_neon
384 b x264_add8x4_idct_neon
387 function x264_add16x16_idct_neon
390 bl x264_add8x4_idct_neon
391 bl x264_add8x4_idct_neon
392 sub r0, r0, #8*FDEC_STRIDE-8
393 bl x264_add8x4_idct_neon
394 bl x264_add8x4_idct_neon
396 bl x264_add8x4_idct_neon
397 bl x264_add8x4_idct_neon
398 sub r0, r0, #8*FDEC_STRIDE-8
399 bl x264_add8x4_idct_neon
401 b x264_add8x4_idct_neon
409 SUMSUB_AB q0, q1, q8, q12 // a0/a2
411 vld1.64 {d28-d31}, [r1,:128]!
415 SUMSUB_SHR 1, q2, q3, q10, q14, q8, q12 // a6/a4
419 SUMSUB_AB q8, q10, q13, q11
420 SUMSUB_15 q8, q10, q9, q15, q12, q14 // a7/a1
421 SUMSUB_AB q14, q15, q15, q9
422 SUMSUB_15 q15, q14, q13, q11, q12, q9 // a5/a3
424 SUMSUB_SHR 2, q13, q14, q14, q15, q11, q9 // b3/b5
425 SUMSUB_SHR2 2, q12, q15, q8, q10, q11, q9 // b1/b7
427 SUMSUB_AB q10, q2, q0, q2 // b0/b6
428 SUMSUB_AB q11, q3, q1, q3 // b2/b4
430 SUMSUB_AB q8, q15, q10, q15
431 SUMSUB_AB q9, q14, q11, q14
432 SUMSUB_AB q10, q13, q3, q13
436 SUMSUB_AB q11, q12, q2, q12
439 function x264_add8x8_idct8_neon
441 vld1.64 {d16-d19}, [r1,:128]!
442 vld1.64 {d20-d23}, [r1,:128]!
443 vld1.64 {d24-d27}, [r1,:128]!
456 vld1.64 {d0}, [r0,:64], r2
458 vld1.64 {d1}, [r0,:64], r2
460 vld1.64 {d2}, [r0,:64], r2
461 vrshr.s16 q10, q10, #6
462 vld1.64 {d3}, [r0,:64], r2
463 vrshr.s16 q11, q11, #6
464 vld1.64 {d4}, [r0,:64], r2
465 vrshr.s16 q12, q12, #6
466 vld1.64 {d5}, [r0,:64], r2
467 vrshr.s16 q13, q13, #6
468 vld1.64 {d6}, [r0,:64], r2
469 vrshr.s16 q14, q14, #6
470 vld1.64 {d7}, [r0,:64], r2
471 vrshr.s16 q15, q15, #6
472 sub r0, r0, r2, lsl #3
476 vaddw.u8 q10, q10, d2
480 vaddw.u8 q11, q11, d3
481 vst1.64 {d0}, [r0,:64], r2
482 vaddw.u8 q12, q12, d4
483 vst1.64 {d1}, [r0,:64], r2
484 vaddw.u8 q13, q13, d5
485 vst1.64 {d2}, [r0,:64], r2
488 vaddw.u8 q14, q14, d6
489 vaddw.u8 q15, q15, d7
490 vst1.64 {d3}, [r0,:64], r2
492 vst1.64 {d4}, [r0,:64], r2
495 vst1.64 {d5}, [r0,:64], r2
496 vst1.64 {d6}, [r0,:64], r2
497 vst1.64 {d7}, [r0,:64], r2
501 function x264_add16x16_idct8_neon
503 bl X(x264_add8x8_idct8_neon)
504 sub r0, r0, #8*FDEC_STRIDE-8
505 bl X(x264_add8x8_idct8_neon)
507 bl X(x264_add8x8_idct8_neon)
508 sub r0, r0, #8*FDEC_STRIDE-8
510 b X(x264_add8x8_idct8_neon)
514 function x264_add8x8_idct_dc_neon
516 vld1.64 {d16}, [r1,:64]
517 vrshr.s16 d16, d16, #6
518 vld1.64 {d0}, [r0,:64], r2
520 vld1.64 {d1}, [r0,:64], r2
521 vld1.64 {d2}, [r0,:64], r2
523 vld1.64 {d3}, [r0,:64], r2
525 vld1.64 {d4}, [r0,:64], r2
527 vld1.64 {d5}, [r0,:64], r2
529 vld1.64 {d6}, [r0,:64], r2
530 vsub.s16 q12, q15, q10
531 vld1.64 {d7}, [r0,:64], r2
532 vsub.s16 q13, q15, q11
534 sub r0, r0, #8*FDEC_STRIDE
553 vst1.64 {d0}, [r0,:64], r2
555 vst1.64 {d1}, [r0,:64], r2
556 vst1.64 {d2}, [r0,:64], r2
557 vst1.64 {d3}, [r0,:64], r2
558 vst1.64 {d4}, [r0,:64], r2
559 vst1.64 {d5}, [r0,:64], r2
560 vst1.64 {d6}, [r0,:64], r2
561 vst1.64 {d7}, [r0,:64], r2
565 .macro ADD16x4_IDCT_DC dc
566 vld1.64 {d16-d17}, [r0,:128], r3
567 vld1.64 {d18-d19}, [r0,:128], r3
570 vld1.64 {d20-d21}, [r0,:128], r3
573 vld1.64 {d22-d23}, [r0,:128], r3
574 vsub.s16 q12, q15, q2
575 vsub.s16 q13, q15, q3
584 vqadd.u8 q10, q10, q2
585 vqadd.u8 q11, q11, q2
589 vqsub.u8 q10, q10, q3
590 vst1.64 {d16-d17}, [r2,:128], r3
591 vqsub.u8 q11, q11, q3
592 vst1.64 {d18-d19}, [r2,:128], r3
593 vst1.64 {d20-d21}, [r2,:128], r3
594 vst1.64 {d22-d23}, [r2,:128], r3
597 function x264_add16x16_idct_dc_neon
602 vld1.64 {d0-d3}, [r1,:64]
613 function x264_sub8x8_dct_dc_neon
616 vld1.64 {d16}, [r1,:64], r3
617 vld1.64 {d17}, [r2,:64], ip
618 vsubl.u8 q8, d16, d17
619 vld1.64 {d18}, [r1,:64], r3
620 vld1.64 {d19}, [r2,:64], ip
621 vsubl.u8 q9, d18, d19
622 vld1.64 {d20}, [r1,:64], r3
623 vld1.64 {d21}, [r2,:64], ip
624 vsubl.u8 q10, d20, d21
625 vld1.64 {d22}, [r1,:64], r3
627 vld1.64 {d23}, [r2,:64], ip
628 vsubl.u8 q11, d22, d23
629 vld1.64 {d24}, [r1,:64], r3
631 vld1.64 {d25}, [r2,:64], ip
632 vsubl.u8 q12, d24, d25
633 vld1.64 {d26}, [r1,:64], r3
635 vld1.64 {d27}, [r2,:64], ip
636 vsubl.u8 q13, d26, d27
637 vld1.64 {d28}, [r1,:64], r3
638 vld1.64 {d29}, [r2,:64], ip
639 vsubl.u8 q14, d28, d29
640 vld1.64 {d30}, [r1,:64], r3
641 vadd.s16 q1, q12, q13
642 vld1.64 {d31}, [r2,:64], ip
643 vsubl.u8 q15, d30, d31
657 vst1.64 {d0}, [r0,:64]
662 function x264_zigzag_scan_4x4_frame_neon
663 movrel r2, scan4x4_frame
664 vld1.64 {d0-d3}, [r1,:128]
665 vld1.64 {d16-d19}, [r2,:128]
666 vtbl.8 d4, {d0-d1}, d16
667 vtbl.8 d5, {d1-d3}, d17
668 vtbl.8 d6, {d0-d2}, d18
669 vtbl.8 d7, {d2-d3}, d19
670 vst1.64 {d4-d7}, [r0,:128]