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 *****************************************************************************/
38 .short 0, -1, -1, -1, 0, -1, -1, -1
40 .short 0, -1, -1, -1, -1, -1, -1, -1
45 function x264_pixel_sad_4x\h\()_armv6
69 .macro SAD_START_4 align:vararg
70 vld1.32 {d1[]}, [r2\align], r3
71 vld1.32 {d0[]}, [r0,:32], r1
75 .macro SAD_4 align:vararg
76 vld1.32 {d1[]}, [r2\align], r3
77 vld1.32 {d0[]}, [r0,:32], r1
81 .macro SAD_START_8 align:vararg
82 vld1.64 {d1}, [r2\align], r3
83 vld1.64 {d0}, [r0,:64], r1
87 .macro SAD_8 align:vararg
88 vld1.64 {d1}, [r2\align], r3
89 vld1.64 {d0}, [r0,:64], r1
93 .macro SAD_START_16 align:vararg
94 vld1.64 {d2-d3}, [r2\align], r3
95 vld1.64 {d0-d1}, [r0,:128], r1
97 vld1.64 {d6-d7}, [r2\align], r3
99 vld1.64 {d4-d5}, [r0,:128], r1
102 .macro SAD_16 align:vararg
104 vld1.64 {d2-d3}, [r2\align], r3
106 vld1.64 {d0-d1}, [r0,:128], r1
108 vld1.64 {d6-d7}, [r2\align], r3
110 vld1.64 {d4-d5}, [r0,:128], r1
113 .macro SAD_FUNC w, h, name, align:vararg
114 function x264_pixel_sad\name\()_\w\()x\h\()_neon
133 vadd.u16 d16, d16, d17
135 vpadd.u16 d0, d16, d16
150 SAD_FUNC 4, 4, _aligned, ,:32
151 SAD_FUNC 4, 8, _aligned, ,:32
152 SAD_FUNC 8, 4, _aligned, ,:64
153 SAD_FUNC 8, 8, _aligned, ,:64
154 SAD_FUNC 8, 16, _aligned, ,:64
155 SAD_FUNC 16, 8, _aligned, ,:128
156 SAD_FUNC 16, 16, _aligned, ,:128
158 // If dual issue is possible, use additional accumulators to avoid
159 // stalls from vadal's latency. This only matters for aligned.
160 .macro SAD_DUAL_START_8
162 vld1.64 {d3}, [r2,:64], r3
163 vld1.64 {d2}, [r0,:64], r1
167 .macro SAD_DUAL_8 align:vararg
168 vld1.64 {d1}, [r2,:64], r3
169 vld1.64 {d0}, [r0,:64], r1
171 vld1.64 {d3}, [r2,:64], r3
172 vld1.64 {d2}, [r0,:64], r1
176 .macro SAD_DUAL_START_16
179 vld1.64 {d2-d3}, [r2,:128], r3
181 vld1.64 {d0-d1}, [r0,:128], r1
186 vld1.64 {d6-d7}, [r2,:128], r3
188 vld1.64 {d4-d5}, [r0,:128], r1
190 vld1.64 {d2-d3}, [r2,:128], r3
192 vld1.64 {d0-d1}, [r0,:128], r1
195 .macro SAD_DUAL_END_16
197 vld1.64 {d6-d7}, [r2,:128], r3
199 vld1.64 {d4-d5}, [r0,:128], r1
204 .macro SAD_FUNC_DUAL w, h
205 function x264_pixel_sad_aligned_\w\()x\h\()_neon_dual
207 .rept \h / 2 - \w / 8
214 vadd.u16 q9, q10, q11
218 vadd.u16 d16, d16, d17
220 vpadd.u16 d0, d16, d16
234 .macro SAD_X_START_4 x
235 vld1.32 {d0[]}, [r0,:32], lr
236 vld1.32 {d1[]}, [r1], r6
238 vld1.32 {d2[]}, [r2], r6
240 vld1.32 {d3[]}, [r3], r6
243 vld1.32 {d4[]}, [r12], r6
249 vld1.32 {d0[]}, [r0,:32], lr
250 vld1.32 {d1[]}, [r1], r6
252 vld1.32 {d2[]}, [r2], r6
254 vld1.32 {d3[]}, [r3], r6
257 vld1.32 {d4[]}, [r12], r6
262 .macro SAD_X_START_8 x
263 vld1.64 {d0}, [r0,:64], lr
264 vld1.64 {d1}, [r1], r6
266 vld1.64 {d2}, [r2], r6
268 vld1.64 {d3}, [r3], r6
271 vld1.64 {d4}, [r12], r6
277 vld1.64 {d0}, [r0,:64], lr
278 vld1.64 {d1}, [r1], r6
280 vld1.64 {d2}, [r2], r6
282 vld1.64 {d3}, [r3], r6
285 vld1.64 {d4}, [r12], r6
290 .macro SAD_X_START_16 x
291 vld1.64 {d0-d1}, [r0,:128], lr
292 vld1.64 {d2-d3}, [r1], r6
295 vld1.64 {d4-d5}, [r2], r6
298 vld1.64 {d6-d7}, [r3], r6
302 vld1.64 {d2-d3}, [r12], r6
309 vld1.64 {d0-d1}, [r0,:128], lr
310 vld1.64 {d2-d3}, [r1], r6
313 vld1.64 {d4-d5}, [r2], r6
316 vld1.64 {d6-d7}, [r3], r6
320 vld1.64 {d2-d3}, [r12], r6
326 .macro SAD_X_FUNC x, w, h
327 function x264_pixel_sad_x\x\()_\w\()x\h\()_neon
330 ldrd r6, r7, [sp, #12]
332 ldrd r6, r7, [sp, #16]
346 vadd.u16 q10, q10, q14
348 vadd.u16 q11, q11, q15
352 vadd.u16 d16, d16, d17
353 vadd.u16 d18, d18, d19
354 vadd.u16 d20, d20, d21
356 vadd.u16 d22, d22, d23
359 vpadd.u16 d0, d16, d18
360 vpadd.u16 d1, d20, d22
365 vst1.32 {d1[0]}, [r7,:32]
367 vst1.32 {d0-d1}, [r7]
391 vld1.32 {d16[]}, [r0,:32], r1
392 vld1.32 {d17[]}, [r2,:32], r3
393 vsubl.u8 q2, d16, d17
394 vld1.32 {d16[]}, [r0,:32], r1
396 vld1.32 {d17[]}, [r2,:32], r3
400 vsubl.u8 q2, d16, d17
401 vld1.32 {d16[]}, [r0,:32], r1
403 vld1.32 {d17[]}, [r2,:32], r3
407 vsubl.u8 q2, d16, d17
412 vld1.64 {d16}, [r0,:64], r1
413 vld1.64 {d17}, [r2,:64], r3
414 vsubl.u8 q2, d16, d17
415 vld1.64 {d16}, [r0,:64], r1
418 vld1.64 {d17}, [r2,:64], r3
422 vsubl.u8 q2, d16, d17
423 vld1.64 {d16}, [r0,:64], r1
426 vld1.64 {d17}, [r2,:64], r3
430 vsubl.u8 q2, d16, d17
436 vld1.64 {d16-d17}, [r0,:128], r1
437 vld1.64 {d18-d19}, [r2,:128], r3
438 vsubl.u8 q2, d16, d18
439 vsubl.u8 q3, d17, d19
440 vld1.64 {d16-d17}, [r0,:128], r1
443 vld1.64 {d18-d19}, [r2,:128], r3
449 vsubl.u8 q2, d16, d18
450 vsubl.u8 q3, d17, d19
451 vld1.64 {d16-d17}, [r0,:128], r1
454 vld1.64 {d18-d19}, [r2,:128], r3
460 vsubl.u8 q2, d16, d18
461 vsubl.u8 q3, d17, d19
469 function x264_pixel_ssd_\w\()x\h\()_neon
491 .macro VAR_SQR_SUM qsqr_sum qsqr_last qsqr dsrc vpadal=vpadal.u16
492 vmull.u8 \qsqr, \dsrc, \dsrc
493 vaddw.u8 q0, q0, \dsrc
494 \vpadal \qsqr_sum, \qsqr_last
497 function x264_pixel_var_8x8_neon
498 vld1.64 {d16}, [r0,:64], r1
499 vmull.u8 q1, d16, d16
501 vld1.64 {d18}, [r0,:64], r1
502 vmull.u8 q2, d18, d18
505 vld1.64 {d20}, [r0,:64], r1
506 VAR_SQR_SUM q1, q1, q3, d20, vpaddl.u16
507 vld1.64 {d22}, [r0,:64], r1
508 VAR_SQR_SUM q2, q2, q8, d22, vpaddl.u16
510 vld1.64 {d24}, [r0,:64], r1
511 VAR_SQR_SUM q1, q3, q9, d24
512 vld1.64 {d26}, [r0,:64], r1
513 VAR_SQR_SUM q2, q8, q10, d26
514 vld1.64 {d24}, [r0,:64], r1
515 VAR_SQR_SUM q1, q9, q14, d24
516 vld1.64 {d26}, [r0,:64], r1
517 VAR_SQR_SUM q2, q10, q15, d26
521 function x264_pixel_var_8x16_neon
522 vld1.64 {d16}, [r0,:64], r1
523 vld1.64 {d18}, [r0,:64], r1
524 vmull.u8 q1, d16, d16
526 vld1.64 {d20}, [r0,:64], r1
527 vmull.u8 q2, d18, d18
532 vld1.64 {d22}, [r0,:64], r1
533 VAR_SQR_SUM q1, q1, q14, d20, vpaddl.u16
534 vld1.64 {d16}, [r0,:64], r1
535 VAR_SQR_SUM q2, q2, q15, d22, vpaddl.u16
538 vld1.64 {d18}, [r0,:64], r1
539 VAR_SQR_SUM q1, q14, q12, d16
540 vld1.64 {d20}, [r0,:64], r1
541 VAR_SQR_SUM q2, q15, q13, d18
542 vld1.64 {d22}, [r0,:64], r1
543 VAR_SQR_SUM q1, q12, q14, d20
545 vld1.64 {d16}, [r0,:64], r1
546 VAR_SQR_SUM q2, q13, q15, d22
549 VAR_SQR_SUM q2, q13, q15, d22
553 function x264_pixel_var_16x16_neon
554 vld1.64 {d16-d17}, [r0,:128], r1
555 vmull.u8 q12, d16, d16
557 vmull.u8 q13, d17, d17
560 vld1.64 {d18-d19}, [r0,:128], r1
561 VAR_SQR_SUM q1, q12, q14, d18, vpaddl.u16
562 VAR_SQR_SUM q2, q13, q15, d19, vpaddl.u16
567 vld1.64 {d16-d17}, [r0,:128], r1
568 VAR_SQR_SUM q1, q14, q12, d16
569 VAR_SQR_SUM q2, q15, q13, d17
571 vld1.64 {d18-d19}, [r0,:128], r1
572 VAR_SQR_SUM q1, q12, q14, d18
573 VAR_SQR_SUM q2, q13, q15, d19
577 function x264_var_end, export=0
592 .macro DIFF_SUM diff da db lastdiff
593 vld1.64 {\da}, [r0,:64], r1
594 vld1.64 {\db}, [r2,:64], r3
596 vadd.s16 q0, q0, \lastdiff
598 vsubl.u8 \diff, \da, \db
601 .macro SQR_ACC acc d0 d1 vmlal=vmlal.s16
602 \vmlal \acc, \d0, \d0
603 vmlal.s16 \acc, \d1, \d1
606 function x264_pixel_var2_8x8_neon
608 DIFF_SUM q8, d16, d17
609 SQR_ACC q1, d0, d1, vmull.s16
610 DIFF_SUM q9, d18, d19, q8
611 SQR_ACC q2, d16, d17, vmull.s16
613 DIFF_SUM q8, d16, d17, q9
615 DIFF_SUM q9, d18, d19, q8
618 DIFF_SUM q8, d16, d17, q9
631 vst1.32 {d0[1]}, [ip,:32]
633 sub r0, r1, r0, lsr #6
637 function x264_pixel_var2_8x16_neon
638 vld1.64 {d16}, [r0,:64], r1
639 vld1.64 {d17}, [r2,:64], r3
640 vld1.64 {d18}, [r0,:64], r1
641 vld1.64 {d19}, [r2,:64], r3
642 vsubl.u8 q10, d16, d17
643 vsubl.u8 q11, d18, d19
644 SQR_ACC q1, d20, d21, vmull.s16
645 vld1.64 {d16}, [r0,:64], r1
646 vadd.s16 q0, q10, q11
647 vld1.64 {d17}, [r2,:64], r3
648 SQR_ACC q2, d22, d23, vmull.s16
651 vld1.64 {d18}, [r0,:64], r1
652 vsubl.u8 q10, d16, d17
653 vld1.64 {d19}, [r2,:64], r3
656 vsubl.u8 q11, d18, d19
658 vld1.64 {d16}, [r0,:64], r1
660 vld1.64 {d17}, [r2,:64], r3
675 vst1.32 {d0[1]}, [ip,:32]
677 sub r0, r1, r0, lsr #7
681 .macro LOAD_DIFF_8x4 q0 q1 q2 q3
682 vld1.32 {d1}, [r2], r3
683 vld1.32 {d0}, [r0,:64], r1
685 vld1.32 {d3}, [r2], r3
686 vld1.32 {d2}, [r0,:64], r1
688 vld1.32 {d5}, [r2], r3
689 vld1.32 {d4}, [r0,:64], r1
691 vld1.32 {d7}, [r2], r3
692 vld1.32 {d6}, [r0,:64], r1
696 function x264_pixel_satd_4x4_neon
697 vld1.32 {d1[]}, [r2], r3
698 vld1.32 {d0[]}, [r0,:32], r1
699 vld1.32 {d3[]}, [r2], r3
700 vld1.32 {d2[]}, [r0,:32], r1
701 vld1.32 {d1[1]}, [r2], r3
702 vld1.32 {d0[1]}, [r0,:32], r1
703 vld1.32 {d3[1]}, [r2], r3
704 vld1.32 {d2[1]}, [r0,:32], r1
708 SUMSUB_AB q2, q3, q0, q1
709 SUMSUB_ABCD d0, d2, d1, d3, d4, d5, d6, d7
710 HADAMARD 1, sumsub, q2, q3, q0, q1
711 HADAMARD 2, amax, q0,, q2, q3
718 function x264_pixel_satd_4x8_neon
719 vld1.32 {d1[]}, [r2], r3
720 vld1.32 {d0[]}, [r0,:32], r1
721 vld1.32 {d3[]}, [r2], r3
722 vld1.32 {d2[]}, [r0,:32], r1
723 vld1.32 {d5[]}, [r2], r3
724 vld1.32 {d4[]}, [r0,:32], r1
725 vld1.32 {d7[]}, [r2], r3
726 vld1.32 {d6[]}, [r0,:32], r1
728 vld1.32 {d1[1]}, [r2], r3
729 vld1.32 {d0[1]}, [r0,:32], r1
731 vld1.32 {d3[1]}, [r2], r3
732 vld1.32 {d2[1]}, [r0,:32], r1
734 vld1.32 {d5[1]}, [r2], r3
735 vld1.32 {d4[1]}, [r0,:32], r1
737 vld1.32 {d7[1]}, [r2], r3
738 SUMSUB_AB q8, q9, q0, q1
739 vld1.32 {d6[1]}, [r0,:32], r1
741 SUMSUB_AB q10, q11, q2, q3
742 b x264_satd_4x8_8x4_end_neon
745 function x264_pixel_satd_8x4_neon
746 vld1.64 {d1}, [r2], r3
747 vld1.64 {d0}, [r0,:64], r1
749 vld1.64 {d3}, [r2], r3
750 vld1.64 {d2}, [r0,:64], r1
752 vld1.64 {d5}, [r2], r3
753 vld1.64 {d4}, [r0,:64], r1
755 vld1.64 {d7}, [r2], r3
756 SUMSUB_AB q8, q9, q0, q1
757 vld1.64 {d6}, [r0,:64], r1
759 SUMSUB_AB q10, q11, q2, q3
762 function x264_satd_4x8_8x4_end_neon, export=0
789 function x264_pixel_satd_8x8_neon
792 bl x264_satd_8x8_neon
793 vadd.u16 q0, q12, q13
794 vadd.u16 q1, q14, q15
803 function x264_pixel_satd_8x16_neon
807 bl x264_satd_8x8_neon
808 vadd.u16 q4, q12, q13
809 vadd.u16 q5, q14, q15
811 bl x264_satd_8x8_neon
825 function x264_satd_8x8_neon, export=0
826 LOAD_DIFF_8x4 q8, q9, q10, q11
827 vld1.64 {d7}, [r2], r3
828 SUMSUB_AB q0, q1, q8, q9
829 vld1.64 {d6}, [r0,:64], r1
831 vld1.64 {d17}, [r2], r3
832 SUMSUB_AB q2, q3, q10, q11
833 vld1.64 {d16}, [r0,:64], r1
834 vsubl.u8 q13, d16, d17
835 vld1.64 {d19}, [r2], r3
836 SUMSUB_AB q8, q10, q0, q2
837 vld1.64 {d18}, [r0,:64], r1
838 vsubl.u8 q14, d18, d19
839 vld1.64 {d1}, [r2], r3
840 SUMSUB_AB q9, q11, q1, q3
841 vld1.64 {d0}, [r0,:64], r1
845 // one vertical hadamard pass and two horizontal
846 function x264_satd_8x4v_8x8h_neon, export=0
847 SUMSUB_ABCD q0, q1, q2, q3, q12, q13, q14, q15
849 SUMSUB_AB q12, q14, q0, q2
851 SUMSUB_AB q13, q15, q1, q3
852 SUMSUB_AB q0, q1, q8, q9
854 SUMSUB_AB q2, q3, q10, q11
856 SUMSUB_AB q8, q9, q12, q13
858 SUMSUB_AB q10, q11, q14, q15
869 vmax.s16 q14, q8, q10
870 vmax.s16 q15, q9, q11
874 function x264_pixel_satd_16x8_neon
878 bl x264_satd_16x4_neon
879 vadd.u16 q4, q12, q13
880 vadd.u16 q5, q14, q15
882 bl x264_satd_16x4_neon
896 function x264_pixel_satd_16x16_neon
900 bl x264_satd_16x4_neon
901 vadd.u16 q4, q12, q13
902 vadd.u16 q5, q14, q15
904 bl x264_satd_16x4_neon
910 bl x264_satd_16x4_neon
916 bl x264_satd_16x4_neon
930 function x264_satd_16x4_neon, export=0
931 vld1.64 {d2-d3}, [r2], r3
932 vld1.64 {d0-d1}, [r0,:128], r1
934 vld1.64 {d6-d7}, [r2], r3
936 vld1.64 {d4-d5}, [r0,:128], r1
938 vld1.64 {d2-d3}, [r2], r3
940 vld1.64 {d0-d1}, [r0,:128], r1
942 vld1.64 {d6-d7}, [r2], r3
945 vld1.64 {d4-d5}, [r0,:128], r1
949 SUMSUB_AB q2, q3, q10, q11
950 SUMSUB_ABCD q8, q10, q9, q11, q0, q2, q1, q3
951 b x264_satd_8x4v_8x8h_neon
955 function x264_pixel_sa8d_8x8_neon
957 bl x264_sa8d_8x8_neon
967 function x264_pixel_sa8d_16x16_neon
970 bl x264_sa8d_8x8_neon
973 bl x264_sa8d_8x8_neon
976 sub r0, r0, r1, lsl #4
977 sub r2, r2, r3, lsl #4
980 bl x264_sa8d_8x8_neon
983 bl x264_sa8d_8x8_neon
999 .macro HADAMARD4_V r1, r2, r3, r4, t1, t2, t3, t4
1000 SUMSUB_ABCD \t1, \t2, \t3, \t4, \r1, \r2, \r3, \r4
1001 SUMSUB_ABCD \r1, \r3, \r2, \r4, \t1, \t3, \t2, \t4
1004 function x264_sa8d_8x8_neon, export=0
1005 LOAD_DIFF_8x4 q8, q9, q10, q11
1006 vld1.64 {d7}, [r2], r3
1007 SUMSUB_AB q0, q1, q8, q9
1008 vld1.64 {d6}, [r0,:64], r1
1009 vsubl.u8 q12, d6, d7
1010 vld1.64 {d17}, [r2], r3
1011 SUMSUB_AB q2, q3, q10, q11
1012 vld1.64 {d16}, [r0,:64], r1
1013 vsubl.u8 q13, d16, d17
1014 vld1.64 {d19}, [r2], r3
1015 SUMSUB_AB q8, q10, q0, q2
1016 vld1.64 {d18}, [r0,:64], r1
1017 vsubl.u8 q14, d18, d19
1018 vld1.64 {d1}, [r2], r3
1019 SUMSUB_AB q9, q11, q1, q3
1020 vld1.64 {d0}, [r0,:64], r1
1021 vsubl.u8 q15, d0, d1
1023 HADAMARD4_V q12, q13, q14, q15, q0, q1, q2, q3
1024 SUMSUB_ABCD q0, q8, q1, q9, q8, q12, q9, q13
1025 SUMSUB_AB q2, q10, q10, q14
1027 SUMSUB_AB q3, q11, q11, q15
1029 SUMSUB_AB q12, q13, q8, q9
1031 SUMSUB_AB q8, q9, q0, q1
1033 SUMSUB_AB q14, q15, q10, q11
1034 vadd.i16 q10, q2, q3
1036 vsub.i16 q11, q2, q3
1038 SUMSUB_AB q0, q2, q12, q14
1040 SUMSUB_AB q1, q3, q13, q15
1042 SUMSUB_AB q12, q14, q8, q10
1043 SUMSUB_AB q13, q15, q9, q11
1053 vmax.s16 q8, q0, q12
1054 vmax.s16 q9, q1, q13
1055 vmax.s16 q10, q2, q14
1056 vmax.s16 q11, q3, q15
1058 vadd.i16 q9, q10, q11
1063 .macro HADAMARD_AC w h
1064 function x264_pixel_hadamard_ac_\w\()x\h\()_neon
1068 // note: this assumes mask_ac8 is after mask_ac4 (so don't move it)
1069 vld1.64 {d12-d15}, [ip,:128]
1073 bl x264_hadamard_ac_8x8_neon
1075 bl x264_hadamard_ac_8x8_neon
1078 sub r0, r0, r1, lsl #3
1080 bl x264_hadamard_ac_8x8_neon
1083 sub r0, r0, r1, lsl #4
1084 bl x264_hadamard_ac_8x8_neon
1088 vadd.s32 d10, d10, d11
1089 vpadd.s32 d0, d8, d10
1104 // q4: satd q5: sa8d q6: mask_ac4 q7: mask_ac8
1105 function x264_hadamard_ac_8x8_neon, export=0
1106 vld1.64 {d2}, [r0,:64], r1
1107 vld1.64 {d3}, [r0,:64], r1
1109 vld1.64 {d6}, [r0,:64], r1
1111 vld1.64 {d7}, [r0,:64], r1
1113 vld1.64 {d18}, [r0,:64], r1
1115 vld1.64 {d19}, [r0,:64], r1
1116 vaddl.u8 q8, d18, d19
1117 vld1.64 {d22}, [r0,:64], r1
1118 vsubl.u8 q9, d18, d19
1119 vld1.64 {d23}, [r0,:64], r1
1121 SUMSUB_ABCD q12, q14, q13, q15, q0, q2, q1, q3
1122 vaddl.u8 q10, d22, d23
1123 vsubl.u8 q11, d22, d23
1125 SUMSUB_ABCD q0, q2, q1, q3, q8, q10, q9, q11
1128 SUMSUB_AB q8, q9, q12, q13
1130 SUMSUB_AB q10, q11, q14, q15
1132 SUMSUB_AB q12, q13, q0, q1
1134 SUMSUB_AB q14, q15, q2, q3
1136 SUMSUB_AB q0, q2, q8, q10
1138 SUMSUB_AB q1, q3, q9, q11
1140 SUMSUB_ABCD q8, q10, q9, q11, q12, q14, q13, q15
1145 vadd.s16 q12, q12, q13
1147 vand.s16 q12, q12, q6
1149 vadd.s16 q12, q12, q15
1151 vadd.s16 q12, q12, q14
1153 vadd.s16 q12, q12, q13
1155 vadd.s16 q12, q12, q15
1156 vsub.s16 q15, q11, q3
1157 vadd.s16 q12, q12, q14
1158 vadd.s16 q14, q11, q3
1159 vadd.s16 q12, q12, q13
1160 vsub.s16 q13, q10, q2
1161 vadd.s16 q2, q10, q2
1164 SUMSUB_AB q10, q11, q9, q1
1165 SUMSUB_AB q9, q8, q0, q8
1175 vmax.s16 q3, q14, q15
1176 vmax.s16 q2, q2, q13
1177 vmax.s16 q1, q10, q11
1179 SUMSUB_AB q14, q15, q9, q8
1187 vadd.s16 q2, q2, q15
1188 vadd.s16 q2, q2, q14
1194 .macro SSIM_ITER n ssa s12 ssb lastssa lasts12 lastssb da db dnext
1195 vld1.64 {\db}, [r2], r3
1196 vmull.u8 \ssa, \da, \da
1197 vmull.u8 \s12, \da, \db
1199 vpaddl.u16 q2, \lastssa
1200 vpaddl.u16 q3, \lasts12
1201 vaddl.u8 q0, d0, \da
1203 vpadal.u16 q2, \lastssa
1204 vpadal.u16 q3, \lasts12
1205 vaddw.u8 q0, q0, \da
1207 vpadal.u16 q2, \lastssb
1209 vld1.64 {\dnext}, [r0], r1
1212 vaddl.u8 q1, d2, \db
1214 vaddw.u8 q1, q1, \db
1216 vmull.u8 \ssb, \db, \db
1219 function x264_pixel_ssim_4x4x2_core_neon
1221 vld1.64 {d0}, [r0], r1
1222 vld1.64 {d2}, [r2], r3
1225 vld1.64 {d28}, [r0], r1
1226 vmull.u8 q15, d2, d2
1228 SSIM_ITER 1, q8, q9, q14, q2, q3, q15, d28, d29, d26
1229 SSIM_ITER 2, q10,q11,q13, q8, q9, q14, d26, d27, d28
1230 SSIM_ITER 3, q8, q9, q15, q10,q11,q13, d28, d29
1238 vpadd.u32 d0, d0, d1
1239 vpadd.u32 d1, d2, d3
1240 vpadd.u32 d2, d4, d5
1241 vpadd.u32 d3, d6, d7
1243 vst4.32 {d0-d3}, [ip]
1247 // FIXME: see about doing 16x16 -> 32 bit multiplies for s1/s2
1248 function x264_pixel_ssim_end4_neon
1249 vld1.32 {d16-d19}, [r0,:128]!
1250 vld1.32 {d20-d23}, [r1,:128]!
1251 vadd.s32 q0, q8, q10
1252 vadd.s32 q1, q9, q11
1253 vld1.32 {d24-d27}, [r0,:128]!
1255 vld1.32 {d28-d31}, [r1,:128]!
1256 vadd.s32 q2, q12, q14
1257 vadd.s32 q3, q13, q15
1258 vld1.32 {d16-d17}, [r0,:128]
1260 vld1.32 {d18-d19}, [r1,:128]
1270 // s1=q0, s2=q1, ss=q2, s12=q3
1271 vmul.s32 q8, q0, q1 // s1*s2
1273 vmla.s32 q0, q1, q1 // s1*s1 + s2*s2
1279 mov r3, #416 // ssim_c1 = .01*.01*255*255*64
1280 movconst ip, 235963 // ssim_c2 = .03*.03*255*255*64*63
1284 vsub.s32 q2, q2, q0 // vars
1285 vsub.s32 q3, q3, q1 // covar*2
1286 vadd.s32 q0, q0, q14
1287 vadd.s32 q2, q2, q15
1288 vadd.s32 q1, q1, q14
1289 vadd.s32 q3, q3, q15
1308 sub r3, r3, r2, lsl #2
1309 vld1.64 {d6-d7}, [r3]
1313 vpadd.f32 d0, d0, d0