1 /*****************************************************************************
2 * pixel.S: arm pixel metrics
3 *****************************************************************************
4 * Copyright (C) 2009-2015 x264 project
6 * Authors: David Conrad <lessen42@gmail.com>
7 * Janne Grunau <janne-x264@jannau.net>
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 *****************************************************************************/
41 .short 0, -1, -1, -1, 0, -1, -1, -1
43 .short 0, -1, -1, -1, -1, -1, -1, -1
48 function x264_pixel_sad_4x\h\()_armv6
72 .macro SAD_START_4 align:vararg
73 vld1.32 {d1[]}, [r2\align], r3
74 vld1.32 {d0[]}, [r0,:32], r1
78 .macro SAD_4 align:vararg
79 vld1.32 {d1[]}, [r2\align], r3
80 vld1.32 {d0[]}, [r0,:32], r1
84 .macro SAD_START_8 align:vararg
85 vld1.64 {d1}, [r2\align], r3
86 vld1.64 {d0}, [r0,:64], r1
90 .macro SAD_8 align:vararg
91 vld1.64 {d1}, [r2\align], r3
92 vld1.64 {d0}, [r0,:64], r1
96 .macro SAD_START_16 align:vararg
97 vld1.64 {d2-d3}, [r2\align], r3
98 vld1.64 {d0-d1}, [r0,:128], r1
100 vld1.64 {d6-d7}, [r2\align], r3
102 vld1.64 {d4-d5}, [r0,:128], r1
105 .macro SAD_16 align:vararg
107 vld1.64 {d2-d3}, [r2\align], r3
109 vld1.64 {d0-d1}, [r0,:128], r1
111 vld1.64 {d6-d7}, [r2\align], r3
113 vld1.64 {d4-d5}, [r0,:128], r1
116 .macro SAD_FUNC w, h, name, align:vararg
117 function x264_pixel_sad\name\()_\w\()x\h\()_neon
136 vadd.u16 d16, d16, d17
138 vpadd.u16 d0, d16, d16
153 SAD_FUNC 4, 4, _aligned, ,:32
154 SAD_FUNC 4, 8, _aligned, ,:32
155 SAD_FUNC 8, 4, _aligned, ,:64
156 SAD_FUNC 8, 8, _aligned, ,:64
157 SAD_FUNC 8, 16, _aligned, ,:64
158 SAD_FUNC 16, 8, _aligned, ,:128
159 SAD_FUNC 16, 16, _aligned, ,:128
161 // If dual issue is possible, use additional accumulators to avoid
162 // stalls from vadal's latency. This only matters for aligned.
163 .macro SAD_DUAL_START_8
165 vld1.64 {d3}, [r2,:64], r3
166 vld1.64 {d2}, [r0,:64], r1
170 .macro SAD_DUAL_8 align:vararg
171 vld1.64 {d1}, [r2,:64], r3
172 vld1.64 {d0}, [r0,:64], r1
174 vld1.64 {d3}, [r2,:64], r3
175 vld1.64 {d2}, [r0,:64], r1
179 .macro SAD_DUAL_START_16
182 vld1.64 {d2-d3}, [r2,:128], r3
184 vld1.64 {d0-d1}, [r0,:128], r1
189 vld1.64 {d6-d7}, [r2,:128], r3
191 vld1.64 {d4-d5}, [r0,:128], r1
193 vld1.64 {d2-d3}, [r2,:128], r3
195 vld1.64 {d0-d1}, [r0,:128], r1
198 .macro SAD_DUAL_END_16
200 vld1.64 {d6-d7}, [r2,:128], r3
202 vld1.64 {d4-d5}, [r0,:128], r1
207 .macro SAD_FUNC_DUAL w, h
208 function x264_pixel_sad_aligned_\w\()x\h\()_neon_dual
210 .rept \h / 2 - \w / 8
217 vadd.u16 q9, q10, q11
221 vadd.u16 d16, d16, d17
223 vpadd.u16 d0, d16, d16
237 .macro SAD_X_START_4 x
238 vld1.32 {d0[]}, [r0,:32], lr
239 vld1.32 {d1[]}, [r1], r6
241 vld1.32 {d2[]}, [r2], r6
243 vld1.32 {d3[]}, [r3], r6
246 vld1.32 {d4[]}, [r12], r6
252 vld1.32 {d0[]}, [r0,:32], lr
253 vld1.32 {d1[]}, [r1], r6
255 vld1.32 {d2[]}, [r2], r6
257 vld1.32 {d3[]}, [r3], r6
260 vld1.32 {d4[]}, [r12], r6
265 .macro SAD_X_START_8 x
266 vld1.64 {d0}, [r0,:64], lr
267 vld1.64 {d1}, [r1], r6
269 vld1.64 {d2}, [r2], r6
271 vld1.64 {d3}, [r3], r6
274 vld1.64 {d4}, [r12], r6
280 vld1.64 {d0}, [r0,:64], lr
281 vld1.64 {d1}, [r1], r6
283 vld1.64 {d2}, [r2], r6
285 vld1.64 {d3}, [r3], r6
288 vld1.64 {d4}, [r12], r6
293 .macro SAD_X_START_16 x
294 vld1.64 {d0-d1}, [r0,:128], lr
295 vld1.64 {d2-d3}, [r1], r6
298 vld1.64 {d4-d5}, [r2], r6
301 vld1.64 {d6-d7}, [r3], r6
305 vld1.64 {d2-d3}, [r12], r6
312 vld1.64 {d0-d1}, [r0,:128], lr
313 vld1.64 {d2-d3}, [r1], r6
316 vld1.64 {d4-d5}, [r2], r6
319 vld1.64 {d6-d7}, [r3], r6
323 vld1.64 {d2-d3}, [r12], r6
329 .macro SAD_X_FUNC x, w, h
330 function x264_pixel_sad_x\x\()_\w\()x\h\()_neon
333 ldrd r6, r7, [sp, #12]
335 ldrd r6, r7, [sp, #16]
349 vadd.u16 q10, q10, q14
351 vadd.u16 q11, q11, q15
355 vadd.u16 d16, d16, d17
356 vadd.u16 d18, d18, d19
357 vadd.u16 d20, d20, d21
359 vadd.u16 d22, d22, d23
362 vpadd.u16 d0, d16, d18
363 vpadd.u16 d1, d20, d22
368 vst1.32 {d1[0]}, [r7,:32]
370 vst1.32 {d0-d1}, [r7]
392 function x264_pixel_vsad_neon
394 vld1.8 {q0}, [r0], r1
395 vld1.8 {q1}, [r0], r1
401 vld1.8 {q0}, [r0], r1
404 vld1.8 {q1}, [r0], r1
416 function x264_pixel_asd8_neon
419 vld1.8 {d0}, [r0], r1
420 vld1.8 {d1}, [r2], r3
421 vld1.8 {d2}, [r0], r1
422 vld1.8 {d3}, [r2], r3
426 vld1.8 {d4}, [r0], r1
427 vld1.8 {d5}, [r2], r3
431 vld1.8 {d2}, [r0], r1
432 vld1.8 {d3}, [r2], r3
438 vpadd.s32 d16, d16, d17
439 vpadd.s32 d16, d16, d17
447 vld1.32 {d16[]}, [r0,:32], r1
448 vld1.32 {d17[]}, [r2,:32], r3
449 vsubl.u8 q2, d16, d17
450 vld1.32 {d16[]}, [r0,:32], r1
452 vld1.32 {d17[]}, [r2,:32], r3
456 vsubl.u8 q2, d16, d17
457 vld1.32 {d16[]}, [r0,:32], r1
459 vld1.32 {d17[]}, [r2,:32], r3
463 vsubl.u8 q2, d16, d17
468 vld1.64 {d16}, [r0,:64], r1
469 vld1.64 {d17}, [r2,:64], r3
470 vsubl.u8 q2, d16, d17
471 vld1.64 {d16}, [r0,:64], r1
474 vld1.64 {d17}, [r2,:64], r3
478 vsubl.u8 q2, d16, d17
479 vld1.64 {d16}, [r0,:64], r1
482 vld1.64 {d17}, [r2,:64], r3
486 vsubl.u8 q2, d16, d17
492 vld1.64 {d16-d17}, [r0,:128], r1
493 vld1.64 {d18-d19}, [r2,:128], r3
494 vsubl.u8 q2, d16, d18
495 vsubl.u8 q3, d17, d19
496 vld1.64 {d16-d17}, [r0,:128], r1
499 vld1.64 {d18-d19}, [r2,:128], r3
505 vsubl.u8 q2, d16, d18
506 vsubl.u8 q3, d17, d19
507 vld1.64 {d16-d17}, [r0,:128], r1
510 vld1.64 {d18-d19}, [r2,:128], r3
516 vsubl.u8 q2, d16, d18
517 vsubl.u8 q3, d17, d19
525 function x264_pixel_ssd_\w\()x\h\()_neon
546 function x264_pixel_ssd_nv12_core_neon
548 ldrd r4, r5, [sp, #8]
553 sub r1, r1, r12, lsl #1
554 sub r3, r3, r12, lsl #1
557 vld2.8 {d0,d1}, [r0]!
558 vld2.8 {d2,d3}, [r2]!
559 vld2.8 {d4,d5}, [r0]!
560 vld2.8 {d6,d7}, [r2]!
564 vmull.s16 q14, d20, d20
565 vmull.s16 q15, d22, d22
568 vmlal.s16 q14, d21, d21
569 vmlal.s16 q15, d23, d23
574 vmlal.s16 q14, d24, d24
575 vmlal.s16 q15, d26, d26
576 vld2.8 {d0,d1}, [r0]!
577 vld2.8 {d2,d3}, [r2]!
578 vmlal.s16 q14, d25, d25
579 vmlal.s16 q15, d27, d27
584 vmlal.s16 q14, d20, d20
585 vmlal.s16 q15, d22, d22
586 vld2.8 {d4,d5}, [r0]!
587 vld2.8 {d6,d7}, [r2]!
588 vmlal.s16 q14, d21, d21
589 vmlal.s16 q15, d23, d23
596 vmlal.s16 q14, d24, d24
597 vmlal.s16 q15, d26, d26
598 vmlal.s16 q14, d25, d25
599 vmlal.s16 q15, d27, d27
602 vaddw.s32 q8, q8, d28
603 vaddw.s32 q9, q9, d30
606 vaddw.s32 q8, q8, d29
607 vaddw.s32 q9, q9, d31
610 vadd.u64 d16, d16, d17
611 vadd.u64 d18, d18, d19
612 ldrd r4, r5, [sp, #16]
620 .macro VAR_SQR_SUM qsqr_sum qsqr_last qsqr dsrc vpadal=vpadal.u16
621 vmull.u8 \qsqr, \dsrc, \dsrc
622 vaddw.u8 q0, q0, \dsrc
623 \vpadal \qsqr_sum, \qsqr_last
626 function x264_pixel_var_8x8_neon
627 vld1.64 {d16}, [r0,:64], r1
628 vmull.u8 q1, d16, d16
630 vld1.64 {d18}, [r0,:64], r1
631 vmull.u8 q2, d18, d18
634 vld1.64 {d20}, [r0,:64], r1
635 VAR_SQR_SUM q1, q1, q3, d20, vpaddl.u16
636 vld1.64 {d22}, [r0,:64], r1
637 VAR_SQR_SUM q2, q2, q8, d22, vpaddl.u16
639 vld1.64 {d24}, [r0,:64], r1
640 VAR_SQR_SUM q1, q3, q9, d24
641 vld1.64 {d26}, [r0,:64], r1
642 VAR_SQR_SUM q2, q8, q10, d26
643 vld1.64 {d24}, [r0,:64], r1
644 VAR_SQR_SUM q1, q9, q14, d24
645 vld1.64 {d26}, [r0,:64], r1
646 VAR_SQR_SUM q2, q10, q15, d26
650 function x264_pixel_var_8x16_neon
651 vld1.64 {d16}, [r0,:64], r1
652 vld1.64 {d18}, [r0,:64], r1
653 vmull.u8 q1, d16, d16
655 vld1.64 {d20}, [r0,:64], r1
656 vmull.u8 q2, d18, d18
661 vld1.64 {d22}, [r0,:64], r1
662 VAR_SQR_SUM q1, q1, q14, d20, vpaddl.u16
663 vld1.64 {d16}, [r0,:64], r1
664 VAR_SQR_SUM q2, q2, q15, d22, vpaddl.u16
667 vld1.64 {d18}, [r0,:64], r1
668 VAR_SQR_SUM q1, q14, q12, d16
669 vld1.64 {d20}, [r0,:64], r1
670 VAR_SQR_SUM q2, q15, q13, d18
671 vld1.64 {d22}, [r0,:64], r1
672 VAR_SQR_SUM q1, q12, q14, d20
674 vld1.64 {d16}, [r0,:64], r1
675 VAR_SQR_SUM q2, q13, q15, d22
678 VAR_SQR_SUM q2, q13, q15, d22
682 function x264_pixel_var_16x16_neon
683 vld1.64 {d16-d17}, [r0,:128], r1
684 vmull.u8 q12, d16, d16
686 vmull.u8 q13, d17, d17
689 vld1.64 {d18-d19}, [r0,:128], r1
690 VAR_SQR_SUM q1, q12, q14, d18, vpaddl.u16
691 VAR_SQR_SUM q2, q13, q15, d19, vpaddl.u16
696 vld1.64 {d16-d17}, [r0,:128], r1
697 VAR_SQR_SUM q1, q14, q12, d16
698 VAR_SQR_SUM q2, q15, q13, d17
700 vld1.64 {d18-d19}, [r0,:128], r1
701 VAR_SQR_SUM q1, q12, q14, d18
702 VAR_SQR_SUM q2, q13, q15, d19
706 function x264_var_end, export=0
721 .macro DIFF_SUM diff da db lastdiff
722 vld1.64 {\da}, [r0,:64], r1
723 vld1.64 {\db}, [r2,:64], r3
725 vadd.s16 q0, q0, \lastdiff
727 vsubl.u8 \diff, \da, \db
730 .macro SQR_ACC acc d0 d1 vmlal=vmlal.s16
731 \vmlal \acc, \d0, \d0
732 vmlal.s16 \acc, \d1, \d1
735 function x264_pixel_var2_8x8_neon
737 DIFF_SUM q8, d16, d17
738 SQR_ACC q1, d0, d1, vmull.s16
739 DIFF_SUM q9, d18, d19, q8
740 SQR_ACC q2, d16, d17, vmull.s16
742 DIFF_SUM q8, d16, d17, q9
744 DIFF_SUM q9, d18, d19, q8
747 DIFF_SUM q8, d16, d17, q9
760 vst1.32 {d0[1]}, [ip,:32]
762 sub r0, r1, r0, lsr #6
766 function x264_pixel_var2_8x16_neon
767 vld1.64 {d16}, [r0,:64], r1
768 vld1.64 {d17}, [r2,:64], r3
769 vld1.64 {d18}, [r0,:64], r1
770 vld1.64 {d19}, [r2,:64], r3
771 vsubl.u8 q10, d16, d17
772 vsubl.u8 q11, d18, d19
773 SQR_ACC q1, d20, d21, vmull.s16
774 vld1.64 {d16}, [r0,:64], r1
775 vadd.s16 q0, q10, q11
776 vld1.64 {d17}, [r2,:64], r3
777 SQR_ACC q2, d22, d23, vmull.s16
780 vld1.64 {d18}, [r0,:64], r1
781 vsubl.u8 q10, d16, d17
782 vld1.64 {d19}, [r2,:64], r3
785 vsubl.u8 q11, d18, d19
787 vld1.64 {d16}, [r0,:64], r1
789 vld1.64 {d17}, [r2,:64], r3
804 vst1.32 {d0[1]}, [ip,:32]
806 sub r0, r1, r0, lsr #7
810 .macro LOAD_DIFF_8x4 q0 q1 q2 q3
811 vld1.32 {d1}, [r2], r3
812 vld1.32 {d0}, [r0,:64], r1
814 vld1.32 {d3}, [r2], r3
815 vld1.32 {d2}, [r0,:64], r1
817 vld1.32 {d5}, [r2], r3
818 vld1.32 {d4}, [r0,:64], r1
820 vld1.32 {d7}, [r2], r3
821 vld1.32 {d6}, [r0,:64], r1
825 function x264_pixel_satd_4x4_neon
826 vld1.32 {d1[]}, [r2], r3
827 vld1.32 {d0[]}, [r0,:32], r1
828 vld1.32 {d3[]}, [r2], r3
829 vld1.32 {d2[]}, [r0,:32], r1
830 vld1.32 {d1[1]}, [r2], r3
831 vld1.32 {d0[1]}, [r0,:32], r1
832 vld1.32 {d3[1]}, [r2], r3
833 vld1.32 {d2[1]}, [r0,:32], r1
837 SUMSUB_AB q2, q3, q0, q1
838 SUMSUB_ABCD d0, d2, d1, d3, d4, d5, d6, d7
839 HADAMARD 1, sumsub, q2, q3, q0, q1
840 HADAMARD 2, amax, q0,, q2, q3
847 function x264_pixel_satd_4x8_neon
848 vld1.32 {d1[]}, [r2], r3
849 vld1.32 {d0[]}, [r0,:32], r1
850 vld1.32 {d3[]}, [r2], r3
851 vld1.32 {d2[]}, [r0,:32], r1
852 vld1.32 {d5[]}, [r2], r3
853 vld1.32 {d4[]}, [r0,:32], r1
854 vld1.32 {d7[]}, [r2], r3
855 vld1.32 {d6[]}, [r0,:32], r1
857 vld1.32 {d1[1]}, [r2], r3
858 vld1.32 {d0[1]}, [r0,:32], r1
860 vld1.32 {d3[1]}, [r2], r3
861 vld1.32 {d2[1]}, [r0,:32], r1
863 vld1.32 {d5[1]}, [r2], r3
864 vld1.32 {d4[1]}, [r0,:32], r1
866 vld1.32 {d7[1]}, [r2], r3
867 SUMSUB_AB q8, q9, q0, q1
868 vld1.32 {d6[1]}, [r0,:32], r1
870 SUMSUB_AB q10, q11, q2, q3
871 b x264_satd_4x8_8x4_end_neon
874 function x264_pixel_satd_8x4_neon
875 vld1.64 {d1}, [r2], r3
876 vld1.64 {d0}, [r0,:64], r1
878 vld1.64 {d3}, [r2], r3
879 vld1.64 {d2}, [r0,:64], r1
881 vld1.64 {d5}, [r2], r3
882 vld1.64 {d4}, [r0,:64], r1
884 vld1.64 {d7}, [r2], r3
885 SUMSUB_AB q8, q9, q0, q1
886 vld1.64 {d6}, [r0,:64], r1
888 SUMSUB_AB q10, q11, q2, q3
891 function x264_satd_4x8_8x4_end_neon, export=0
918 function x264_pixel_satd_8x8_neon
921 bl x264_satd_8x8_neon
922 vadd.u16 q0, q12, q13
923 vadd.u16 q1, q14, q15
932 function x264_pixel_satd_8x16_neon
936 bl x264_satd_8x8_neon
937 vadd.u16 q4, q12, q13
938 vadd.u16 q5, q14, q15
940 bl x264_satd_8x8_neon
954 function x264_satd_8x8_neon, export=0
955 LOAD_DIFF_8x4 q8, q9, q10, q11
956 vld1.64 {d7}, [r2], r3
957 SUMSUB_AB q0, q1, q8, q9
958 vld1.64 {d6}, [r0,:64], r1
960 vld1.64 {d17}, [r2], r3
961 SUMSUB_AB q2, q3, q10, q11
962 vld1.64 {d16}, [r0,:64], r1
963 vsubl.u8 q13, d16, d17
964 vld1.64 {d19}, [r2], r3
965 SUMSUB_AB q8, q10, q0, q2
966 vld1.64 {d18}, [r0,:64], r1
967 vsubl.u8 q14, d18, d19
968 vld1.64 {d1}, [r2], r3
969 SUMSUB_AB q9, q11, q1, q3
970 vld1.64 {d0}, [r0,:64], r1
974 // one vertical hadamard pass and two horizontal
975 function x264_satd_8x4v_8x8h_neon, export=0
976 SUMSUB_ABCD q0, q1, q2, q3, q12, q13, q14, q15
978 SUMSUB_AB q12, q14, q0, q2
980 SUMSUB_AB q13, q15, q1, q3
981 SUMSUB_AB q0, q1, q8, q9
983 SUMSUB_AB q2, q3, q10, q11
985 SUMSUB_AB q8, q9, q12, q13
987 SUMSUB_AB q10, q11, q14, q15
998 vmax.s16 q14, q8, q10
999 vmax.s16 q15, q9, q11
1003 function x264_pixel_satd_16x8_neon
1007 bl x264_satd_16x4_neon
1008 vadd.u16 q4, q12, q13
1009 vadd.u16 q5, q14, q15
1011 bl x264_satd_16x4_neon
1012 vadd.u16 q4, q4, q12
1013 vadd.u16 q5, q5, q13
1014 vadd.u16 q4, q4, q14
1015 vadd.u16 q5, q5, q15
1018 HORIZ_ADD d0, d0, d1
1025 function x264_pixel_satd_16x16_neon
1029 bl x264_satd_16x4_neon
1030 vadd.u16 q4, q12, q13
1031 vadd.u16 q5, q14, q15
1033 bl x264_satd_16x4_neon
1034 vadd.u16 q4, q4, q12
1035 vadd.u16 q5, q5, q13
1036 vadd.u16 q4, q4, q14
1037 vadd.u16 q5, q5, q15
1039 bl x264_satd_16x4_neon
1040 vadd.u16 q4, q4, q12
1041 vadd.u16 q5, q5, q13
1042 vadd.u16 q4, q4, q14
1043 vadd.u16 q5, q5, q15
1045 bl x264_satd_16x4_neon
1046 vadd.u16 q4, q4, q12
1047 vadd.u16 q5, q5, q13
1048 vadd.u16 q4, q4, q14
1049 vadd.u16 q5, q5, q15
1052 HORIZ_ADD d0, d0, d1
1059 function x264_satd_16x4_neon, export=0
1060 vld1.64 {d2-d3}, [r2], r3
1061 vld1.64 {d0-d1}, [r0,:128], r1
1063 vld1.64 {d6-d7}, [r2], r3
1064 vsubl.u8 q12, d1, d3
1065 vld1.64 {d4-d5}, [r0,:128], r1
1067 vld1.64 {d2-d3}, [r2], r3
1068 vsubl.u8 q13, d5, d7
1069 vld1.64 {d0-d1}, [r0,:128], r1
1070 vsubl.u8 q10, d0, d2
1071 vld1.64 {d6-d7}, [r2], r3
1072 vsubl.u8 q14, d1, d3
1074 vld1.64 {d4-d5}, [r0,:128], r1
1076 vsubl.u8 q11, d4, d6
1077 vsubl.u8 q15, d5, d7
1078 SUMSUB_AB q2, q3, q10, q11
1079 SUMSUB_ABCD q8, q10, q9, q11, q0, q2, q1, q3
1080 b x264_satd_8x4v_8x8h_neon
1084 function x264_pixel_sa8d_8x8_neon
1086 bl x264_sa8d_8x8_neon
1088 HORIZ_ADD d0, d0, d1
1096 function x264_pixel_sa8d_16x16_neon
1099 bl x264_sa8d_8x8_neon
1102 bl x264_sa8d_8x8_neon
1105 sub r0, r0, r1, lsl #4
1106 sub r2, r2, r3, lsl #4
1109 bl x264_sa8d_8x8_neon
1112 bl x264_sa8d_8x8_neon
1119 vpadd.u32 d0, d0, d0
1128 .macro HADAMARD4_V r1, r2, r3, r4, t1, t2, t3, t4
1129 SUMSUB_ABCD \t1, \t2, \t3, \t4, \r1, \r2, \r3, \r4
1130 SUMSUB_ABCD \r1, \r3, \r2, \r4, \t1, \t3, \t2, \t4
1133 function x264_sa8d_8x8_neon, export=0
1134 LOAD_DIFF_8x4 q8, q9, q10, q11
1135 vld1.64 {d7}, [r2], r3
1136 SUMSUB_AB q0, q1, q8, q9
1137 vld1.64 {d6}, [r0,:64], r1
1138 vsubl.u8 q12, d6, d7
1139 vld1.64 {d17}, [r2], r3
1140 SUMSUB_AB q2, q3, q10, q11
1141 vld1.64 {d16}, [r0,:64], r1
1142 vsubl.u8 q13, d16, d17
1143 vld1.64 {d19}, [r2], r3
1144 SUMSUB_AB q8, q10, q0, q2
1145 vld1.64 {d18}, [r0,:64], r1
1146 vsubl.u8 q14, d18, d19
1147 vld1.64 {d1}, [r2], r3
1148 SUMSUB_AB q9, q11, q1, q3
1149 vld1.64 {d0}, [r0,:64], r1
1150 vsubl.u8 q15, d0, d1
1152 HADAMARD4_V q12, q13, q14, q15, q0, q1, q2, q3
1153 SUMSUB_ABCD q0, q8, q1, q9, q8, q12, q9, q13
1154 SUMSUB_AB q2, q10, q10, q14
1156 SUMSUB_AB q3, q11, q11, q15
1158 SUMSUB_AB q12, q13, q8, q9
1160 SUMSUB_AB q8, q9, q0, q1
1162 SUMSUB_AB q14, q15, q10, q11
1163 vadd.i16 q10, q2, q3
1165 vsub.i16 q11, q2, q3
1167 SUMSUB_AB q0, q2, q12, q14
1169 SUMSUB_AB q1, q3, q13, q15
1171 SUMSUB_AB q12, q14, q8, q10
1172 SUMSUB_AB q13, q15, q9, q11
1182 vmax.s16 q8, q0, q12
1183 vmax.s16 q9, q1, q13
1184 vmax.s16 q10, q2, q14
1185 vmax.s16 q11, q3, q15
1187 vadd.i16 q9, q10, q11
1192 .macro HADAMARD_AC w h
1193 function x264_pixel_hadamard_ac_\w\()x\h\()_neon
1197 // note: this assumes mask_ac8 is after mask_ac4 (so don't move it)
1198 vld1.64 {d12-d15}, [ip,:128]
1202 bl x264_hadamard_ac_8x8_neon
1204 bl x264_hadamard_ac_8x8_neon
1207 sub r0, r0, r1, lsl #3
1209 bl x264_hadamard_ac_8x8_neon
1212 sub r0, r0, r1, lsl #4
1213 bl x264_hadamard_ac_8x8_neon
1217 vadd.s32 d10, d10, d11
1218 vpadd.s32 d0, d8, d10
1233 // q4: satd q5: sa8d q6: mask_ac4 q7: mask_ac8
1234 function x264_hadamard_ac_8x8_neon, export=0
1235 vld1.64 {d2}, [r0,:64], r1
1236 vld1.64 {d3}, [r0,:64], r1
1238 vld1.64 {d6}, [r0,:64], r1
1240 vld1.64 {d7}, [r0,:64], r1
1242 vld1.64 {d18}, [r0,:64], r1
1244 vld1.64 {d19}, [r0,:64], r1
1245 vaddl.u8 q8, d18, d19
1246 vld1.64 {d22}, [r0,:64], r1
1247 vsubl.u8 q9, d18, d19
1248 vld1.64 {d23}, [r0,:64], r1
1250 SUMSUB_ABCD q12, q14, q13, q15, q0, q2, q1, q3
1251 vaddl.u8 q10, d22, d23
1252 vsubl.u8 q11, d22, d23
1254 SUMSUB_ABCD q0, q2, q1, q3, q8, q10, q9, q11
1257 SUMSUB_AB q8, q9, q12, q13
1259 SUMSUB_AB q10, q11, q14, q15
1261 SUMSUB_AB q12, q13, q0, q1
1263 SUMSUB_AB q14, q15, q2, q3
1265 SUMSUB_AB q0, q2, q8, q10
1267 SUMSUB_AB q1, q3, q9, q11
1269 SUMSUB_ABCD q8, q10, q9, q11, q12, q14, q13, q15
1274 vadd.s16 q12, q12, q13
1276 vand.s16 q12, q12, q6
1278 vadd.s16 q12, q12, q15
1280 vadd.s16 q12, q12, q14
1282 vadd.s16 q12, q12, q13
1284 vadd.s16 q12, q12, q15
1285 vsub.s16 q15, q11, q3
1286 vadd.s16 q12, q12, q14
1287 vadd.s16 q14, q11, q3
1288 vadd.s16 q12, q12, q13
1289 vsub.s16 q13, q10, q2
1290 vadd.s16 q2, q10, q2
1293 SUMSUB_AB q10, q11, q9, q1
1294 SUMSUB_AB q9, q8, q0, q8
1304 vmax.s16 q3, q14, q15
1305 vmax.s16 q2, q2, q13
1306 vmax.s16 q1, q10, q11
1308 SUMSUB_AB q14, q15, q9, q8
1316 vadd.s16 q2, q2, q15
1317 vadd.s16 q2, q2, q14
1323 .macro SSIM_ITER n ssa s12 ssb lastssa lasts12 lastssb da db dnext
1324 vld1.64 {\db}, [r2], r3
1325 vmull.u8 \ssa, \da, \da
1326 vmull.u8 \s12, \da, \db
1328 vpaddl.u16 q2, \lastssa
1329 vpaddl.u16 q3, \lasts12
1330 vaddl.u8 q0, d0, \da
1332 vpadal.u16 q2, \lastssa
1333 vpadal.u16 q3, \lasts12
1334 vaddw.u8 q0, q0, \da
1336 vpadal.u16 q2, \lastssb
1338 vld1.64 {\dnext}, [r0], r1
1341 vaddl.u8 q1, d2, \db
1343 vaddw.u8 q1, q1, \db
1345 vmull.u8 \ssb, \db, \db
1348 function x264_pixel_ssim_4x4x2_core_neon
1350 vld1.64 {d0}, [r0], r1
1351 vld1.64 {d2}, [r2], r3
1354 vld1.64 {d28}, [r0], r1
1355 vmull.u8 q15, d2, d2
1357 SSIM_ITER 1, q8, q9, q14, q2, q3, q15, d28, d29, d26
1358 SSIM_ITER 2, q10,q11,q13, q8, q9, q14, d26, d27, d28
1359 SSIM_ITER 3, q8, q9, q15, q10,q11,q13, d28, d29
1367 vpadd.u32 d0, d0, d1
1368 vpadd.u32 d1, d2, d3
1369 vpadd.u32 d2, d4, d5
1370 vpadd.u32 d3, d6, d7
1372 vst4.32 {d0-d3}, [ip]
1376 // FIXME: see about doing 16x16 -> 32 bit multiplies for s1/s2
1377 function x264_pixel_ssim_end4_neon
1378 vld1.32 {d16-d19}, [r0,:128]!
1379 vld1.32 {d20-d23}, [r1,:128]!
1380 vadd.s32 q0, q8, q10
1381 vadd.s32 q1, q9, q11
1382 vld1.32 {d24-d27}, [r0,:128]!
1384 vld1.32 {d28-d31}, [r1,:128]!
1385 vadd.s32 q2, q12, q14
1386 vadd.s32 q3, q13, q15
1387 vld1.32 {d16-d17}, [r0,:128]
1389 vld1.32 {d18-d19}, [r1,:128]
1399 // s1=q0, s2=q1, ss=q2, s12=q3
1400 vmul.s32 q8, q0, q1 // s1*s2
1402 vmla.s32 q0, q1, q1 // s1*s1 + s2*s2
1408 mov r3, #416 // ssim_c1 = .01*.01*255*255*64
1409 movconst ip, 235963 // ssim_c2 = .03*.03*255*255*64*63
1413 vsub.s32 q2, q2, q0 // vars
1414 vsub.s32 q3, q3, q1 // covar*2
1415 vadd.s32 q0, q0, q14
1416 vadd.s32 q2, q2, q15
1417 vadd.s32 q1, q1, q14
1418 vadd.s32 q3, q3, q15
1437 sub r3, r3, r2, lsl #2
1438 vld1.64 {d6-d7}, [r3]
1442 vpadd.f32 d0, d0, d0