Bumping gaia.json for 2 gaia revision(s) a=gaia-bump
[gecko.git] / media / libpng / arm / filter_neon.S
blob42d5ee3e6d936022532462a2f70d11e4acf3eb9e
2 /* filter_neon.S - NEON optimised filter functions
3  *
4  * Copyright (c) 2013 Glenn Randers-Pehrson
5  * Written by Mans Rullgard, 2011.
6  * Last changed in libpng 1.6.8 [December 19, 2013]
7  *
8  * This code is released under the libpng license.
9  * For conditions of distribution and use, see the disclaimer
10  * and license in png.h
11  */
13 /* These are required because Mozilla's moz.build system doesn't pass
14  * -DDefined macros to the assembler.
15  */
16 #define PNG_READ_SUPPORTED
17 #define MOZ_PNG_HAVE_ARM_NEON
19 /* This is required to get the symbol renames, which are #defines, and also
20  * includes the definition (or not) of PNG_ARM_NEON_OPT and
21  * PNG_ARM_NEON_IMPLEMENTATION.
22  */
23 #define PNG_VERSION_INFO_ONLY
24 #include "../pngpriv.h"
26 #if defined(__linux__) && defined(__ELF__)
27 .section .note.GNU-stack,"",%progbits /* mark stack as non-executable */
28 #endif
30 /* Assembler NEON support - only works for 32-bit ARM (i.e. it does not work for
31  * ARM64).  The code in arm/filter_neon_intrinsics.c supports ARM64, however it
32  * only works if -mfpu=neon is specified on the GCC command line.  See pngpriv.h
33  * for the logic which sets PNG_USE_ARM_NEON_ASM:
34  */
35 #if PNG_ARM_NEON_IMPLEMENTATION == 2 /* hand-coded assembler */
37 #ifdef PNG_READ_SUPPORTED
38 #if PNG_ARM_NEON_OPT > 0
40 #ifdef __ELF__
41 #   define ELF
42 #else
43 #   define ELF @
44 #endif
46         .arch armv7-a
47         .fpu  neon
49 .macro  func    name, export=0
50     .macro endfunc
51 ELF     .size   \name, . - \name
52         .endfunc
53         .purgem endfunc
54     .endm
55         .text
57         /* Explicitly specifying alignment here because some versions of
58            gas don't align code correctly. See
59            http://lists.gnu.org/archive/html/bug-binutils/2011-06/msg00199.html
60            and https://bugzilla.mozilla.org/show_bug.cgi?id=920992
61          */
62         .align 2
64     .if \export
65         .global \name
66     .endif
67 ELF     .type   \name, STT_FUNC
68         .func   \name
69 \name:
70 .endm
72 func    png_read_filter_row_sub4_neon, export=1
73         ldr             r3,  [r0, #4]           @ rowbytes
74         vmov.i8         d3,  #0
76         vld4.32         {d4[],d5[],d6[],d7[]},    [r1,:128]
77         vadd.u8         d0,  d3,  d4
78         vadd.u8         d1,  d0,  d5
79         vadd.u8         d2,  d1,  d6
80         vadd.u8         d3,  d2,  d7
81         vst4.32         {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
82         subs            r3,  r3,  #16
83         bgt             1b
85         bx              lr
86 endfunc
88 func    png_read_filter_row_sub3_neon, export=1
89         ldr             r3,  [r0, #4]           @ rowbytes
90         vmov.i8         d3,  #0
91         mov             r0,  r1
92         mov             r2,  #3
93         mov             r12, #12
94         vld1.8          {q11},    [r0], r12
96         vext.8          d5,  d22, d23, #3
97         vadd.u8         d0,  d3,  d22
98         vext.8          d6,  d22, d23, #6
99         vadd.u8         d1,  d0,  d5
100         vext.8          d7,  d23, d23, #1
101         vld1.8          {q11},    [r0], r12
102         vst1.32         {d0[0]},  [r1,:32], r2
103         vadd.u8         d2,  d1,  d6
104         vst1.32         {d1[0]},  [r1], r2
105         vadd.u8         d3,  d2,  d7
106         vst1.32         {d2[0]},  [r1], r2
107         vst1.32         {d3[0]},  [r1], r2
108         subs            r3,  r3,  #12
109         bgt             1b
111         bx              lr
112 endfunc
114 func    png_read_filter_row_up_neon, export=1
115         ldr             r3,  [r0, #4]           @ rowbytes
117         vld1.8          {q0}, [r1,:128]
118         vld1.8          {q1}, [r2,:128]!
119         vadd.u8         q0,  q0,  q1
120         vst1.8          {q0}, [r1,:128]!
121         subs            r3,  r3,  #16
122         bgt             1b
124         bx              lr
125 endfunc
127 func    png_read_filter_row_avg4_neon, export=1
128         ldr             r12, [r0, #4]           @ rowbytes
129         vmov.i8         d3,  #0
131         vld4.32         {d4[],d5[],d6[],d7[]},    [r1,:128]
132         vld4.32         {d16[],d17[],d18[],d19[]},[r2,:128]!
133         vhadd.u8        d0,  d3,  d16
134         vadd.u8         d0,  d0,  d4
135         vhadd.u8        d1,  d0,  d17
136         vadd.u8         d1,  d1,  d5
137         vhadd.u8        d2,  d1,  d18
138         vadd.u8         d2,  d2,  d6
139         vhadd.u8        d3,  d2,  d19
140         vadd.u8         d3,  d3,  d7
141         vst4.32         {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
142         subs            r12, r12, #16
143         bgt             1b
145         bx              lr
146 endfunc
148 func    png_read_filter_row_avg3_neon, export=1
149         push            {r4,lr}
150         ldr             r12, [r0, #4]           @ rowbytes
151         vmov.i8         d3,  #0
152         mov             r0,  r1
153         mov             r4,  #3
154         mov             lr,  #12
155         vld1.8          {q11},    [r0], lr
157         vld1.8          {q10},    [r2], lr
158         vext.8          d5,  d22, d23, #3
159         vhadd.u8        d0,  d3,  d20
160         vext.8          d17, d20, d21, #3
161         vadd.u8         d0,  d0,  d22
162         vext.8          d6,  d22, d23, #6
163         vhadd.u8        d1,  d0,  d17
164         vext.8          d18, d20, d21, #6
165         vadd.u8         d1,  d1,  d5
166         vext.8          d7,  d23, d23, #1
167         vld1.8          {q11},    [r0], lr
168         vst1.32         {d0[0]},  [r1,:32], r4
169         vhadd.u8        d2,  d1,  d18
170         vst1.32         {d1[0]},  [r1], r4
171         vext.8          d19, d21, d21, #1
172         vadd.u8         d2,  d2,  d6
173         vhadd.u8        d3,  d2,  d19
174         vst1.32         {d2[0]},  [r1], r4
175         vadd.u8         d3,  d3,  d7
176         vst1.32         {d3[0]},  [r1], r4
177         subs            r12, r12, #12
178         bgt             1b
180         pop             {r4,pc}
181 endfunc
183 .macro  paeth           rx,  ra,  rb,  rc
184         vaddl.u8        q12, \ra, \rb           @ a + b
185         vaddl.u8        q15, \rc, \rc           @ 2*c
186         vabdl.u8        q13, \rb, \rc           @ pa
187         vabdl.u8        q14, \ra, \rc           @ pb
188         vabd.u16        q15, q12, q15           @ pc
189         vcle.u16        q12, q13, q14           @ pa <= pb
190         vcle.u16        q13, q13, q15           @ pa <= pc
191         vcle.u16        q14, q14, q15           @ pb <= pc
192         vand            q12, q12, q13           @ pa <= pb && pa <= pc
193         vmovn.u16       d28, q14
194         vmovn.u16       \rx, q12
195         vbsl            d28, \rb, \rc
196         vbsl            \rx, \ra, d28
197 .endm
199 func    png_read_filter_row_paeth4_neon, export=1
200         ldr             r12, [r0, #4]           @ rowbytes
201         vmov.i8         d3,  #0
202         vmov.i8         d20, #0
204         vld4.32         {d4[],d5[],d6[],d7[]},    [r1,:128]
205         vld4.32         {d16[],d17[],d18[],d19[]},[r2,:128]!
206         paeth           d0,  d3,  d16, d20
207         vadd.u8         d0,  d0,  d4
208         paeth           d1,  d0,  d17, d16
209         vadd.u8         d1,  d1,  d5
210         paeth           d2,  d1,  d18, d17
211         vadd.u8         d2,  d2,  d6
212         paeth           d3,  d2,  d19, d18
213         vmov            d20, d19
214         vadd.u8         d3,  d3,  d7
215         vst4.32         {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
216         subs            r12, r12, #16
217         bgt             1b
219         bx              lr
220 endfunc
222 func    png_read_filter_row_paeth3_neon, export=1
223         push            {r4,lr}
224         ldr             r12, [r0, #4]           @ rowbytes
225         vmov.i8         d3,  #0
226         vmov.i8         d4,  #0
227         mov             r0,  r1
228         mov             r4,  #3
229         mov             lr,  #12
230         vld1.8          {q11},    [r0], lr
232         vld1.8          {q10},    [r2], lr
233         paeth           d0,  d3,  d20, d4
234         vext.8          d5,  d22, d23, #3
235         vadd.u8         d0,  d0,  d22
236         vext.8          d17, d20, d21, #3
237         paeth           d1,  d0,  d17, d20
238         vst1.32         {d0[0]},  [r1,:32], r4
239         vext.8          d6,  d22, d23, #6
240         vadd.u8         d1,  d1,  d5
241         vext.8          d18, d20, d21, #6
242         paeth           d2,  d1,  d18, d17
243         vext.8          d7,  d23, d23, #1
244         vld1.8          {q11},    [r0], lr
245         vst1.32         {d1[0]},  [r1], r4
246         vadd.u8         d2,  d2,  d6
247         vext.8          d19, d21, d21, #1
248         paeth           d3,  d2,  d19, d18
249         vst1.32         {d2[0]},  [r1], r4
250         vmov            d4,  d19
251         vadd.u8         d3,  d3,  d7
252         vst1.32         {d3[0]},  [r1], r4
253         subs            r12, r12, #12
254         bgt             1b
256         pop             {r4,pc}
257 endfunc
258 #endif /* PNG_ARM_NEON_OPT > 0 */
259 #endif /* PNG_READ_SUPPORTED */
260 #endif /* PNG_ARM_NEON_IMPLEMENTATION == 2 (assembler) */