1 /*****************************************************************************
2 * pixel.S: arm pixel metrics
3 *****************************************************************************
4 * Copyright (C) 2009-2015 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 *****************************************************************************/
40 .short 0, -1, -1, -1, 0, -1, -1, -1
42 .short 0, -1, -1, -1, -1, -1, -1, -1
47 function x264_pixel_sad_4x\h\()_armv6
71 .macro SAD_START_4 align:vararg
72 vld1.32 {d1[]}, [r2\align], r3
73 vld1.32 {d0[]}, [r0,:32], r1
77 .macro SAD_4 align:vararg
78 vld1.32 {d1[]}, [r2\align], r3
79 vld1.32 {d0[]}, [r0,:32], r1
83 .macro SAD_START_8 align:vararg
84 vld1.64 {d1}, [r2\align], r3
85 vld1.64 {d0}, [r0,:64], r1
89 .macro SAD_8 align:vararg
90 vld1.64 {d1}, [r2\align], r3
91 vld1.64 {d0}, [r0,:64], r1
95 .macro SAD_START_16 align:vararg
96 vld1.64 {d2-d3}, [r2\align], r3
97 vld1.64 {d0-d1}, [r0,:128], r1
99 vld1.64 {d6-d7}, [r2\align], r3
101 vld1.64 {d4-d5}, [r0,:128], r1
104 .macro SAD_16 align:vararg
106 vld1.64 {d2-d3}, [r2\align], r3
108 vld1.64 {d0-d1}, [r0,:128], r1
110 vld1.64 {d6-d7}, [r2\align], r3
112 vld1.64 {d4-d5}, [r0,:128], r1
115 .macro SAD_FUNC w, h, name, align:vararg
116 function x264_pixel_sad\name\()_\w\()x\h\()_neon
135 vadd.u16 d16, d16, d17
137 vpadd.u16 d0, d16, d16
152 SAD_FUNC 4, 4, _aligned, ,:32
153 SAD_FUNC 4, 8, _aligned, ,:32
154 SAD_FUNC 8, 4, _aligned, ,:64
155 SAD_FUNC 8, 8, _aligned, ,:64
156 SAD_FUNC 8, 16, _aligned, ,:64
157 SAD_FUNC 16, 8, _aligned, ,:128
158 SAD_FUNC 16, 16, _aligned, ,:128
160 // If dual issue is possible, use additional accumulators to avoid
161 // stalls from vadal's latency. This only matters for aligned.
162 .macro SAD_DUAL_START_8
164 vld1.64 {d3}, [r2,:64], r3
165 vld1.64 {d2}, [r0,:64], r1
169 .macro SAD_DUAL_8 align:vararg
170 vld1.64 {d1}, [r2,:64], r3
171 vld1.64 {d0}, [r0,:64], r1
173 vld1.64 {d3}, [r2,:64], r3
174 vld1.64 {d2}, [r0,:64], r1
178 .macro SAD_DUAL_START_16
181 vld1.64 {d2-d3}, [r2,:128], r3
183 vld1.64 {d0-d1}, [r0,:128], r1
188 vld1.64 {d6-d7}, [r2,:128], r3
190 vld1.64 {d4-d5}, [r0,:128], r1
192 vld1.64 {d2-d3}, [r2,:128], r3
194 vld1.64 {d0-d1}, [r0,:128], r1
197 .macro SAD_DUAL_END_16
199 vld1.64 {d6-d7}, [r2,:128], r3
201 vld1.64 {d4-d5}, [r0,:128], r1
206 .macro SAD_FUNC_DUAL w, h
207 function x264_pixel_sad_aligned_\w\()x\h\()_neon_dual
209 .rept \h / 2 - \w / 8
216 vadd.u16 q9, q10, q11
220 vadd.u16 d16, d16, d17
222 vpadd.u16 d0, d16, d16
236 .macro SAD_X_START_4 x
237 vld1.32 {d0[]}, [r0,:32], lr
238 vld1.32 {d1[]}, [r1], r6
240 vld1.32 {d2[]}, [r2], r6
242 vld1.32 {d3[]}, [r3], r6
245 vld1.32 {d4[]}, [r12], r6
251 vld1.32 {d0[]}, [r0,:32], lr
252 vld1.32 {d1[]}, [r1], r6
254 vld1.32 {d2[]}, [r2], r6
256 vld1.32 {d3[]}, [r3], r6
259 vld1.32 {d4[]}, [r12], r6
264 .macro SAD_X_START_8 x
265 vld1.64 {d0}, [r0,:64], lr
266 vld1.64 {d1}, [r1], r6
268 vld1.64 {d2}, [r2], r6
270 vld1.64 {d3}, [r3], r6
273 vld1.64 {d4}, [r12], r6
279 vld1.64 {d0}, [r0,:64], lr
280 vld1.64 {d1}, [r1], r6
282 vld1.64 {d2}, [r2], r6
284 vld1.64 {d3}, [r3], r6
287 vld1.64 {d4}, [r12], r6
292 .macro SAD_X_START_16 x
293 vld1.64 {d0-d1}, [r0,:128], lr
294 vld1.64 {d2-d3}, [r1], r6
297 vld1.64 {d4-d5}, [r2], r6
300 vld1.64 {d6-d7}, [r3], r6
304 vld1.64 {d2-d3}, [r12], r6
311 vld1.64 {d0-d1}, [r0,:128], lr
312 vld1.64 {d2-d3}, [r1], r6
315 vld1.64 {d4-d5}, [r2], r6
318 vld1.64 {d6-d7}, [r3], r6
322 vld1.64 {d2-d3}, [r12], r6
328 .macro SAD_X_FUNC x, w, h
329 function x264_pixel_sad_x\x\()_\w\()x\h\()_neon
332 ldrd r6, r7, [sp, #12]
334 ldrd r6, r7, [sp, #16]
348 vadd.u16 q10, q10, q14
350 vadd.u16 q11, q11, q15
354 vadd.u16 d16, d16, d17
355 vadd.u16 d18, d18, d19
356 vadd.u16 d20, d20, d21
358 vadd.u16 d22, d22, d23
361 vpadd.u16 d0, d16, d18
362 vpadd.u16 d1, d20, d22
367 vst1.32 {d1[0]}, [r7,:32]
369 vst1.32 {d0-d1}, [r7]
393 vld1.32 {d16[]}, [r0,:32], r1
394 vld1.32 {d17[]}, [r2,:32], r3
395 vsubl.u8 q2, d16, d17
396 vld1.32 {d16[]}, [r0,:32], r1
398 vld1.32 {d17[]}, [r2,:32], r3
402 vsubl.u8 q2, d16, d17
403 vld1.32 {d16[]}, [r0,:32], r1
405 vld1.32 {d17[]}, [r2,:32], r3
409 vsubl.u8 q2, d16, d17
414 vld1.64 {d16}, [r0,:64], r1
415 vld1.64 {d17}, [r2,:64], r3
416 vsubl.u8 q2, d16, d17
417 vld1.64 {d16}, [r0,:64], r1
420 vld1.64 {d17}, [r2,:64], r3
424 vsubl.u8 q2, d16, d17
425 vld1.64 {d16}, [r0,:64], r1
428 vld1.64 {d17}, [r2,:64], r3
432 vsubl.u8 q2, d16, d17
438 vld1.64 {d16-d17}, [r0,:128], r1
439 vld1.64 {d18-d19}, [r2,:128], r3
440 vsubl.u8 q2, d16, d18
441 vsubl.u8 q3, d17, d19
442 vld1.64 {d16-d17}, [r0,:128], r1
445 vld1.64 {d18-d19}, [r2,:128], r3
451 vsubl.u8 q2, d16, d18
452 vsubl.u8 q3, d17, d19
453 vld1.64 {d16-d17}, [r0,:128], r1
456 vld1.64 {d18-d19}, [r2,:128], r3
462 vsubl.u8 q2, d16, d18
463 vsubl.u8 q3, d17, d19
471 function x264_pixel_ssd_\w\()x\h\()_neon
493 .macro VAR_SQR_SUM qsqr_sum qsqr_last qsqr dsrc vpadal=vpadal.u16
494 vmull.u8 \qsqr, \dsrc, \dsrc
495 vaddw.u8 q0, q0, \dsrc
496 \vpadal \qsqr_sum, \qsqr_last
499 function x264_pixel_var_8x8_neon
500 vld1.64 {d16}, [r0,:64], r1
501 vmull.u8 q1, d16, d16
503 vld1.64 {d18}, [r0,:64], r1
504 vmull.u8 q2, d18, d18
507 vld1.64 {d20}, [r0,:64], r1
508 VAR_SQR_SUM q1, q1, q3, d20, vpaddl.u16
509 vld1.64 {d22}, [r0,:64], r1
510 VAR_SQR_SUM q2, q2, q8, d22, vpaddl.u16
512 vld1.64 {d24}, [r0,:64], r1
513 VAR_SQR_SUM q1, q3, q9, d24
514 vld1.64 {d26}, [r0,:64], r1
515 VAR_SQR_SUM q2, q8, q10, d26
516 vld1.64 {d24}, [r0,:64], r1
517 VAR_SQR_SUM q1, q9, q14, d24
518 vld1.64 {d26}, [r0,:64], r1
519 VAR_SQR_SUM q2, q10, q15, d26
523 function x264_pixel_var_8x16_neon
524 vld1.64 {d16}, [r0,:64], r1
525 vld1.64 {d18}, [r0,:64], r1
526 vmull.u8 q1, d16, d16
528 vld1.64 {d20}, [r0,:64], r1
529 vmull.u8 q2, d18, d18
534 vld1.64 {d22}, [r0,:64], r1
535 VAR_SQR_SUM q1, q1, q14, d20, vpaddl.u16
536 vld1.64 {d16}, [r0,:64], r1
537 VAR_SQR_SUM q2, q2, q15, d22, vpaddl.u16
540 vld1.64 {d18}, [r0,:64], r1
541 VAR_SQR_SUM q1, q14, q12, d16
542 vld1.64 {d20}, [r0,:64], r1
543 VAR_SQR_SUM q2, q15, q13, d18
544 vld1.64 {d22}, [r0,:64], r1
545 VAR_SQR_SUM q1, q12, q14, d20
547 vld1.64 {d16}, [r0,:64], r1
548 VAR_SQR_SUM q2, q13, q15, d22
551 VAR_SQR_SUM q2, q13, q15, d22
555 function x264_pixel_var_16x16_neon
556 vld1.64 {d16-d17}, [r0,:128], r1
557 vmull.u8 q12, d16, d16
559 vmull.u8 q13, d17, d17
562 vld1.64 {d18-d19}, [r0,:128], r1
563 VAR_SQR_SUM q1, q12, q14, d18, vpaddl.u16
564 VAR_SQR_SUM q2, q13, q15, d19, vpaddl.u16
569 vld1.64 {d16-d17}, [r0,:128], r1
570 VAR_SQR_SUM q1, q14, q12, d16
571 VAR_SQR_SUM q2, q15, q13, d17
573 vld1.64 {d18-d19}, [r0,:128], r1
574 VAR_SQR_SUM q1, q12, q14, d18
575 VAR_SQR_SUM q2, q13, q15, d19
579 function x264_var_end, export=0
594 .macro DIFF_SUM diff da db lastdiff
595 vld1.64 {\da}, [r0,:64], r1
596 vld1.64 {\db}, [r2,:64], r3
598 vadd.s16 q0, q0, \lastdiff
600 vsubl.u8 \diff, \da, \db
603 .macro SQR_ACC acc d0 d1 vmlal=vmlal.s16
604 \vmlal \acc, \d0, \d0
605 vmlal.s16 \acc, \d1, \d1
608 function x264_pixel_var2_8x8_neon
610 DIFF_SUM q8, d16, d17
611 SQR_ACC q1, d0, d1, vmull.s16
612 DIFF_SUM q9, d18, d19, q8
613 SQR_ACC q2, d16, d17, vmull.s16
615 DIFF_SUM q8, d16, d17, q9
617 DIFF_SUM q9, d18, d19, q8
620 DIFF_SUM q8, d16, d17, q9
633 vst1.32 {d0[1]}, [ip,:32]
635 sub r0, r1, r0, lsr #6
639 function x264_pixel_var2_8x16_neon
640 vld1.64 {d16}, [r0,:64], r1
641 vld1.64 {d17}, [r2,:64], r3
642 vld1.64 {d18}, [r0,:64], r1
643 vld1.64 {d19}, [r2,:64], r3
644 vsubl.u8 q10, d16, d17
645 vsubl.u8 q11, d18, d19
646 SQR_ACC q1, d20, d21, vmull.s16
647 vld1.64 {d16}, [r0,:64], r1
648 vadd.s16 q0, q10, q11
649 vld1.64 {d17}, [r2,:64], r3
650 SQR_ACC q2, d22, d23, vmull.s16
653 vld1.64 {d18}, [r0,:64], r1
654 vsubl.u8 q10, d16, d17
655 vld1.64 {d19}, [r2,:64], r3
658 vsubl.u8 q11, d18, d19
660 vld1.64 {d16}, [r0,:64], r1
662 vld1.64 {d17}, [r2,:64], r3
677 vst1.32 {d0[1]}, [ip,:32]
679 sub r0, r1, r0, lsr #7
683 .macro LOAD_DIFF_8x4 q0 q1 q2 q3
684 vld1.32 {d1}, [r2], r3
685 vld1.32 {d0}, [r0,:64], r1
687 vld1.32 {d3}, [r2], r3
688 vld1.32 {d2}, [r0,:64], r1
690 vld1.32 {d5}, [r2], r3
691 vld1.32 {d4}, [r0,:64], r1
693 vld1.32 {d7}, [r2], r3
694 vld1.32 {d6}, [r0,:64], r1
698 function x264_pixel_satd_4x4_neon
699 vld1.32 {d1[]}, [r2], r3
700 vld1.32 {d0[]}, [r0,:32], r1
701 vld1.32 {d3[]}, [r2], r3
702 vld1.32 {d2[]}, [r0,:32], r1
703 vld1.32 {d1[1]}, [r2], r3
704 vld1.32 {d0[1]}, [r0,:32], r1
705 vld1.32 {d3[1]}, [r2], r3
706 vld1.32 {d2[1]}, [r0,:32], r1
710 SUMSUB_AB q2, q3, q0, q1
711 SUMSUB_ABCD d0, d2, d1, d3, d4, d5, d6, d7
712 HADAMARD 1, sumsub, q2, q3, q0, q1
713 HADAMARD 2, amax, q0,, q2, q3
720 function x264_pixel_satd_4x8_neon
721 vld1.32 {d1[]}, [r2], r3
722 vld1.32 {d0[]}, [r0,:32], r1
723 vld1.32 {d3[]}, [r2], r3
724 vld1.32 {d2[]}, [r0,:32], r1
725 vld1.32 {d5[]}, [r2], r3
726 vld1.32 {d4[]}, [r0,:32], r1
727 vld1.32 {d7[]}, [r2], r3
728 vld1.32 {d6[]}, [r0,:32], r1
730 vld1.32 {d1[1]}, [r2], r3
731 vld1.32 {d0[1]}, [r0,:32], r1
733 vld1.32 {d3[1]}, [r2], r3
734 vld1.32 {d2[1]}, [r0,:32], r1
736 vld1.32 {d5[1]}, [r2], r3
737 vld1.32 {d4[1]}, [r0,:32], r1
739 vld1.32 {d7[1]}, [r2], r3
740 SUMSUB_AB q8, q9, q0, q1
741 vld1.32 {d6[1]}, [r0,:32], r1
743 SUMSUB_AB q10, q11, q2, q3
744 b x264_satd_4x8_8x4_end_neon
747 function x264_pixel_satd_8x4_neon
748 vld1.64 {d1}, [r2], r3
749 vld1.64 {d0}, [r0,:64], r1
751 vld1.64 {d3}, [r2], r3
752 vld1.64 {d2}, [r0,:64], r1
754 vld1.64 {d5}, [r2], r3
755 vld1.64 {d4}, [r0,:64], r1
757 vld1.64 {d7}, [r2], r3
758 SUMSUB_AB q8, q9, q0, q1
759 vld1.64 {d6}, [r0,:64], r1
761 SUMSUB_AB q10, q11, q2, q3
764 function x264_satd_4x8_8x4_end_neon, export=0
791 function x264_pixel_satd_8x8_neon
794 bl x264_satd_8x8_neon
795 vadd.u16 q0, q12, q13
796 vadd.u16 q1, q14, q15
805 function x264_pixel_satd_8x16_neon
809 bl x264_satd_8x8_neon
810 vadd.u16 q4, q12, q13
811 vadd.u16 q5, q14, q15
813 bl x264_satd_8x8_neon
827 function x264_satd_8x8_neon, export=0
828 LOAD_DIFF_8x4 q8, q9, q10, q11
829 vld1.64 {d7}, [r2], r3
830 SUMSUB_AB q0, q1, q8, q9
831 vld1.64 {d6}, [r0,:64], r1
833 vld1.64 {d17}, [r2], r3
834 SUMSUB_AB q2, q3, q10, q11
835 vld1.64 {d16}, [r0,:64], r1
836 vsubl.u8 q13, d16, d17
837 vld1.64 {d19}, [r2], r3
838 SUMSUB_AB q8, q10, q0, q2
839 vld1.64 {d18}, [r0,:64], r1
840 vsubl.u8 q14, d18, d19
841 vld1.64 {d1}, [r2], r3
842 SUMSUB_AB q9, q11, q1, q3
843 vld1.64 {d0}, [r0,:64], r1
847 // one vertical hadamard pass and two horizontal
848 function x264_satd_8x4v_8x8h_neon, export=0
849 SUMSUB_ABCD q0, q1, q2, q3, q12, q13, q14, q15
851 SUMSUB_AB q12, q14, q0, q2
853 SUMSUB_AB q13, q15, q1, q3
854 SUMSUB_AB q0, q1, q8, q9
856 SUMSUB_AB q2, q3, q10, q11
858 SUMSUB_AB q8, q9, q12, q13
860 SUMSUB_AB q10, q11, q14, q15
871 vmax.s16 q14, q8, q10
872 vmax.s16 q15, q9, q11
876 function x264_pixel_satd_16x8_neon
880 bl x264_satd_16x4_neon
881 vadd.u16 q4, q12, q13
882 vadd.u16 q5, q14, q15
884 bl x264_satd_16x4_neon
898 function x264_pixel_satd_16x16_neon
902 bl x264_satd_16x4_neon
903 vadd.u16 q4, q12, q13
904 vadd.u16 q5, q14, q15
906 bl x264_satd_16x4_neon
912 bl x264_satd_16x4_neon
918 bl x264_satd_16x4_neon
932 function x264_satd_16x4_neon, export=0
933 vld1.64 {d2-d3}, [r2], r3
934 vld1.64 {d0-d1}, [r0,:128], r1
936 vld1.64 {d6-d7}, [r2], r3
938 vld1.64 {d4-d5}, [r0,:128], r1
940 vld1.64 {d2-d3}, [r2], r3
942 vld1.64 {d0-d1}, [r0,:128], r1
944 vld1.64 {d6-d7}, [r2], r3
947 vld1.64 {d4-d5}, [r0,:128], r1
951 SUMSUB_AB q2, q3, q10, q11
952 SUMSUB_ABCD q8, q10, q9, q11, q0, q2, q1, q3
953 b x264_satd_8x4v_8x8h_neon
957 function x264_pixel_sa8d_8x8_neon
959 bl x264_sa8d_8x8_neon
969 function x264_pixel_sa8d_16x16_neon
972 bl x264_sa8d_8x8_neon
975 bl x264_sa8d_8x8_neon
978 sub r0, r0, r1, lsl #4
979 sub r2, r2, r3, lsl #4
982 bl x264_sa8d_8x8_neon
985 bl x264_sa8d_8x8_neon
1001 .macro HADAMARD4_V r1, r2, r3, r4, t1, t2, t3, t4
1002 SUMSUB_ABCD \t1, \t2, \t3, \t4, \r1, \r2, \r3, \r4
1003 SUMSUB_ABCD \r1, \r3, \r2, \r4, \t1, \t3, \t2, \t4
1006 function x264_sa8d_8x8_neon, export=0
1007 LOAD_DIFF_8x4 q8, q9, q10, q11
1008 vld1.64 {d7}, [r2], r3
1009 SUMSUB_AB q0, q1, q8, q9
1010 vld1.64 {d6}, [r0,:64], r1
1011 vsubl.u8 q12, d6, d7
1012 vld1.64 {d17}, [r2], r3
1013 SUMSUB_AB q2, q3, q10, q11
1014 vld1.64 {d16}, [r0,:64], r1
1015 vsubl.u8 q13, d16, d17
1016 vld1.64 {d19}, [r2], r3
1017 SUMSUB_AB q8, q10, q0, q2
1018 vld1.64 {d18}, [r0,:64], r1
1019 vsubl.u8 q14, d18, d19
1020 vld1.64 {d1}, [r2], r3
1021 SUMSUB_AB q9, q11, q1, q3
1022 vld1.64 {d0}, [r0,:64], r1
1023 vsubl.u8 q15, d0, d1
1025 HADAMARD4_V q12, q13, q14, q15, q0, q1, q2, q3
1026 SUMSUB_ABCD q0, q8, q1, q9, q8, q12, q9, q13
1027 SUMSUB_AB q2, q10, q10, q14
1029 SUMSUB_AB q3, q11, q11, q15
1031 SUMSUB_AB q12, q13, q8, q9
1033 SUMSUB_AB q8, q9, q0, q1
1035 SUMSUB_AB q14, q15, q10, q11
1036 vadd.i16 q10, q2, q3
1038 vsub.i16 q11, q2, q3
1040 SUMSUB_AB q0, q2, q12, q14
1042 SUMSUB_AB q1, q3, q13, q15
1044 SUMSUB_AB q12, q14, q8, q10
1045 SUMSUB_AB q13, q15, q9, q11
1055 vmax.s16 q8, q0, q12
1056 vmax.s16 q9, q1, q13
1057 vmax.s16 q10, q2, q14
1058 vmax.s16 q11, q3, q15
1060 vadd.i16 q9, q10, q11
1065 .macro HADAMARD_AC w h
1066 function x264_pixel_hadamard_ac_\w\()x\h\()_neon
1070 // note: this assumes mask_ac8 is after mask_ac4 (so don't move it)
1071 vld1.64 {d12-d15}, [ip,:128]
1075 bl x264_hadamard_ac_8x8_neon
1077 bl x264_hadamard_ac_8x8_neon
1080 sub r0, r0, r1, lsl #3
1082 bl x264_hadamard_ac_8x8_neon
1085 sub r0, r0, r1, lsl #4
1086 bl x264_hadamard_ac_8x8_neon
1090 vadd.s32 d10, d10, d11
1091 vpadd.s32 d0, d8, d10
1106 // q4: satd q5: sa8d q6: mask_ac4 q7: mask_ac8
1107 function x264_hadamard_ac_8x8_neon, export=0
1108 vld1.64 {d2}, [r0,:64], r1
1109 vld1.64 {d3}, [r0,:64], r1
1111 vld1.64 {d6}, [r0,:64], r1
1113 vld1.64 {d7}, [r0,:64], r1
1115 vld1.64 {d18}, [r0,:64], r1
1117 vld1.64 {d19}, [r0,:64], r1
1118 vaddl.u8 q8, d18, d19
1119 vld1.64 {d22}, [r0,:64], r1
1120 vsubl.u8 q9, d18, d19
1121 vld1.64 {d23}, [r0,:64], r1
1123 SUMSUB_ABCD q12, q14, q13, q15, q0, q2, q1, q3
1124 vaddl.u8 q10, d22, d23
1125 vsubl.u8 q11, d22, d23
1127 SUMSUB_ABCD q0, q2, q1, q3, q8, q10, q9, q11
1130 SUMSUB_AB q8, q9, q12, q13
1132 SUMSUB_AB q10, q11, q14, q15
1134 SUMSUB_AB q12, q13, q0, q1
1136 SUMSUB_AB q14, q15, q2, q3
1138 SUMSUB_AB q0, q2, q8, q10
1140 SUMSUB_AB q1, q3, q9, q11
1142 SUMSUB_ABCD q8, q10, q9, q11, q12, q14, q13, q15
1147 vadd.s16 q12, q12, q13
1149 vand.s16 q12, q12, q6
1151 vadd.s16 q12, q12, q15
1153 vadd.s16 q12, q12, q14
1155 vadd.s16 q12, q12, q13
1157 vadd.s16 q12, q12, q15
1158 vsub.s16 q15, q11, q3
1159 vadd.s16 q12, q12, q14
1160 vadd.s16 q14, q11, q3
1161 vadd.s16 q12, q12, q13
1162 vsub.s16 q13, q10, q2
1163 vadd.s16 q2, q10, q2
1166 SUMSUB_AB q10, q11, q9, q1
1167 SUMSUB_AB q9, q8, q0, q8
1177 vmax.s16 q3, q14, q15
1178 vmax.s16 q2, q2, q13
1179 vmax.s16 q1, q10, q11
1181 SUMSUB_AB q14, q15, q9, q8
1189 vadd.s16 q2, q2, q15
1190 vadd.s16 q2, q2, q14
1196 .macro SSIM_ITER n ssa s12 ssb lastssa lasts12 lastssb da db dnext
1197 vld1.64 {\db}, [r2], r3
1198 vmull.u8 \ssa, \da, \da
1199 vmull.u8 \s12, \da, \db
1201 vpaddl.u16 q2, \lastssa
1202 vpaddl.u16 q3, \lasts12
1203 vaddl.u8 q0, d0, \da
1205 vpadal.u16 q2, \lastssa
1206 vpadal.u16 q3, \lasts12
1207 vaddw.u8 q0, q0, \da
1209 vpadal.u16 q2, \lastssb
1211 vld1.64 {\dnext}, [r0], r1
1214 vaddl.u8 q1, d2, \db
1216 vaddw.u8 q1, q1, \db
1218 vmull.u8 \ssb, \db, \db
1221 function x264_pixel_ssim_4x4x2_core_neon
1223 vld1.64 {d0}, [r0], r1
1224 vld1.64 {d2}, [r2], r3
1227 vld1.64 {d28}, [r0], r1
1228 vmull.u8 q15, d2, d2
1230 SSIM_ITER 1, q8, q9, q14, q2, q3, q15, d28, d29, d26
1231 SSIM_ITER 2, q10,q11,q13, q8, q9, q14, d26, d27, d28
1232 SSIM_ITER 3, q8, q9, q15, q10,q11,q13, d28, d29
1240 vpadd.u32 d0, d0, d1
1241 vpadd.u32 d1, d2, d3
1242 vpadd.u32 d2, d4, d5
1243 vpadd.u32 d3, d6, d7
1245 vst4.32 {d0-d3}, [ip]
1249 // FIXME: see about doing 16x16 -> 32 bit multiplies for s1/s2
1250 function x264_pixel_ssim_end4_neon
1251 vld1.32 {d16-d19}, [r0,:128]!
1252 vld1.32 {d20-d23}, [r1,:128]!
1253 vadd.s32 q0, q8, q10
1254 vadd.s32 q1, q9, q11
1255 vld1.32 {d24-d27}, [r0,:128]!
1257 vld1.32 {d28-d31}, [r1,:128]!
1258 vadd.s32 q2, q12, q14
1259 vadd.s32 q3, q13, q15
1260 vld1.32 {d16-d17}, [r0,:128]
1262 vld1.32 {d18-d19}, [r1,:128]
1272 // s1=q0, s2=q1, ss=q2, s12=q3
1273 vmul.s32 q8, q0, q1 // s1*s2
1275 vmla.s32 q0, q1, q1 // s1*s1 + s2*s2
1281 mov r3, #416 // ssim_c1 = .01*.01*255*255*64
1282 movconst ip, 235963 // ssim_c2 = .03*.03*255*255*64*63
1286 vsub.s32 q2, q2, q0 // vars
1287 vsub.s32 q3, q3, q1 // covar*2
1288 vadd.s32 q0, q0, q14
1289 vadd.s32 q2, q2, q15
1290 vadd.s32 q1, q1, q14
1291 vadd.s32 q3, q3, q15
1310 sub r3, r3, r2, lsl #2
1311 vld1.64 {d6-d7}, [r3]
1315 vpadd.f32 d0, d0, d0