1 /*****************************************************************************
2 * pixel.S: arm pixel metrics
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 *****************************************************************************/
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
331 ldrd r6, r7, [sp, #12]
333 ldrd r6, r7, [sp, #16]
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_8x16_neon
523 vld1.64 {d16}, [r0,:64], r1
524 vld1.64 {d18}, [r0,:64], r1
525 vmull.u8 q1, d16, d16
527 vld1.64 {d20}, [r0,:64], r1
528 vmull.u8 q2, d18, d18
533 vld1.64 {d22}, [r0,:64], r1
534 VAR_SQR_SUM q1, q1, q14, d20, vpaddl.u16
535 vld1.64 {d16}, [r0,:64], r1
536 VAR_SQR_SUM q2, q2, q15, d22, vpaddl.u16
539 vld1.64 {d18}, [r0,:64], r1
540 VAR_SQR_SUM q1, q14, q12, d16
541 vld1.64 {d20}, [r0,:64], r1
542 VAR_SQR_SUM q2, q15, q13, d18
543 vld1.64 {d22}, [r0,:64], r1
544 VAR_SQR_SUM q1, q12, q14, d20
546 vld1.64 {d16}, [r0,:64], r1
547 VAR_SQR_SUM q2, q13, q15, d22
550 VAR_SQR_SUM q2, q13, q15, d22
554 function x264_pixel_var_16x16_neon
555 vld1.64 {d16-d17}, [r0,:128], r1
556 vmull.u8 q12, d16, d16
558 vmull.u8 q13, d17, d17
561 vld1.64 {d18-d19}, [r0,:128], r1
562 VAR_SQR_SUM q1, q12, q14, d18, vpaddl.u16
563 VAR_SQR_SUM q2, q13, q15, d19, vpaddl.u16
568 vld1.64 {d16-d17}, [r0,:128], r1
569 VAR_SQR_SUM q1, q14, q12, d16
570 VAR_SQR_SUM q2, q15, q13, d17
572 vld1.64 {d18-d19}, [r0,:128], r1
573 VAR_SQR_SUM q1, q12, q14, d18
574 VAR_SQR_SUM q2, q13, q15, d19
578 function x264_var_end
593 .macro DIFF_SUM diff da db lastdiff
594 vld1.64 {\da}, [r0,:64], r1
595 vld1.64 {\db}, [r2,:64], r3
597 vadd.s16 q0, q0, \lastdiff
599 vsubl.u8 \diff, \da, \db
602 .macro SQR_ACC acc d0 d1 vmlal=vmlal.s16
603 \vmlal \acc, \d0, \d0
604 vmlal.s16 \acc, \d1, \d1
607 function x264_pixel_var2_8x8_neon
609 DIFF_SUM q8, d16, d17
610 SQR_ACC q1, d0, d1, vmull.s16
611 DIFF_SUM q9, d18, d19, q8
612 SQR_ACC q2, d16, d17, vmull.s16
614 DIFF_SUM q8, d16, d17, q9
616 DIFF_SUM q9, d18, d19, q8
619 DIFF_SUM q8, d16, d17, q9
632 vst1.32 {d0[1]}, [ip,:32]
634 sub r0, r1, r0, lsr #6
638 function x264_pixel_var2_8x16_neon
639 vld1.64 {d16}, [r0,:64], r1
640 vld1.64 {d17}, [r2,:64], r3
641 vld1.64 {d18}, [r0,:64], r1
642 vld1.64 {d19}, [r2,:64], r3
643 vsubl.u8 q10, d16, d17
644 vsubl.u8 q11, d18, d19
645 SQR_ACC q1, d20, d21, vmull.s16
646 vld1.64 {d16}, [r0,:64], r1
647 vadd.s16 q0, q10, q11
648 vld1.64 {d17}, [r2,:64], r3
649 SQR_ACC q2, d22, d23, vmull.s16
652 vld1.64 {d18}, [r0,:64], r1
653 vsubl.u8 q10, d16, d17
654 vld1.64 {d19}, [r2,:64], r3
657 vsubl.u8 q11, d18, d19
659 vld1.64 {d16}, [r0,:64], r1
661 vld1.64 {d17}, [r2,:64], r3
676 vst1.32 {d0[1]}, [ip,:32]
678 sub r0, r1, r0, lsr #7
682 .macro LOAD_DIFF_8x4 q0 q1 q2 q3
683 vld1.32 {d1}, [r2], r3
684 vld1.32 {d0}, [r0,:64], r1
686 vld1.32 {d3}, [r2], r3
687 vld1.32 {d2}, [r0,:64], r1
689 vld1.32 {d5}, [r2], r3
690 vld1.32 {d4}, [r0,:64], r1
692 vld1.32 {d7}, [r2], r3
693 vld1.32 {d6}, [r0,:64], r1
697 function x264_pixel_satd_4x4_neon
698 vld1.32 {d1[]}, [r2], r3
699 vld1.32 {d0[]}, [r0,:32], r1
700 vld1.32 {d3[]}, [r2], r3
701 vld1.32 {d2[]}, [r0,:32], r1
702 vld1.32 {d1[1]}, [r2], r3
703 vld1.32 {d0[1]}, [r0,:32], r1
704 vld1.32 {d3[1]}, [r2], r3
705 vld1.32 {d2[1]}, [r0,:32], r1
709 SUMSUB_AB q2, q3, q0, q1
710 SUMSUB_ABCD d0, d2, d1, d3, d4, d5, d6, d7
711 HADAMARD 1, sumsub, q2, q3, q0, q1
712 HADAMARD 2, amax, q0,, q2, q3
719 function x264_pixel_satd_4x8_neon
720 vld1.32 {d1[]}, [r2], r3
721 vld1.32 {d0[]}, [r0,:32], r1
722 vld1.32 {d3[]}, [r2], r3
723 vld1.32 {d2[]}, [r0,:32], r1
724 vld1.32 {d5[]}, [r2], r3
725 vld1.32 {d4[]}, [r0,:32], r1
726 vld1.32 {d7[]}, [r2], r3
727 vld1.32 {d6[]}, [r0,:32], r1
729 vld1.32 {d1[1]}, [r2], r3
730 vld1.32 {d0[1]}, [r0,:32], r1
732 vld1.32 {d3[1]}, [r2], r3
733 vld1.32 {d2[1]}, [r0,:32], r1
735 vld1.32 {d5[1]}, [r2], r3
736 vld1.32 {d4[1]}, [r0,:32], r1
738 vld1.32 {d7[1]}, [r2], r3
739 SUMSUB_AB q8, q9, q0, q1
740 vld1.32 {d6[1]}, [r0,:32], r1
742 SUMSUB_AB q10, q11, q2, q3
743 b x264_satd_4x8_8x4_end_neon
746 function x264_pixel_satd_8x4_neon
747 vld1.64 {d1}, [r2], r3
748 vld1.64 {d0}, [r0,:64], r1
750 vld1.64 {d3}, [r2], r3
751 vld1.64 {d2}, [r0,:64], r1
753 vld1.64 {d5}, [r2], r3
754 vld1.64 {d4}, [r0,:64], r1
756 vld1.64 {d7}, [r2], r3
757 SUMSUB_AB q8, q9, q0, q1
758 vld1.64 {d6}, [r0,:64], r1
760 SUMSUB_AB q10, q11, q2, q3
763 function x264_satd_4x8_8x4_end_neon
790 function x264_pixel_satd_8x8_neon
793 bl x264_satd_8x8_neon
794 vadd.u16 q0, q12, q13
795 vadd.u16 q1, q14, q15
804 function x264_pixel_satd_8x16_neon
808 bl x264_satd_8x8_neon
809 vadd.u16 q4, q12, q13
810 vadd.u16 q5, q14, q15
812 bl x264_satd_8x8_neon
826 function x264_satd_8x8_neon
827 LOAD_DIFF_8x4 q8, q9, q10, q11
828 vld1.64 {d7}, [r2], r3
829 SUMSUB_AB q0, q1, q8, q9
830 vld1.64 {d6}, [r0,:64], r1
832 vld1.64 {d17}, [r2], r3
833 SUMSUB_AB q2, q3, q10, q11
834 vld1.64 {d16}, [r0,:64], r1
835 vsubl.u8 q13, d16, d17
836 vld1.64 {d19}, [r2], r3
837 SUMSUB_AB q8, q10, q0, q2
838 vld1.64 {d18}, [r0,:64], r1
839 vsubl.u8 q14, d18, d19
840 vld1.64 {d1}, [r2], r3
841 SUMSUB_AB q9, q11, q1, q3
842 vld1.64 {d0}, [r0,:64], r1
846 // one vertical hadamard pass and two horizontal
847 function x264_satd_8x4v_8x8h_neon
848 SUMSUB_ABCD q0, q1, q2, q3, q12, q13, q14, q15
850 SUMSUB_AB q12, q14, q0, q2
852 SUMSUB_AB q13, q15, q1, q3
853 SUMSUB_AB q0, q1, q8, q9
855 SUMSUB_AB q2, q3, q10, q11
857 SUMSUB_AB q8, q9, q12, q13
859 SUMSUB_AB q10, q11, q14, q15
870 vmax.s16 q14, q8, q10
871 vmax.s16 q15, q9, q11
875 function x264_pixel_satd_16x8_neon
879 bl x264_satd_16x4_neon
880 vadd.u16 q4, q12, q13
881 vadd.u16 q5, q14, q15
883 bl x264_satd_16x4_neon
897 function x264_pixel_satd_16x16_neon
901 bl x264_satd_16x4_neon
902 vadd.u16 q4, q12, q13
903 vadd.u16 q5, q14, q15
905 bl x264_satd_16x4_neon
911 bl x264_satd_16x4_neon
917 bl x264_satd_16x4_neon
931 function x264_satd_16x4_neon
932 vld1.64 {d2-d3}, [r2], r3
933 vld1.64 {d0-d1}, [r0,:128], r1
935 vld1.64 {d6-d7}, [r2], r3
937 vld1.64 {d4-d5}, [r0,:128], r1
939 vld1.64 {d2-d3}, [r2], r3
941 vld1.64 {d0-d1}, [r0,:128], r1
943 vld1.64 {d6-d7}, [r2], r3
946 vld1.64 {d4-d5}, [r0,:128], r1
950 SUMSUB_AB q2, q3, q10, q11
951 SUMSUB_ABCD q8, q10, q9, q11, q0, q2, q1, q3
952 b x264_satd_8x4v_8x8h_neon
956 function x264_pixel_sa8d_8x8_neon
958 bl x264_sa8d_8x8_neon
968 function x264_pixel_sa8d_16x16_neon
971 bl x264_sa8d_8x8_neon
974 bl x264_sa8d_8x8_neon
977 sub r0, r0, r1, lsl #4
978 sub r2, r2, r3, lsl #4
981 bl x264_sa8d_8x8_neon
984 bl x264_sa8d_8x8_neon
1000 .macro HADAMARD4_V r1, r2, r3, r4, t1, t2, t3, t4
1001 SUMSUB_ABCD \t1, \t2, \t3, \t4, \r1, \r2, \r3, \r4
1002 SUMSUB_ABCD \r1, \r3, \r2, \r4, \t1, \t3, \t2, \t4
1005 function x264_sa8d_8x8_neon
1006 LOAD_DIFF_8x4 q8, q9, q10, q11
1007 vld1.64 {d7}, [r2], r3
1008 SUMSUB_AB q0, q1, q8, q9
1009 vld1.64 {d6}, [r0,:64], r1
1010 vsubl.u8 q12, d6, d7
1011 vld1.64 {d17}, [r2], r3
1012 SUMSUB_AB q2, q3, q10, q11
1013 vld1.64 {d16}, [r0,:64], r1
1014 vsubl.u8 q13, d16, d17
1015 vld1.64 {d19}, [r2], r3
1016 SUMSUB_AB q8, q10, q0, q2
1017 vld1.64 {d18}, [r0,:64], r1
1018 vsubl.u8 q14, d18, d19
1019 vld1.64 {d1}, [r2], r3
1020 SUMSUB_AB q9, q11, q1, q3
1021 vld1.64 {d0}, [r0,:64], r1
1022 vsubl.u8 q15, d0, d1
1024 HADAMARD4_V q12, q13, q14, q15, q0, q1, q2, q3
1025 SUMSUB_ABCD q0, q8, q1, q9, q8, q12, q9, q13
1026 SUMSUB_AB q2, q10, q10, q14
1028 SUMSUB_AB q3, q11, q11, q15
1030 SUMSUB_AB q12, q13, q8, q9
1032 SUMSUB_AB q8, q9, q0, q1
1034 SUMSUB_AB q14, q15, q10, q11
1035 vadd.i16 q10, q2, q3
1037 vsub.i16 q11, q2, q3
1039 SUMSUB_AB q0, q2, q12, q14
1041 SUMSUB_AB q1, q3, q13, q15
1043 SUMSUB_AB q12, q14, q8, q10
1044 SUMSUB_AB q13, q15, q9, q11
1054 vmax.s16 q8, q0, q12
1055 vmax.s16 q9, q1, q13
1056 vmax.s16 q10, q2, q14
1057 vmax.s16 q11, q3, q15
1059 vadd.i16 q9, q10, q11
1064 .macro HADAMARD_AC w h
1065 function x264_pixel_hadamard_ac_\w\()x\h\()_neon
1069 // note: this assumes mask_ac8 is after mask_ac4 (so don't move it)
1070 vld1.64 {d12-d15}, [ip,:128]
1074 bl x264_hadamard_ac_8x8_neon
1076 bl x264_hadamard_ac_8x8_neon
1079 sub r0, r0, r1, lsl #3
1081 bl x264_hadamard_ac_8x8_neon
1084 sub r0, r0, r1, lsl #4
1085 bl x264_hadamard_ac_8x8_neon
1089 vadd.s32 d10, d10, d11
1090 vpadd.s32 d0, d8, d10
1105 // q4: satd q5: sa8d q6: mask_ac4 q7: mask_ac8
1106 function x264_hadamard_ac_8x8_neon
1107 vld1.64 {d2}, [r0,:64], r1
1108 vld1.64 {d3}, [r0,:64], r1
1110 vld1.64 {d6}, [r0,:64], r1
1112 vld1.64 {d7}, [r0,:64], r1
1114 vld1.64 {d18}, [r0,:64], r1
1116 vld1.64 {d19}, [r0,:64], r1
1117 vaddl.u8 q8, d18, d19
1118 vld1.64 {d22}, [r0,:64], r1
1119 vsubl.u8 q9, d18, d19
1120 vld1.64 {d23}, [r0,:64], r1
1122 SUMSUB_ABCD q12, q14, q13, q15, q0, q2, q1, q3
1123 vaddl.u8 q10, d22, d23
1124 vsubl.u8 q11, d22, d23
1126 SUMSUB_ABCD q0, q2, q1, q3, q8, q10, q9, q11
1129 SUMSUB_AB q8, q9, q12, q13
1131 SUMSUB_AB q10, q11, q14, q15
1133 SUMSUB_AB q12, q13, q0, q1
1135 SUMSUB_AB q14, q15, q2, q3
1137 SUMSUB_AB q0, q2, q8, q10
1139 SUMSUB_AB q1, q3, q9, q11
1141 SUMSUB_ABCD q8, q10, q9, q11, q12, q14, q13, q15
1146 vadd.s16 q12, q12, q13
1148 vand.s16 q12, q12, q6
1150 vadd.s16 q12, q12, q15
1152 vadd.s16 q12, q12, q14
1154 vadd.s16 q12, q12, q13
1156 vadd.s16 q12, q12, q15
1157 vsub.s16 q15, q11, q3
1158 vadd.s16 q12, q12, q14
1159 vadd.s16 q14, q11, q3
1160 vadd.s16 q12, q12, q13
1161 vsub.s16 q13, q10, q2
1162 vadd.s16 q2, q10, q2
1165 SUMSUB_AB q10, q11, q9, q1
1166 SUMSUB_AB q9, q8, q0, q8
1176 vmax.s16 q3, q14, q15
1177 vmax.s16 q2, q2, q13
1178 vmax.s16 q1, q10, q11
1180 SUMSUB_AB q14, q15, q9, q8
1188 vadd.s16 q2, q2, q15
1189 vadd.s16 q2, q2, q14
1195 .macro SSIM_ITER n ssa s12 ssb lastssa lasts12 lastssb da db dnext
1196 vld1.64 {\db}, [r2], r3
1197 vmull.u8 \ssa, \da, \da
1198 vmull.u8 \s12, \da, \db
1200 vpaddl.u16 q2, \lastssa
1201 vpaddl.u16 q3, \lasts12
1202 vaddl.u8 q0, d0, \da
1204 vpadal.u16 q2, \lastssa
1205 vpadal.u16 q3, \lasts12
1206 vaddw.u8 q0, q0, \da
1208 vpadal.u16 q2, \lastssb
1210 vld1.64 {\dnext}, [r0], r1
1213 vaddl.u8 q1, d2, \db
1215 vaddw.u8 q1, q1, \db
1217 vmull.u8 \ssb, \db, \db
1220 function x264_pixel_ssim_4x4x2_core_neon
1222 vld1.64 {d0}, [r0], r1
1223 vld1.64 {d2}, [r2], r3
1226 vld1.64 {d28}, [r0], r1
1227 vmull.u8 q15, d2, d2
1229 SSIM_ITER 1, q8, q9, q14, q2, q3, q15, d28, d29, d26
1230 SSIM_ITER 2, q10,q11,q13, q8, q9, q14, d26, d27, d28
1231 SSIM_ITER 3, q8, q9, q15, q10,q11,q13, d28, d29
1239 vpadd.u32 d0, d0, d1
1240 vpadd.u32 d1, d2, d3
1241 vpadd.u32 d2, d4, d5
1242 vpadd.u32 d3, d6, d7
1244 vst4.32 {d0-d3}, [ip]
1248 // FIXME: see about doing 16x16 -> 32 bit multiplies for s1/s2
1249 function x264_pixel_ssim_end4_neon
1250 vld1.32 {d16-d19}, [r0,:128]!
1251 vld1.32 {d20-d23}, [r1,:128]!
1252 vadd.s32 q0, q8, q10
1253 vadd.s32 q1, q9, q11
1254 vld1.32 {d24-d27}, [r0,:128]!
1256 vld1.32 {d28-d31}, [r1,:128]!
1257 vadd.s32 q2, q12, q14
1258 vadd.s32 q3, q13, q15
1259 vld1.32 {d16-d17}, [r0,:128]
1261 vld1.32 {d18-d19}, [r1,:128]
1271 // s1=q0, s2=q1, ss=q2, s12=q3
1272 vmul.s32 q8, q0, q1 // s1*s2
1274 vmla.s32 q0, q1, q1 // s1*s1 + s2*s2
1280 mov r3, #416 // ssim_c1 = .01*.01*255*255*64
1281 movconst ip, 235963 // ssim_c2 = .03*.03*255*255*64*63
1285 vsub.s32 q2, q2, q0 // vars
1286 vsub.s32 q3, q3, q1 // covar*2
1287 vadd.s32 q0, q0, q14
1288 vadd.s32 q2, q2, q15
1289 vadd.s32 q1, q1, q14
1290 vadd.s32 q3, q3, q15
1309 sub r3, r3, r2, lsl #2
1310 vld1.64 {d6-d7}, [r3]
1314 vpadd.f32 d0, d0, d0