OSDN Git Service

40d97775d630ee91255d544044a0e17abb710979
[putex/putex.git] / src / texsourc / libpng / arm / filter_neon.S
1
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  */
12
13 /* This is required to get the symbol renames, which are #defines, and also
14  * includes the definition (or not) of PNG_ARM_NEON_OPT and
15  * PNG_ARM_NEON_IMPLEMENTATION.
16  */
17 #define PNG_VERSION_INFO_ONLY
18 #include "../pngpriv.h"
19
20 #if defined(__linux__) && defined(__ELF__)
21 .section .note.GNU-stack,"",%progbits /* mark stack as non-executable */
22 #endif
23
24 /* Assembler NEON support - only works for 32-bit ARM (i.e. it does not work for
25  * ARM64).  The code in arm/filter_neon_intrinsics.c supports ARM64, however it
26  * only works if -mfpu=neon is specified on the GCC command line.  See pngpriv.h
27  * for the logic which sets PNG_USE_ARM_NEON_ASM:
28  */
29 #if PNG_ARM_NEON_IMPLEMENTATION == 2 /* hand-coded assembler */
30
31 #ifdef PNG_READ_SUPPORTED
32 #if PNG_ARM_NEON_OPT > 0
33
34 #ifdef __ELF__
35 #   define ELF
36 #else
37 #   define ELF @
38 #endif
39
40         .arch armv7-a
41         .fpu  neon
42
43 .macro  func    name, export=0
44     .macro endfunc
45 ELF     .size   \name, . - \name
46         .endfunc
47         .purgem endfunc
48     .endm
49         .text
50     .if \export
51         .global \name
52     .endif
53 ELF     .type   \name, STT_FUNC
54         .func   \name
55 \name:
56 .endm
57
58 func    png_read_filter_row_sub4_neon, export=1
59         ldr             r3,  [r0, #4]           @ rowbytes
60         vmov.i8         d3,  #0
61 1:
62         vld4.32         {d4[],d5[],d6[],d7[]},    [r1,:128]
63         vadd.u8         d0,  d3,  d4
64         vadd.u8         d1,  d0,  d5
65         vadd.u8         d2,  d1,  d6
66         vadd.u8         d3,  d2,  d7
67         vst4.32         {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
68         subs            r3,  r3,  #16
69         bgt             1b
70
71         bx              lr
72 endfunc
73
74 func    png_read_filter_row_sub3_neon, export=1
75         ldr             r3,  [r0, #4]           @ rowbytes
76         vmov.i8         d3,  #0
77         mov             r0,  r1
78         mov             r2,  #3
79         mov             r12, #12
80         vld1.8          {q11},    [r0], r12
81 1:
82         vext.8          d5,  d22, d23, #3
83         vadd.u8         d0,  d3,  d22
84         vext.8          d6,  d22, d23, #6
85         vadd.u8         d1,  d0,  d5
86         vext.8          d7,  d23, d23, #1
87         vld1.8          {q11},    [r0], r12
88         vst1.32         {d0[0]},  [r1,:32], r2
89         vadd.u8         d2,  d1,  d6
90         vst1.32         {d1[0]},  [r1], r2
91         vadd.u8         d3,  d2,  d7
92         vst1.32         {d2[0]},  [r1], r2
93         vst1.32         {d3[0]},  [r1], r2
94         subs            r3,  r3,  #12
95         bgt             1b
96
97         bx              lr
98 endfunc
99
100 func    png_read_filter_row_up_neon, export=1
101         ldr             r3,  [r0, #4]           @ rowbytes
102 1:
103         vld1.8          {q0}, [r1,:128]
104         vld1.8          {q1}, [r2,:128]!
105         vadd.u8         q0,  q0,  q1
106         vst1.8          {q0}, [r1,:128]!
107         subs            r3,  r3,  #16
108         bgt             1b
109
110         bx              lr
111 endfunc
112
113 func    png_read_filter_row_avg4_neon, export=1
114         ldr             r12, [r0, #4]           @ rowbytes
115         vmov.i8         d3,  #0
116 1:
117         vld4.32         {d4[],d5[],d6[],d7[]},    [r1,:128]
118         vld4.32         {d16[],d17[],d18[],d19[]},[r2,:128]!
119         vhadd.u8        d0,  d3,  d16
120         vadd.u8         d0,  d0,  d4
121         vhadd.u8        d1,  d0,  d17
122         vadd.u8         d1,  d1,  d5
123         vhadd.u8        d2,  d1,  d18
124         vadd.u8         d2,  d2,  d6
125         vhadd.u8        d3,  d2,  d19
126         vadd.u8         d3,  d3,  d7
127         vst4.32         {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
128         subs            r12, r12, #16
129         bgt             1b
130
131         bx              lr
132 endfunc
133
134 func    png_read_filter_row_avg3_neon, export=1
135         push            {r4,lr}
136         ldr             r12, [r0, #4]           @ rowbytes
137         vmov.i8         d3,  #0
138         mov             r0,  r1
139         mov             r4,  #3
140         mov             lr,  #12
141         vld1.8          {q11},    [r0], lr
142 1:
143         vld1.8          {q10},    [r2], lr
144         vext.8          d5,  d22, d23, #3
145         vhadd.u8        d0,  d3,  d20
146         vext.8          d17, d20, d21, #3
147         vadd.u8         d0,  d0,  d22
148         vext.8          d6,  d22, d23, #6
149         vhadd.u8        d1,  d0,  d17
150         vext.8          d18, d20, d21, #6
151         vadd.u8         d1,  d1,  d5
152         vext.8          d7,  d23, d23, #1
153         vld1.8          {q11},    [r0], lr
154         vst1.32         {d0[0]},  [r1,:32], r4
155         vhadd.u8        d2,  d1,  d18
156         vst1.32         {d1[0]},  [r1], r4
157         vext.8          d19, d21, d21, #1
158         vadd.u8         d2,  d2,  d6
159         vhadd.u8        d3,  d2,  d19
160         vst1.32         {d2[0]},  [r1], r4
161         vadd.u8         d3,  d3,  d7
162         vst1.32         {d3[0]},  [r1], r4
163         subs            r12, r12, #12
164         bgt             1b
165
166         pop             {r4,pc}
167 endfunc
168
169 .macro  paeth           rx,  ra,  rb,  rc
170         vaddl.u8        q12, \ra, \rb           @ a + b
171         vaddl.u8        q15, \rc, \rc           @ 2*c
172         vabdl.u8        q13, \rb, \rc           @ pa
173         vabdl.u8        q14, \ra, \rc           @ pb
174         vabd.u16        q15, q12, q15           @ pc
175         vcle.u16        q12, q13, q14           @ pa <= pb
176         vcle.u16        q13, q13, q15           @ pa <= pc
177         vcle.u16        q14, q14, q15           @ pb <= pc
178         vand            q12, q12, q13           @ pa <= pb && pa <= pc
179         vmovn.u16       d28, q14
180         vmovn.u16       \rx, q12
181         vbsl            d28, \rb, \rc
182         vbsl            \rx, \ra, d28
183 .endm
184
185 func    png_read_filter_row_paeth4_neon, export=1
186         ldr             r12, [r0, #4]           @ rowbytes
187         vmov.i8         d3,  #0
188         vmov.i8         d20, #0
189 1:
190         vld4.32         {d4[],d5[],d6[],d7[]},    [r1,:128]
191         vld4.32         {d16[],d17[],d18[],d19[]},[r2,:128]!
192         paeth           d0,  d3,  d16, d20
193         vadd.u8         d0,  d0,  d4
194         paeth           d1,  d0,  d17, d16
195         vadd.u8         d1,  d1,  d5
196         paeth           d2,  d1,  d18, d17
197         vadd.u8         d2,  d2,  d6
198         paeth           d3,  d2,  d19, d18
199         vmov            d20, d19
200         vadd.u8         d3,  d3,  d7
201         vst4.32         {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
202         subs            r12, r12, #16
203         bgt             1b
204
205         bx              lr
206 endfunc
207
208 func    png_read_filter_row_paeth3_neon, export=1
209         push            {r4,lr}
210         ldr             r12, [r0, #4]           @ rowbytes
211         vmov.i8         d3,  #0
212         vmov.i8         d4,  #0
213         mov             r0,  r1
214         mov             r4,  #3
215         mov             lr,  #12
216         vld1.8          {q11},    [r0], lr
217 1:
218         vld1.8          {q10},    [r2], lr
219         paeth           d0,  d3,  d20, d4
220         vext.8          d5,  d22, d23, #3
221         vadd.u8         d0,  d0,  d22
222         vext.8          d17, d20, d21, #3
223         paeth           d1,  d0,  d17, d20
224         vst1.32         {d0[0]},  [r1,:32], r4
225         vext.8          d6,  d22, d23, #6
226         vadd.u8         d1,  d1,  d5
227         vext.8          d18, d20, d21, #6
228         paeth           d2,  d1,  d18, d17
229         vext.8          d7,  d23, d23, #1
230         vld1.8          {q11},    [r0], lr
231         vst1.32         {d1[0]},  [r1], r4
232         vadd.u8         d2,  d2,  d6
233         vext.8          d19, d21, d21, #1
234         paeth           d3,  d2,  d19, d18
235         vst1.32         {d2[0]},  [r1], r4
236         vmov            d4,  d19
237         vadd.u8         d3,  d3,  d7
238         vst1.32         {d3[0]},  [r1], r4
239         subs            r12, r12, #12
240         bgt             1b
241
242         pop             {r4,pc}
243 endfunc
244 #endif /* PNG_ARM_NEON_OPT > 0 */
245 #endif /* PNG_READ_SUPPORTED */
246 #endif /* PNG_ARM_NEON_IMPLEMENTATION == 2 (assembler) */