1 /****************************************************************************
2 * dct-a.S: arm transform and zigzag
3 *****************************************************************************
4 * Copyright (C) 2009-2010 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 *****************************************************************************/
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
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
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
57 // a += 1.5*ma b -= 1.5*mb
58 .macro SUMSUB_15 a b ma mb t0 t1
61 vadd.s16 \t0, \t0, \ma
62 vadd.s16 \t1, \t1, \mb
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
74 HADAMARD 1, sumsub, q2, q3, q0, q1
83 vst1.64 {d0-d3}, [r0,:128]
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
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]
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
111 function x264_sub4x4_dct_neon
114 vld1.32 {d0[]}, [r1,:32], r3
115 vld1.32 {d1[]}, [r2,:32], ip
116 vld1.32 {d2[]}, [r1,:32], r3
118 vld1.32 {d3[]}, [r2,:32], ip
119 vld1.32 {d4[]}, [r1,:32], r3
121 vld1.32 {d5[]}, [r2,:32], ip
122 vld1.32 {d6[]}, [r1,:32], r3
124 vld1.32 {d7[]}, [r2,:32], ip
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]
134 function x264_sub8x4_dct_neon
135 vld1.64 {d0}, [r1,:64], r3
136 vld1.64 {d1}, [r2,:64], ip
138 vld1.64 {d2}, [r1,:64], r3
139 vld1.64 {d3}, [r2,:64], ip
141 vld1.64 {d4}, [r1,:64], r3
142 vld1.64 {d5}, [r2,:64], ip
144 vld1.64 {d6}, [r1,:64], r3
145 vld1.64 {d7}, [r2,:64], ip
148 DCT_1D q0, q1, q2, q3, q8, q9, q10, q11
149 TRANSPOSE4x4_16 q0, q1, q2, q3
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]!
170 function x264_sub8x8_dct_neon
174 bl x264_sub8x4_dct_neon
176 b x264_sub8x4_dct_neon
179 function x264_sub16x16_dct_neon
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
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
197 b x264_sub8x4_dct_neon
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
207 SUMSUB_AB q9, q2, q14, q2 // a0/a2
208 SUMSUB_AB q12, q14, q13, q3 // a1/a3
210 SUMSUB_AB q3, q13, q8, q1 // a6/a5
212 vshr.s16 q15, q11, #1
214 vadd.s16 q15, q15, q11
216 vsub.s16 q13, q13, q15
218 SUMSUB_AB q0, q15, q10, q11 // a4/a7
221 vadd.s16 q10, q10, q8
222 vadd.s16 q11, q11, q1
223 vadd.s16 q10, q0, q10
224 vadd.s16 q15, q15, q11
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
232 function x264_sub8x8_dct8_neon
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
261 vswp d17, d24 // 8, 12
262 vswp d21, d28 // 10,14
266 vswp d19, d26 // 9, 13
267 vswp d23, d30 // 11,15
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]!
284 function x264_sub16x16_dct8_neon
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
292 bl x264_sub8x8_dct8_neon
294 sub r1, r1, #FENC_STRIDE*8 - 8
295 sub r2, r2, #FDEC_STRIDE*8 - 8
296 b x264_sub8x8_dct8_neon
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
309 function x264_add4x4_idct_neon
311 vld1.64 {d0-d3}, [r1,:128]
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
317 TRANSPOSE4x4_16 d0, d1, d3, d2
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
324 vld1.32 {d31[1]}, [r0,:32], r2
326 vld1.32 {d31[0]}, [r0,:32], r2
328 sub r0, r0, r2, lsl #2
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
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
349 TRANSPOSE4x4_16 q0, q1, q2, q3
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
356 vld1.32 {d28}, [r0,:64], r2
358 vld1.32 {d29}, [r0,:64], r2
360 vld1.32 {d30}, [r0,:64], r2
362 vld1.32 {d31}, [r0,:64], r2
364 sub r0, r0, r2, lsl #2
372 vst1.32 {d0}, [r0,:64], r2
374 vst1.32 {d1}, [r0,:64], r2
376 vst1.32 {d2}, [r0,:64], r2
377 vst1.32 {d3}, [r0,:64], r2
381 function x264_add8x8_idct_neon
384 bl x264_add8x4_idct_neon
386 b x264_add8x4_idct_neon
389 function x264_add16x16_idct_neon
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
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
403 b x264_add8x4_idct_neon
411 SUMSUB_AB q0, q1, q8, q12 // a0/a2
413 vld1.64 {d28-d31}, [r1,:128]!
417 SUMSUB_SHR 1, q2, q3, q10, q14, q8, q12 // a6/a4
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
426 SUMSUB_SHR 2, q13, q14, q14, q15, q11, q9 // b3/b5
427 SUMSUB_SHR2 2, q12, q15, q8, q10, q11, q9 // b1/b7
429 SUMSUB_AB q10, q2, q0, q2 // b0/b6
430 SUMSUB_AB q11, q3, q1, q3 // b2/b4
432 SUMSUB_AB q8, q15, q10, q15
433 SUMSUB_AB q9, q14, q11, q14
434 SUMSUB_AB q10, q13, q3, q13
438 SUMSUB_AB q11, q12, q2, q12
441 function x264_add8x8_idct8_neon
443 vld1.64 {d16-d19}, [r1,:128]!
444 vld1.64 {d20-d23}, [r1,:128]!
445 vld1.64 {d24-d27}, [r1,:128]!
458 vld1.64 {d0}, [r0,:64], r2
460 vld1.64 {d1}, [r0,:64], r2
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
478 vaddw.u8 q10, q10, d2
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
490 vaddw.u8 q14, q14, d6
491 vaddw.u8 q15, q15, d7
492 vst1.64 {d3}, [r0,:64], r2
494 vst1.64 {d4}, [r0,:64], r2
497 vst1.64 {d5}, [r0,:64], r2
498 vst1.64 {d6}, [r0,:64], r2
499 vst1.64 {d7}, [r0,:64], r2
503 function x264_add16x16_idct8_neon
505 bl x264_add8x8_idct8_neon
506 sub r0, r0, #8*FDEC_STRIDE-8
507 bl x264_add8x8_idct8_neon
509 bl x264_add8x8_idct8_neon
510 sub r0, r0, #8*FDEC_STRIDE-8
512 b x264_add8x8_idct8_neon
516 function x264_add8x8_idct_dc_neon
518 vld1.64 {d16}, [r1,:64]
519 vrshr.s16 d16, d16, #6
520 vld1.64 {d0}, [r0,:64], r2
522 vld1.64 {d1}, [r0,:64], r2
523 vld1.64 {d2}, [r0,:64], r2
525 vld1.64 {d3}, [r0,:64], r2
527 vld1.64 {d4}, [r0,:64], r2
529 vld1.64 {d5}, [r0,:64], r2
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
536 sub r0, r0, #8*FDEC_STRIDE
555 vst1.64 {d0}, [r0,:64], r2
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
567 .macro ADD16x4_IDCT_DC dc
568 vld1.64 {d16-d17}, [r0,:128], r3
569 vld1.64 {d18-d19}, [r0,:128], r3
572 vld1.64 {d20-d21}, [r0,:128], r3
575 vld1.64 {d22-d23}, [r0,:128], r3
576 vsub.s16 q12, q15, q2
577 vsub.s16 q13, q15, q3
586 vqadd.u8 q10, q10, q2
587 vqadd.u8 q11, q11, q2
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
599 function x264_add16x16_idct_dc_neon
604 vld1.64 {d0-d3}, [r1,:64]
615 function x264_sub8x8_dct_dc_neon
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
629 vld1.64 {d23}, [r2,:64], ip
630 vsubl.u8 q11, d22, d23
631 vld1.64 {d24}, [r1,:64], r3
633 vld1.64 {d25}, [r2,:64], ip
634 vsubl.u8 q12, d24, d25
635 vld1.64 {d26}, [r1,:64], r3
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
659 vst1.64 {d0}, [r0,:64]
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]