lavfi/nlmeans: add AArch64 SIMD for compute_safe_ssd_integral_image
[ffmpeg.git] / libavfilter / aarch64 / vf_nlmeans_neon.S
1 /*
2  * Copyright (c) 2018 Clément Bœsch <u pkh me>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 #include "libavutil/aarch64/asm.S"
22
23 // acc_sum_store(ABCD) = {X+A, X+A+B, X+A+B+C, X+A+B+C+D}
24 .macro acc_sum_store x, xb
25         dup             v24.4S, v24.4S[3]                               // ...X -> XXXX
26         ext             v25.16B, v26.16B, \xb, #12                      // ext(0000,ABCD,12)=0ABC
27         add             v24.4S, v24.4S, \x                              // XXXX+ABCD={X+A,X+B,X+C,X+D}
28         add             v24.4S, v24.4S, v25.4S                          // {X+A,X+B+A,X+C+B,X+D+C}       (+0ABC)
29         ext             v25.16B, v26.16B, v25.16B, #12                  // ext(0000,0ABC,12)=00AB
30         add             v24.4S, v24.4S, v25.4S                          // {X+A,X+B+A,X+C+B+A,X+D+C+B}   (+00AB)
31         ext             v25.16B, v26.16B, v25.16B, #12                  // ext(0000,00AB,12)=000A
32         add             v24.4S, v24.4S, v25.4S                          // {X+A,X+B+A,X+C+B+A,X+D+C+B+A} (+000A)
33         st1             {v24.4S}, [x0], #16                             // write 4x32-bit final values
34 .endm
35
36 function ff_compute_safe_ssd_integral_image_neon, export=1
37         movi            v26.4S, #0                                      // used as zero for the "rotations" in acc_sum_store
38         sub             x3, x3, w6, UXTW                                // s1 padding (s1_linesize - w)
39         sub             x5, x5, w6, UXTW                                // s2 padding (s2_linesize - w)
40         sub             x9, x0, x1, UXTW #2                             // dst_top
41         sub             x1, x1, w6, UXTW                                // dst padding (dst_linesize_32 - w)
42         lsl             x1, x1, #2                                      // dst padding expressed in bytes
43 1:      mov             w10, w6                                         // width copy for each line
44         sub             x0, x0, #16                                     // beginning of the dst line minus 4 sums
45         sub             x8, x9, #4                                      // dst_top-1
46         ld1             {v24.4S}, [x0], #16                             // load ...X (contextual last sums)
47 2:      ld1             {v0.16B}, [x2], #16                             // s1[x + 0..15]
48         ld1             {v1.16B}, [x4], #16                             // s2[x + 0..15]
49         ld1             {v16.4S,v17.4S}, [x8], #32                      // dst_top[x + 0..7 - 1]
50         usubl           v2.8H, v0.8B,  v1.8B                            // d[x + 0..7]  = s1[x + 0..7]  - s2[x + 0..7]
51         usubl2          v3.8H, v0.16B, v1.16B                           // d[x + 8..15] = s1[x + 8..15] - s2[x + 8..15]
52         ld1             {v18.4S,v19.4S}, [x8], #32                      // dst_top[x + 8..15 - 1]
53         smull           v4.4S, v2.4H, v2.4H                             // d[x + 0..3]^2
54         smull2          v5.4S, v2.8H, v2.8H                             // d[x + 4..7]^2
55         ld1             {v20.4S,v21.4S}, [x9], #32                      // dst_top[x + 0..7]
56         smull           v6.4S, v3.4H, v3.4H                             // d[x + 8..11]^2
57         smull2          v7.4S, v3.8H, v3.8H                             // d[x + 12..15]^2
58         ld1             {v22.4S,v23.4S}, [x9], #32                      // dst_top[x + 8..15]
59         sub             v0.4S, v20.4S, v16.4S                           // dst_top[x + 0..3] - dst_top[x + 0..3 - 1]
60         sub             v1.4S, v21.4S, v17.4S                           // dst_top[x + 4..7] - dst_top[x + 4..7 - 1]
61         add             v0.4S, v0.4S, v4.4S                             // + d[x + 0..3]^2
62         add             v1.4S, v1.4S, v5.4S                             // + d[x + 4..7]^2
63         sub             v2.4S, v22.4S, v18.4S                           // dst_top[x +  8..11] - dst_top[x +  8..11 - 1]
64         sub             v3.4S, v23.4S, v19.4S                           // dst_top[x + 12..15] - dst_top[x + 12..15 - 1]
65         add             v2.4S, v2.4S, v6.4S                             // + d[x +  8..11]^2
66         add             v3.4S, v3.4S, v7.4S                             // + d[x + 12..15]^2
67         acc_sum_store   v0.4S, v0.16B                                   // accumulate and store dst[ 0..3]
68         acc_sum_store   v1.4S, v1.16B                                   // accumulate and store dst[ 4..7]
69         acc_sum_store   v2.4S, v2.16B                                   // accumulate and store dst[ 8..11]
70         acc_sum_store   v3.4S, v3.16B                                   // accumulate and store dst[12..15]
71         subs            w10, w10, #16                                   // width dec
72         b.ne            2b                                              // loop til next line
73         add             x2, x2, x3                                      // skip to next line (s1)
74         add             x4, x4, x5                                      // skip to next line (s2)
75         add             x0, x0, x1                                      // skip to next line (dst)
76         add             x9, x9, x1                                      // skip to next line (dst_top)
77         subs            w7, w7, #1                                      // height dec
78         b.ne            1b
79         ret
80 endfunc