1 /*****************************************************************************
2 * pixel.S: arm pixel metrics
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 *****************************************************************************/
39 .short 0, -1, -1, -1, 0, -1, -1, -1
41 .short 0, -1, -1, -1, -1, -1, -1, -1
46 function x264_pixel_sad_4x\h\()_armv6
70 .macro SAD_START_4 align:vararg
71 vld1.32 {d1[]}, [r2 \align], r3
72 vld1.32 {d0[]}, [r0,:32], r1
76 .macro SAD_4 align:vararg
77 vld1.32 {d1[]}, [r2 \align], r3
78 vld1.32 {d0[]}, [r0,:32], r1
82 .macro SAD_START_8 align:vararg
83 vld1.64 {d1}, [r2 \align], r3
84 vld1.64 {d0}, [r0,:64], r1
88 .macro SAD_8 align:vararg
89 vld1.64 {d1}, [r2 \align], r3
90 vld1.64 {d0}, [r0,:64], r1
94 .macro SAD_START_16 align:vararg
95 vld1.64 {d2-d3}, [r2 \align], r3
96 vld1.64 {d0-d1}, [r0,:128], r1
98 vld1.64 {d6-d7}, [r2 \align], r3
100 vld1.64 {d4-d5}, [r0,:128], r1
103 .macro SAD_16 align:vararg
105 vld1.64 {d2-d3}, [r2 \align], r3
107 vld1.64 {d0-d1}, [r0,:128], r1
109 vld1.64 {d6-d7}, [r2 \align], r3
111 vld1.64 {d4-d5}, [r0,:128], r1
114 .macro SAD_FUNC w, h, name, align:vararg
115 function x264_pixel_sad\name\()_\w\()x\h\()_neon
134 vadd.u16 d16, d16, d17
136 vpadd.u16 d0, d16, d16
151 SAD_FUNC 4, 4, _aligned, ,:32
152 SAD_FUNC 4, 8, _aligned, ,:32
153 SAD_FUNC 8, 4, _aligned, ,:64
154 SAD_FUNC 8, 8, _aligned, ,:64
155 SAD_FUNC 8, 16, _aligned, ,:64
156 SAD_FUNC 16, 8, _aligned, ,:128
157 SAD_FUNC 16, 16, _aligned, ,:128
159 // If dual issue is possible, use additional accumulators to avoid
160 // stalls from vadal's latency. This only matters for aligned.
161 .macro SAD_DUAL_START_8
163 vld1.64 {d3}, [r2,:64], r3
164 vld1.64 {d2}, [r0,:64], r1
168 .macro SAD_DUAL_8 align:vararg
169 vld1.64 {d1}, [r2,:64], r3
170 vld1.64 {d0}, [r0,:64], r1
172 vld1.64 {d3}, [r2,:64], r3
173 vld1.64 {d2}, [r0,:64], r1
177 .macro SAD_DUAL_START_16
180 vld1.64 {d2-d3}, [r2,:128], r3
182 vld1.64 {d0-d1}, [r0,:128], r1
187 vld1.64 {d6-d7}, [r2,:128], r3
189 vld1.64 {d4-d5}, [r0,:128], r1
191 vld1.64 {d2-d3}, [r2,:128], r3
193 vld1.64 {d0-d1}, [r0,:128], r1
196 .macro SAD_DUAL_END_16
198 vld1.64 {d6-d7}, [r2,:128], r3
200 vld1.64 {d4-d5}, [r0,:128], r1
205 .macro SAD_FUNC_DUAL w, h
206 function x264_pixel_sad_aligned_\w\()x\h\()_neon_dual
208 .rept \h / 2 - \w / 8
215 vadd.u16 q9, q10, q11
219 vadd.u16 d16, d16, d17
221 vpadd.u16 d0, d16, d16
235 .macro SAD_X_START_4 x
236 vld1.32 {d0[]}, [r0,:32], lr
237 vld1.32 {d1[]}, [r1], r6
239 vld1.32 {d2[]}, [r2], r6
241 vld1.32 {d3[]}, [r3], r6
244 vld1.32 {d4[]}, [r12], r6
250 vld1.32 {d0[]}, [r0,:32], lr
251 vld1.32 {d1[]}, [r1], r6
253 vld1.32 {d2[]}, [r2], r6
255 vld1.32 {d3[]}, [r3], r6
258 vld1.32 {d4[]}, [r12], r6
263 .macro SAD_X_START_8 x
264 vld1.64 {d0}, [r0,:64], lr
265 vld1.64 {d1}, [r1], r6
267 vld1.64 {d2}, [r2], r6
269 vld1.64 {d3}, [r3], r6
272 vld1.64 {d4}, [r12], r6
278 vld1.64 {d0}, [r0,:64], lr
279 vld1.64 {d1}, [r1], r6
281 vld1.64 {d2}, [r2], r6
283 vld1.64 {d3}, [r3], r6
286 vld1.64 {d4}, [r12], r6
291 .macro SAD_X_START_16 x
292 vld1.64 {d0-d1}, [r0,:128], lr
293 vld1.64 {d2-d3}, [r1], r6
296 vld1.64 {d4-d5}, [r2], r6
299 vld1.64 {d6-d7}, [r3], r6
303 vld1.64 {d2-d3}, [r12], r6
310 vld1.64 {d0-d1}, [r0,:128], lr
311 vld1.64 {d2-d3}, [r1], r6
314 vld1.64 {d4-d5}, [r2], r6
317 vld1.64 {d6-d7}, [r3], r6
321 vld1.64 {d2-d3}, [r12], r6
327 .macro SAD_X_FUNC x, w, h
328 function x264_pixel_sad_x\x\()_\w\()x\h\()_neon
347 vadd.u16 q10, q10, q14
349 vadd.u16 q11, q11, q15
353 vadd.u16 d16, d16, d17
354 vadd.u16 d18, d18, d19
355 vadd.u16 d20, d20, d21
357 vadd.u16 d22, d22, d23
360 vpadd.u16 d0, d16, d18
361 vpadd.u16 d1, d20, d22
366 vst1.32 {d1[0]}, [r7,:32]
368 vst1.32 {d0-d1}, [r7]
392 vld1.32 {d16[]}, [r0,:32], r1
393 vld1.32 {d17[]}, [r2,:32], r3
394 vsubl.u8 q2, d16, d17
395 vld1.32 {d16[]}, [r0,:32], r1
397 vld1.32 {d17[]}, [r2,:32], r3
401 vsubl.u8 q2, d16, d17
402 vld1.32 {d16[]}, [r0,:32], r1
404 vld1.32 {d17[]}, [r2,:32], r3
408 vsubl.u8 q2, d16, d17
413 vld1.64 {d16}, [r0,:64], r1
414 vld1.64 {d17}, [r2,:64], r3
415 vsubl.u8 q2, d16, d17
416 vld1.64 {d16}, [r0,:64], r1
419 vld1.64 {d17}, [r2,:64], r3
423 vsubl.u8 q2, d16, d17
424 vld1.64 {d16}, [r0,:64], r1
427 vld1.64 {d17}, [r2,:64], r3
431 vsubl.u8 q2, d16, d17
437 vld1.64 {d16-d17}, [r0,:128], r1
438 vld1.64 {d18-d19}, [r2,:128], r3
439 vsubl.u8 q2, d16, d18
440 vsubl.u8 q3, d17, d19
441 vld1.64 {d16-d17}, [r0,:128], r1
444 vld1.64 {d18-d19}, [r2,:128], r3
450 vsubl.u8 q2, d16, d18
451 vsubl.u8 q3, d17, d19
452 vld1.64 {d16-d17}, [r0,:128], r1
455 vld1.64 {d18-d19}, [r2,:128], r3
461 vsubl.u8 q2, d16, d18
462 vsubl.u8 q3, d17, d19
470 function x264_pixel_ssd_\w\()x\h\()_neon
492 .macro VAR_SQR_SUM qsqr_sum qsqr_last qsqr dsrc vpadal=vpadal.u16
493 vmull.u8 \qsqr, \dsrc, \dsrc
494 vaddw.u8 q0, q0, \dsrc
495 \vpadal \qsqr_sum, \qsqr_last
498 function x264_pixel_var_8x8_neon
499 vld1.64 {d16}, [r0,:64], r1
500 vmull.u8 q1, d16, d16
502 vld1.64 {d18}, [r0,:64], r1
503 vmull.u8 q2, d18, d18
506 vld1.64 {d20}, [r0,:64], r1
507 VAR_SQR_SUM q1, q1, q3, d20, vpaddl.u16
508 vld1.64 {d22}, [r0,:64], r1
509 VAR_SQR_SUM q2, q2, q8, d22, vpaddl.u16
511 vld1.64 {d24}, [r0,:64], r1
512 VAR_SQR_SUM q1, q3, q9, d24
513 vld1.64 {d26}, [r0,:64], r1
514 VAR_SQR_SUM q2, q8, q10, d26
515 vld1.64 {d24}, [r0,:64], r1
516 VAR_SQR_SUM q1, q9, q14, d24
517 vld1.64 {d26}, [r0,:64], r1
518 VAR_SQR_SUM q2, q10, q15, d26
522 function x264_pixel_var_16x16_neon
523 vld1.64 {d16-d17}, [r0,:128], r1
524 vmull.u8 q12, d16, d16
526 vmull.u8 q13, d17, d17
529 vld1.64 {d18-d19}, [r0,:128], r1
530 VAR_SQR_SUM q1, q12, q14, d18, vpaddl.u16
531 VAR_SQR_SUM q2, q13, q15, d19, vpaddl.u16
536 vld1.64 {d16-d17}, [r0,:128], r1
537 VAR_SQR_SUM q1, q14, q12, d16
538 VAR_SQR_SUM q2, q15, q13, d17
540 vld1.64 {d18-d19}, [r0,:128], r1
541 VAR_SQR_SUM q1, q12, q14, d18
542 VAR_SQR_SUM q2, q13, q15, d19
546 function x264_var_end
561 .macro DIFF_SUM diff da db lastdiff
562 vld1.64 {\da}, [r0,:64], r1
563 vld1.64 {\db}, [r2,:64], r3
565 vadd.s16 q0, q0, \lastdiff
567 vsubl.u8 \diff, \da, \db
570 .macro SQR_ACC acc d0 d1 vmlal=vmlal.s16
571 \vmlal \acc, \d0, \d0
572 vmlal.s16 \acc, \d1, \d1
575 function x264_pixel_var2_8x8_neon
577 DIFF_SUM q8, d16, d17
578 SQR_ACC q1, d0, d1, vmull.s16
579 DIFF_SUM q9, d18, d19, q8
580 SQR_ACC q2, d16, d17, vmull.s16
582 DIFF_SUM q8, d16, d17, q9
584 DIFF_SUM q9, d18, d19, q8
587 DIFF_SUM q8, d16, d17, q9
600 vst1.32 {d0[1]}, [ip,:32]
602 sub r0, r1, r0, lsr #6
607 .macro LOAD_DIFF_8x4 q0 q1 q2 q3
608 vld1.32 {d1}, [r2], r3
609 vld1.32 {d0}, [r0,:64], r1
611 vld1.32 {d3}, [r2], r3
612 vld1.32 {d2}, [r0,:64], r1
614 vld1.32 {d5}, [r2], r3
615 vld1.32 {d4}, [r0,:64], r1
617 vld1.32 {d7}, [r2], r3
618 vld1.32 {d6}, [r0,:64], r1
622 function x264_pixel_satd_4x4_neon
623 vld1.32 {d1[]}, [r2], r3
624 vld1.32 {d0[]}, [r0,:32], r1
625 vld1.32 {d3[]}, [r2], r3
626 vld1.32 {d2[]}, [r0,:32], r1
627 vld1.32 {d1[1]}, [r2], r3
628 vld1.32 {d0[1]}, [r0,:32], r1
629 vld1.32 {d3[1]}, [r2], r3
630 vld1.32 {d2[1]}, [r0,:32], r1
634 SUMSUB_AB q2, q3, q0, q1
635 SUMSUB_ABCD d0, d2, d1, d3, d4, d5, d6, d7
636 HADAMARD 1, sumsub, q2, q3, q0, q1
637 HADAMARD 2, amax, q0,, q2, q3
644 function x264_pixel_satd_4x8_neon
645 vld1.32 {d1[]}, [r2], r3
646 vld1.32 {d0[]}, [r0,:32], r1
647 vld1.32 {d3[]}, [r2], r3
648 vld1.32 {d2[]}, [r0,:32], r1
649 vld1.32 {d5[]}, [r2], r3
650 vld1.32 {d4[]}, [r0,:32], r1
651 vld1.32 {d7[]}, [r2], r3
652 vld1.32 {d6[]}, [r0,:32], r1
654 vld1.32 {d1[1]}, [r2], r3
655 vld1.32 {d0[1]}, [r0,:32], r1
657 vld1.32 {d3[1]}, [r2], r3
658 vld1.32 {d2[1]}, [r0,:32], r1
660 vld1.32 {d5[1]}, [r2], r3
661 vld1.32 {d4[1]}, [r0,:32], r1
663 vld1.32 {d7[1]}, [r2], r3
664 SUMSUB_AB q8, q9, q0, q1
665 vld1.32 {d6[1]}, [r0,:32], r1
667 SUMSUB_AB q10, q11, q2, q3
668 b x264_satd_4x8_8x4_end_neon
671 function x264_pixel_satd_8x4_neon
672 vld1.64 {d1}, [r2], r3
673 vld1.64 {d0}, [r0,:64], r1
675 vld1.64 {d3}, [r2], r3
676 vld1.64 {d2}, [r0,:64], r1
678 vld1.64 {d5}, [r2], r3
679 vld1.64 {d4}, [r0,:64], r1
681 vld1.64 {d7}, [r2], r3
682 SUMSUB_AB q8, q9, q0, q1
683 vld1.64 {d6}, [r0,:64], r1
685 SUMSUB_AB q10, q11, q2, q3
688 function x264_satd_4x8_8x4_end_neon
715 function x264_pixel_satd_8x8_neon
718 bl x264_satd_8x8_neon
719 vadd.u16 q0, q12, q13
720 vadd.u16 q1, q14, q15
729 function x264_pixel_satd_8x16_neon
733 bl x264_satd_8x8_neon
734 vadd.u16 q4, q12, q13
735 vadd.u16 q5, q14, q15
737 bl x264_satd_8x8_neon
751 function x264_satd_8x8_neon
752 LOAD_DIFF_8x4 q8, q9, q10, q11
753 vld1.64 {d7}, [r2], r3
754 SUMSUB_AB q0, q1, q8, q9
755 vld1.64 {d6}, [r0,:64], r1
757 vld1.64 {d17}, [r2], r3
758 SUMSUB_AB q2, q3, q10, q11
759 vld1.64 {d16}, [r0,:64], r1
760 vsubl.u8 q13, d16, d17
761 vld1.64 {d19}, [r2], r3
762 SUMSUB_AB q8, q10, q0, q2
763 vld1.64 {d18}, [r0,:64], r1
764 vsubl.u8 q14, d18, d19
765 vld1.64 {d1}, [r2], r3
766 SUMSUB_AB q9, q11, q1, q3
767 vld1.64 {d0}, [r0,:64], r1
771 // one vertical hadamard pass and two horizontal
772 function x264_satd_8x4v_8x8h_neon
773 SUMSUB_ABCD q0, q1, q2, q3, q12, q13, q14, q15
775 SUMSUB_AB q12, q14, q0, q2
777 SUMSUB_AB q13, q15, q1, q3
778 SUMSUB_AB q0, q1, q8, q9
780 SUMSUB_AB q2, q3, q10, q11
782 SUMSUB_AB q8, q9, q12, q13
784 SUMSUB_AB q10, q11, q14, q15
795 vmax.s16 q14, q8, q10
796 vmax.s16 q15, q9, q11
800 function x264_pixel_satd_16x8_neon
804 bl x264_satd_16x4_neon
805 vadd.u16 q4, q12, q13
806 vadd.u16 q5, q14, q15
808 bl x264_satd_16x4_neon
822 function x264_pixel_satd_16x16_neon
826 bl x264_satd_16x4_neon
827 vadd.u16 q4, q12, q13
828 vadd.u16 q5, q14, q15
830 bl x264_satd_16x4_neon
836 bl x264_satd_16x4_neon
842 bl x264_satd_16x4_neon
856 function x264_satd_16x4_neon
857 vld1.64 {d2-d3}, [r2], r3
858 vld1.64 {d0-d1}, [r0,:128], r1
860 vld1.64 {d6-d7}, [r2], r3
862 vld1.64 {d4-d5}, [r0,:128], r1
864 vld1.64 {d2-d3}, [r2], r3
866 vld1.64 {d0-d1}, [r0,:128], r1
868 vld1.64 {d6-d7}, [r2], r3
871 vld1.64 {d4-d5}, [r0,:128], r1
875 SUMSUB_AB q2, q3, q10, q11
876 SUMSUB_ABCD q8, q10, q9, q11, q0, q2, q1, q3
877 b x264_satd_8x4v_8x8h_neon
881 function x264_pixel_sa8d_8x8_neon
883 bl x264_sa8d_8x8_neon
893 function x264_pixel_sa8d_16x16_neon
896 bl x264_sa8d_8x8_neon
899 bl x264_sa8d_8x8_neon
902 sub r0, r0, r1, lsl #4
903 sub r2, r2, r3, lsl #4
906 bl x264_sa8d_8x8_neon
909 bl x264_sa8d_8x8_neon
925 .macro HADAMARD4_V r1, r2, r3, r4, t1, t2, t3, t4
926 SUMSUB_ABCD \t1, \t2, \t3, \t4, \r1, \r2, \r3, \r4
927 SUMSUB_ABCD \r1, \r3, \r2, \r4, \t1, \t3, \t2, \t4
930 function x264_sa8d_8x8_neon
931 LOAD_DIFF_8x4 q8, q9, q10, q11
932 vld1.64 {d7}, [r2], r3
933 SUMSUB_AB q0, q1, q8, q9
934 vld1.64 {d6}, [r0,:64], r1
936 vld1.64 {d17}, [r2], r3
937 SUMSUB_AB q2, q3, q10, q11
938 vld1.64 {d16}, [r0,:64], r1
939 vsubl.u8 q13, d16, d17
940 vld1.64 {d19}, [r2], r3
941 SUMSUB_AB q8, q10, q0, q2
942 vld1.64 {d18}, [r0,:64], r1
943 vsubl.u8 q14, d18, d19
944 vld1.64 {d1}, [r2], r3
945 SUMSUB_AB q9, q11, q1, q3
946 vld1.64 {d0}, [r0,:64], r1
949 HADAMARD4_V q12, q13, q14, q15, q0, q1, q2, q3
950 SUMSUB_ABCD q0, q8, q1, q9, q8, q12, q9, q13
951 SUMSUB_AB q2, q10, q10, q14
953 SUMSUB_AB q3, q11, q11, q15
955 SUMSUB_AB q12, q13, q8, q9
957 SUMSUB_AB q8, q9, q0, q1
959 SUMSUB_AB q14, q15, q10, q11
964 SUMSUB_AB q0, q2, q12, q14
966 SUMSUB_AB q1, q3, q13, q15
968 SUMSUB_AB q12, q14, q8, q10
969 SUMSUB_AB q13, q15, q9, q11
981 vmax.s16 q10, q2, q14
982 vmax.s16 q11, q3, q15
984 vadd.i16 q9, q10, q11
989 .macro HADAMARD_AC w h
990 function x264_pixel_hadamard_ac_\w\()x\h\()_neon
994 // note: this assumes mask_ac8 is after mask_ac4 (so don't move it)
995 vld1.64 {d12-d15}, [ip,:128]
999 bl x264_hadamard_ac_8x8_neon
1001 bl x264_hadamard_ac_8x8_neon
1004 sub r0, r0, r1, lsl #3
1006 bl x264_hadamard_ac_8x8_neon
1009 sub r0, r0, r1, lsl #4
1010 bl x264_hadamard_ac_8x8_neon
1014 vadd.s32 d10, d10, d11
1015 vpadd.s32 d0, d8, d10
1030 // q4: satd q5: sa8d q6: mask_ac4 q7: mask_ac8
1031 function x264_hadamard_ac_8x8_neon
1032 vld1.64 {d2}, [r0,:64], r1
1033 vld1.64 {d3}, [r0,:64], r1
1035 vld1.64 {d6}, [r0,:64], r1
1037 vld1.64 {d7}, [r0,:64], r1
1039 vld1.64 {d18}, [r0,:64], r1
1041 vld1.64 {d19}, [r0,:64], r1
1042 vaddl.u8 q8, d18, d19
1043 vld1.64 {d22}, [r0,:64], r1
1044 vsubl.u8 q9, d18, d19
1045 vld1.64 {d23}, [r0,:64], r1
1047 SUMSUB_ABCD q12, q14, q13, q15, q0, q2, q1, q3
1048 vaddl.u8 q10, d22, d23
1049 vsubl.u8 q11, d22, d23
1051 SUMSUB_ABCD q0, q2, q1, q3, q8, q10, q9, q11
1054 SUMSUB_AB q8, q9, q12, q13
1056 SUMSUB_AB q10, q11, q14, q15
1058 SUMSUB_AB q12, q13, q0, q1
1060 SUMSUB_AB q14, q15, q2, q3
1062 SUMSUB_AB q0, q2, q8, q10
1064 SUMSUB_AB q1, q3, q9, q11
1066 SUMSUB_ABCD q8, q10, q9, q11, q12, q14, q13, q15
1071 vadd.s16 q12, q12, q13
1073 vand.s16 q12, q12, q6
1075 vadd.s16 q12, q12, q15
1077 vadd.s16 q12, q12, q14
1079 vadd.s16 q12, q12, q13
1081 vadd.s16 q12, q12, q15
1082 vsub.s16 q15, q11, q3
1083 vadd.s16 q12, q12, q14
1084 vadd.s16 q14, q11, q3
1085 vadd.s16 q12, q12, q13
1086 vsub.s16 q13, q10, q2
1087 vadd.s16 q2, q10, q2
1090 SUMSUB_AB q10, q11, q9, q1
1091 SUMSUB_AB q9, q8, q0, q8
1101 vmax.s16 q3, q14, q15
1102 vmax.s16 q2, q2, q13
1103 vmax.s16 q1, q10, q11
1105 SUMSUB_AB q14, q15, q9, q8
1113 vadd.s16 q2, q2, q15
1114 vadd.s16 q2, q2, q14
1120 .macro SSIM_ITER n ssa s12 ssb lastssa lasts12 lastssb da db dnext
1121 vld1.64 {\db}, [r2], r3
1122 vmull.u8 \ssa, \da, \da
1123 vmull.u8 \s12, \da, \db
1125 vpaddl.u16 q2, \lastssa
1126 vpaddl.u16 q3, \lasts12
1127 vaddl.u8 q0, d0, \da
1129 vpadal.u16 q2, \lastssa
1130 vpadal.u16 q3, \lasts12
1131 vaddw.u8 q0, q0, \da
1133 vpadal.u16 q2, \lastssb
1135 vld1.64 {\dnext}, [r0], r1
1138 vaddl.u8 q1, d2, \db
1140 vaddw.u8 q1, q1, \db
1142 vmull.u8 \ssb, \db, \db
1145 function x264_pixel_ssim_4x4x2_core_neon
1147 vld1.64 {d0}, [r0], r1
1148 vld1.64 {d2}, [r2], r3
1151 vld1.64 {d28}, [r0], r1
1152 vmull.u8 q15, d2, d2
1154 SSIM_ITER 1, q8, q9, q14, q2, q3, q15, d28, d29, d26
1155 SSIM_ITER 2, q10,q11,q13, q8, q9, q14, d26, d27, d28
1156 SSIM_ITER 3, q8, q9, q15, q10,q11,q13, d28, d29
1164 vpadd.u32 d0, d0, d1
1165 vpadd.u32 d1, d2, d3
1166 vpadd.u32 d2, d4, d5
1167 vpadd.u32 d3, d6, d7
1169 vst4.32 {d0-d3}, [ip]
1173 // FIXME: see about doing 16x16 -> 32 bit multiplies for s1/s2
1174 function x264_pixel_ssim_end4_neon
1175 vld1.32 {d16-d19}, [r0,:128]!
1176 vld1.32 {d20-d23}, [r1,:128]!
1177 vadd.s32 q0, q8, q10
1178 vadd.s32 q1, q9, q11
1179 vld1.32 {d24-d27}, [r0,:128]!
1181 vld1.32 {d28-d31}, [r1,:128]!
1182 vadd.s32 q2, q12, q14
1183 vadd.s32 q3, q13, q15
1184 vld1.32 {d16-d17}, [r0,:128]
1186 vld1.32 {d18-d19}, [r1,:128]
1196 // s1=q0, s2=q1, ss=q2, s12=q3
1197 vmul.s32 q8, q0, q1 // s1*s2
1199 vmla.s32 q0, q1, q1 // s1*s1 + s2*s2
1205 mov r3, #416 // ssim_c1 = .01*.01*255*255*64
1206 movconst ip, 235963 // ssim_c2 = .03*.03*255*255*64*63
1210 vsub.s32 q2, q2, q0 // vars
1211 vsub.s32 q3, q3, q1 // covar*2
1212 vadd.s32 q0, q0, q14
1213 vadd.s32 q2, q2, q15
1214 vadd.s32 q1, q1, q14
1215 vadd.s32 q3, q3, q15
1234 sub r3, r3, r2, lsl #2
1235 vld1.64 {d6-d7}, [r3]
1239 vpadd.f32 d0, d0, d0