1 /*****************************************************************************
2 * dct-a.S: h264 encoder library
3 *****************************************************************************
4 * Copyright (C) 2009 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.
21 *****************************************************************************/
31 .byte 0,1, 8,9, 2,3, 4,5
32 .byte 2,3, 8,9, 16,17, 10,11
33 .byte 12,13, 6,7, 14,15, 20,21
34 .byte 10,11, 12,13, 6,7, 14,15
38 // sum = a + (b>>shift) sub = (a>>shift) - b
39 .macro SUMSUB_SHR shift sum sub a b t0 t1
40 vshr.s16 \t0, \b, #\shift
41 vshr.s16 \t1, \a, #\shift
42 vadd.s16 \sum, \a, \t0
43 vsub.s16 \sub, \t1, \b
46 // sum = (a>>shift) + b sub = a - (b>>shift)
47 .macro SUMSUB_SHR2 shift sum sub a b t0 t1
48 vshr.s16 \t0, \a, #\shift
49 vshr.s16 \t1, \b, #\shift
50 vadd.s16 \sum, \t0, \b
51 vsub.s16 \sub, \a, \t1
54 // a += 1.5*ma b -= 1.5*mb
55 .macro SUMSUB_15 a b ma mb t0 t1
58 vadd.s16 \t0, \t0, \ma
59 vadd.s16 \t1, \t1, \mb
65 function x264_dct4x4dc_neon
66 vld1.64 {d0-d3}, [r0,:128]
67 SUMSUB_ABCD d4, d5, d6, d7, d0, d1, d2, d3
68 SUMSUB_ABCD d0, d2, d3, d1, d4, d6, d5, d7
71 HADAMARD 1, sumsub, q2, q3, q0, q1
80 vst1.64 {d0-d3}, [r0,:128]
84 function x264_idct4x4dc_neon
85 vld1.64 {d0-d3}, [r0,:128]
86 SUMSUB_ABCD d4, d5, d6, d7, d0, d1, d2, d3
87 SUMSUB_ABCD d0, d2, d3, d1, d4, d6, d5, d7
89 HADAMARD 1, sumsub, q2, q3, q0, q1
90 HADAMARD 2, sumsub, d0, d1, d4, d5
91 HADAMARD 2, sumsub, d3, d2, d6, d7
92 vst1.64 {d0-d3}, [r0,:128]
97 .macro DCT_1D d0 d1 d2 d3 d4 d5 d6 d7
98 SUMSUB_AB \d1, \d6, \d5, \d6
99 SUMSUB_AB \d3, \d7, \d4, \d7
100 vadd.s16 \d0, \d3, \d1
101 vadd.s16 \d4, \d7, \d7
102 vadd.s16 \d5, \d6, \d6
103 vsub.s16 \d2, \d3, \d1
104 vadd.s16 \d1, \d4, \d6
105 vsub.s16 \d3, \d7, \d5
108 function x264_sub4x4_dct_neon
111 vld1.32 {d0[]}, [r1,:32], r3
112 vld1.32 {d1[]}, [r2,:32], ip
113 vld1.32 {d2[]}, [r1,:32], r3
115 vld1.32 {d3[]}, [r2,:32], ip
116 vld1.32 {d4[]}, [r1,:32], r3
118 vld1.32 {d5[]}, [r2,:32], ip
119 vld1.32 {d6[]}, [r1,:32], r3
121 vld1.32 {d7[]}, [r2,:32], ip
124 DCT_1D d0, d1, d2, d3, d16, d18, d20, d22
125 TRANSPOSE4x4_16 d0, d1, d2, d3
126 DCT_1D d4, d5, d6, d7, d0, d1, d2, d3
127 vst1.64 {d4-d7}, [r0,:128]
131 function x264_sub8x4_dct_neon
132 vld1.64 {d0}, [r1,:64], r3
133 vld1.64 {d1}, [r2,:64], ip
135 vld1.64 {d2}, [r1,:64], r3
136 vld1.64 {d3}, [r2,:64], ip
138 vld1.64 {d4}, [r1,:64], r3
139 vld1.64 {d5}, [r2,:64], ip
141 vld1.64 {d6}, [r1,:64], r3
142 vld1.64 {d7}, [r2,:64], ip
145 DCT_1D q0, q1, q2, q3, q8, q9, q10, q11
146 TRANSPOSE4x4_16 q0, q1, q2, q3
148 SUMSUB_AB q8, q12, q0, q3
149 SUMSUB_AB q9, q10, q1, q2
150 vadd.i16 q13, q12, q12
151 vadd.i16 q11, q10, q10
152 vadd.i16 d0, d16, d18
153 vadd.i16 d1, d26, d20
154 vsub.i16 d2, d16, d18
155 vsub.i16 d3, d24, d22
156 vst1.64 {d0-d1}, [r0,:128]!
157 vadd.i16 d4, d17, d19
158 vadd.i16 d5, d27, d21
159 vst1.64 {d2-d3}, [r0,:128]!
160 vsub.i16 d6, d17, d19
161 vsub.i16 d7, d25, d23
162 vst1.64 {d4-d5}, [r0,:128]!
163 vst1.64 {d6-d7}, [r0,:128]!
167 function x264_sub8x8_dct_neon
171 bl x264_sub8x4_dct_neon
173 b x264_sub8x4_dct_neon
176 function x264_sub16x16_dct_neon
180 bl x264_sub8x4_dct_neon
181 bl x264_sub8x4_dct_neon
182 sub r1, r1, #8*FENC_STRIDE-8
183 sub r2, r2, #8*FDEC_STRIDE-8
184 bl x264_sub8x4_dct_neon
185 bl x264_sub8x4_dct_neon
188 bl x264_sub8x4_dct_neon
189 bl x264_sub8x4_dct_neon
190 sub r1, r1, #8*FENC_STRIDE-8
191 sub r2, r2, #8*FDEC_STRIDE-8
192 bl x264_sub8x4_dct_neon
194 b x264_sub8x4_dct_neon
199 SUMSUB_AB q2, q1, q11, q12 // s34/d34
200 SUMSUB_AB q3, q11, q10, q13 // s25/d25
201 SUMSUB_AB q13, q10, q9, q14 // s16/d16
202 SUMSUB_AB q14, q8, q8, q15 // s07/d07
204 SUMSUB_AB q9, q2, q14, q2 // a0/a2
205 SUMSUB_AB q12, q14, q13, q3 // a1/a3
207 SUMSUB_AB q3, q13, q8, q1 // a6/a5
209 vshr.s16 q15, q11, #1
211 vadd.s16 q15, q15, q11
213 vsub.s16 q13, q13, q15
215 SUMSUB_AB q0, q15, q10, q11 // a4/a7
218 vadd.s16 q10, q10, q8
219 vadd.s16 q11, q11, q1
220 vadd.s16 q10, q0, q10
221 vadd.s16 q15, q15, q11
223 SUMSUB_AB q8, q12, q9, q12
224 SUMSUB_SHR 2, q9, q15, q10, q15, q0, q1
225 SUMSUB_SHR 1, q10, q14, q2, q14, q0, q1
226 SUMSUB_SHR2 2, q11, q13, q3, q13, q0, q1
229 function x264_sub8x8_dct8_neon
232 vld1.64 {d16}, [r1,:64], r3
233 vld1.64 {d17}, [r2,:64], ip
234 vsubl.u8 q8, d16, d17
235 vld1.64 {d18}, [r1,:64], r3
236 vld1.64 {d19}, [r2,:64], ip
237 vsubl.u8 q9, d18, d19
238 vld1.64 {d20}, [r1,:64], r3
239 vld1.64 {d21}, [r2,:64], ip
240 vsubl.u8 q10, d20, d21
241 vld1.64 {d22}, [r1,:64], r3
242 vld1.64 {d23}, [r2,:64], ip
243 vsubl.u8 q11, d22, d23
244 vld1.64 {d24}, [r1,:64], r3
245 vld1.64 {d25}, [r2,:64], ip
246 vsubl.u8 q12, d24, d25
247 vld1.64 {d26}, [r1,:64], r3
248 vld1.64 {d27}, [r2,:64], ip
249 vsubl.u8 q13, d26, d27
250 vld1.64 {d28}, [r1,:64], r3
251 vld1.64 {d29}, [r2,:64], ip
252 vsubl.u8 q14, d28, d29
253 vld1.64 {d30}, [r1,:64], r3
254 vld1.64 {d31}, [r2,:64], ip
255 vsubl.u8 q15, d30, d31
258 vswp d17, d24 // 8, 12
259 vswp d21, d28 // 10,14
263 vswp d19, d26 // 9, 13
264 vswp d23, d30 // 11,15
274 vst1.64 {d16-d19}, [r0,:128]!
275 vst1.64 {d20-d23}, [r0,:128]!
276 vst1.64 {d24-d27}, [r0,:128]!
277 vst1.64 {d28-d31}, [r0,:128]!
281 function x264_sub16x16_dct8_neon
283 bl x264_sub8x8_dct8_neon
284 sub r1, r1, #FENC_STRIDE*8 - 8
285 sub r2, r2, #FDEC_STRIDE*8 - 8
286 bl x264_sub8x8_dct8_neon
289 bl x264_sub8x8_dct8_neon
291 sub r1, r1, #FENC_STRIDE*8 - 8
292 sub r2, r2, #FDEC_STRIDE*8 - 8
293 b x264_sub8x8_dct8_neon
297 // First part of IDCT (minus final SUMSUB_BA)
298 .macro IDCT_1D d4 d5 d6 d7 d0 d1 d2 d3
299 SUMSUB_AB \d4, \d5, \d0, \d2
300 vshr.s16 \d7, \d1, #1
301 vshr.s16 \d6, \d3, #1
302 vsub.s16 \d7, \d7, \d3
303 vadd.s16 \d6, \d6, \d1
306 function x264_add4x4_idct_neon
308 vld1.64 {d0-d3}, [r1,:128]
310 IDCT_1D d4, d5, d6, d7, d0, d1, d2, d3
311 vld1.32 {d30[0]}, [r0,:32], r2
312 SUMSUB_AB q0, q1, q2, q3
314 TRANSPOSE4x4_16 d0, d1, d3, d2
316 IDCT_1D d4, d5, d6, d7, d0, d1, d3, d2
317 vld1.32 {d30[1]}, [r0,:32], r2
318 SUMSUB_AB q0, q1, q2, q3
321 vld1.32 {d31[1]}, [r0,:32], r2
323 vld1.32 {d31[0]}, [r0,:32], r2
325 sub r0, r0, r2, lsl #2
331 vst1.32 {d0[0]}, [r0,:32], r2
332 vst1.32 {d0[1]}, [r0,:32], r2
333 vst1.32 {d2[1]}, [r0,:32], r2
334 vst1.32 {d2[0]}, [r0,:32], r2
338 function x264_add8x4_idct_neon
339 vld1.64 {d0-d3}, [r1,:128]!
340 IDCT_1D d16, d18, d20, d22, d0, d1, d2, d3
341 vld1.64 {d4-d7}, [r1,:128]!
342 IDCT_1D d17, d19, d21, d23, d4, d5, d6, d7
343 SUMSUB_AB q0, q3, q8, q10
344 SUMSUB_AB q1, q2, q9, q11
346 TRANSPOSE4x4_16 q0, q1, q2, q3
348 IDCT_1D q8, q9, q10, q11, q0, q1, q2, q3
349 SUMSUB_AB q0, q3, q8, q10
350 SUMSUB_AB q1, q2, q9, q11
353 vld1.32 {d28}, [r0,:64], r2
355 vld1.32 {d29}, [r0,:64], r2
357 vld1.32 {d30}, [r0,:64], r2
359 vld1.32 {d31}, [r0,:64], r2
361 sub r0, r0, r2, lsl #2
369 vst1.32 {d0}, [r0,:64], r2
371 vst1.32 {d1}, [r0,:64], r2
373 vst1.32 {d2}, [r0,:64], r2
374 vst1.32 {d3}, [r0,:64], r2
378 function x264_add8x8_idct_neon
381 bl x264_add8x4_idct_neon
383 b x264_add8x4_idct_neon
386 function x264_add16x16_idct_neon
389 bl x264_add8x4_idct_neon
390 bl x264_add8x4_idct_neon
391 sub r0, r0, #8*FDEC_STRIDE-8
392 bl x264_add8x4_idct_neon
393 bl x264_add8x4_idct_neon
395 bl x264_add8x4_idct_neon
396 bl x264_add8x4_idct_neon
397 sub r0, r0, #8*FDEC_STRIDE-8
398 bl x264_add8x4_idct_neon
400 b x264_add8x4_idct_neon
408 SUMSUB_AB q0, q1, q8, q12 // a0/a2
410 vld1.64 {d28-d31}, [r1,:128]!
414 SUMSUB_SHR 1, q2, q3, q10, q14, q8, q12 // a6/a4
418 SUMSUB_AB q8, q10, q13, q11
419 SUMSUB_15 q8, q10, q9, q15, q12, q14 // a7/a1
420 SUMSUB_AB q14, q15, q15, q9
421 SUMSUB_15 q15, q14, q13, q11, q12, q9 // a5/a3
423 SUMSUB_SHR 2, q13, q14, q14, q15, q11, q9 // b3/b5
424 SUMSUB_SHR2 2, q12, q15, q8, q10, q11, q9 // b1/b7
426 SUMSUB_AB q10, q2, q0, q2 // b0/b6
427 SUMSUB_AB q11, q3, q1, q3 // b2/b4
429 SUMSUB_AB q8, q15, q10, q15
430 SUMSUB_AB q9, q14, q11, q14
431 SUMSUB_AB q10, q13, q3, q13
435 SUMSUB_AB q11, q12, q2, q12
438 function x264_add8x8_idct8_neon
440 vld1.64 {d16-d19}, [r1,:128]!
441 vld1.64 {d20-d23}, [r1,:128]!
442 vld1.64 {d24-d27}, [r1,:128]!
455 vld1.64 {d0}, [r0,:64], r2
457 vld1.64 {d1}, [r0,:64], r2
459 vld1.64 {d2}, [r0,:64], r2
460 vrshr.s16 q10, q10, #6
461 vld1.64 {d3}, [r0,:64], r2
462 vrshr.s16 q11, q11, #6
463 vld1.64 {d4}, [r0,:64], r2
464 vrshr.s16 q12, q12, #6
465 vld1.64 {d5}, [r0,:64], r2
466 vrshr.s16 q13, q13, #6
467 vld1.64 {d6}, [r0,:64], r2
468 vrshr.s16 q14, q14, #6
469 vld1.64 {d7}, [r0,:64], r2
470 vrshr.s16 q15, q15, #6
471 sub r0, r0, r2, lsl #3
475 vaddw.u8 q10, q10, d2
479 vaddw.u8 q11, q11, d3
480 vst1.64 {d0}, [r0,:64], r2
481 vaddw.u8 q12, q12, d4
482 vst1.64 {d1}, [r0,:64], r2
483 vaddw.u8 q13, q13, d5
484 vst1.64 {d2}, [r0,:64], r2
487 vaddw.u8 q14, q14, d6
488 vaddw.u8 q15, q15, d7
489 vst1.64 {d3}, [r0,:64], r2
491 vst1.64 {d4}, [r0,:64], r2
494 vst1.64 {d5}, [r0,:64], r2
495 vst1.64 {d6}, [r0,:64], r2
496 vst1.64 {d7}, [r0,:64], r2
500 function x264_add16x16_idct8_neon
502 bl x264_add8x8_idct8_neon
503 sub r0, r0, #8*FDEC_STRIDE-8
504 bl x264_add8x8_idct8_neon
506 bl x264_add8x8_idct8_neon
507 sub r0, r0, #8*FDEC_STRIDE-8
509 b x264_add8x8_idct8_neon
513 function x264_add8x8_idct_dc_neon
515 vld1.64 {d16}, [r1,:64]
516 vrshr.s16 d16, d16, #6
517 vld1.64 {d0}, [r0,:64], r2
519 vld1.64 {d1}, [r0,:64], r2
520 vld1.64 {d2}, [r0,:64], r2
522 vld1.64 {d3}, [r0,:64], r2
524 vld1.64 {d4}, [r0,:64], r2
526 vld1.64 {d5}, [r0,:64], r2
528 vld1.64 {d6}, [r0,:64], r2
529 vsub.s16 q12, q15, q10
530 vld1.64 {d7}, [r0,:64], r2
531 vsub.s16 q13, q15, q11
533 sub r0, r0, #8*FDEC_STRIDE
552 vst1.64 {d0}, [r0,:64], r2
554 vst1.64 {d1}, [r0,:64], r2
555 vst1.64 {d2}, [r0,:64], r2
556 vst1.64 {d3}, [r0,:64], r2
557 vst1.64 {d4}, [r0,:64], r2
558 vst1.64 {d5}, [r0,:64], r2
559 vst1.64 {d6}, [r0,:64], r2
560 vst1.64 {d7}, [r0,:64], r2
564 .macro ADD16x4_IDCT_DC dc
565 vld1.64 {d16-d17}, [r0,:128], r3
566 vld1.64 {d18-d19}, [r0,:128], r3
569 vld1.64 {d20-d21}, [r0,:128], r3
572 vld1.64 {d22-d23}, [r0,:128], r3
573 vsub.s16 q12, q15, q2
574 vsub.s16 q13, q15, q3
583 vqadd.u8 q10, q10, q2
584 vqadd.u8 q11, q11, q2
588 vqsub.u8 q10, q10, q3
589 vst1.64 {d16-d17}, [r2,:128], r3
590 vqsub.u8 q11, q11, q3
591 vst1.64 {d18-d19}, [r2,:128], r3
592 vst1.64 {d20-d21}, [r2,:128], r3
593 vst1.64 {d22-d23}, [r2,:128], r3
596 function x264_add16x16_idct_dc_neon
601 vld1.64 {d0-d3}, [r1,:64]
612 function x264_sub8x8_dct_dc_neon
615 vld1.64 {d16}, [r1,:64], r3
616 vld1.64 {d17}, [r2,:64], ip
617 vsubl.u8 q8, d16, d17
618 vld1.64 {d18}, [r1,:64], r3
619 vld1.64 {d19}, [r2,:64], ip
620 vsubl.u8 q9, d18, d19
621 vld1.64 {d20}, [r1,:64], r3
622 vld1.64 {d21}, [r2,:64], ip
623 vsubl.u8 q10, d20, d21
624 vld1.64 {d22}, [r1,:64], r3
626 vld1.64 {d23}, [r2,:64], ip
627 vsubl.u8 q11, d22, d23
628 vld1.64 {d24}, [r1,:64], r3
630 vld1.64 {d25}, [r2,:64], ip
631 vsubl.u8 q12, d24, d25
632 vld1.64 {d26}, [r1,:64], r3
634 vld1.64 {d27}, [r2,:64], ip
635 vsubl.u8 q13, d26, d27
636 vld1.64 {d28}, [r1,:64], r3
637 vld1.64 {d29}, [r2,:64], ip
638 vsubl.u8 q14, d28, d29
639 vld1.64 {d30}, [r1,:64], r3
640 vadd.s16 q1, q12, q13
641 vld1.64 {d31}, [r2,:64], ip
644 vsubl.u8 q15, d30, d31
648 vst1.64 {d0}, [r0,:64]
653 function x264_zigzag_scan_4x4_frame_neon
654 movrel r2, scan4x4_frame
655 vld1.64 {d0-d3}, [r1,:128]
656 vld1.64 {d16-d19}, [r2,:128]
657 vtbl.8 d4, {d0-d1}, d16
658 vtbl.8 d5, {d1-d3}, d17
659 vtbl.8 d6, {d0-d2}, d18
660 vtbl.8 d7, {d2-d3}, d19
661 vst1.64 {d4-d7}, [r0,:128]