]> git.saurik.com Git - wxWidgets.git/blob - src/png/arm/filter_neon.S
new file added
[wxWidgets.git] / src / png / arm / filter_neon.S
1
2 /* filter_neon.S - NEON optimised filter functions
3 *
4 * Copyright (c) 2011 Glenn Randers-Pehrson
5 * Written by Mans Rullgard, 2011.
6 *
7 * This code is released under the libpng license.
8 * For conditions of distribution and use, see the disclaimer
9 * and license in png.h
10 */
11
12 #if defined(__linux__) && defined(__ELF__)
13 .section .note.GNU-stack,"",%progbits /* mark stack as non-executable */
14 #endif
15
16 #ifdef __ELF__
17 # define ELF
18 #else
19 # define ELF @
20 #endif
21
22 .arch armv7-a
23 .fpu neon
24
25 .macro func name, export=0
26 .macro endfunc
27 ELF .size \name, . - \name
28 .endfunc
29 .purgem endfunc
30 .endm
31 .text
32 .if \export
33 .global \name
34 .endif
35 ELF .type \name, STT_FUNC
36 .func \name
37 \name:
38 .endm
39
40 func png_read_filter_row_sub4_neon, export=1
41 ldr r3, [r0, #4] @ rowbytes
42 vmov.i8 d3, #0
43 1:
44 vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128]
45 vadd.u8 d0, d3, d4
46 vadd.u8 d1, d0, d5
47 vadd.u8 d2, d1, d6
48 vadd.u8 d3, d2, d7
49 vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
50 subs r3, r3, #16
51 bgt 1b
52
53 bx lr
54 endfunc
55
56 func png_read_filter_row_sub3_neon, export=1
57 ldr r3, [r0, #4] @ rowbytes
58 vmov.i8 d3, #0
59 mov r0, r1
60 mov r2, #3
61 mov r12, #12
62 vld1.8 {q11}, [r0], r12
63 1:
64 vext.8 d5, d22, d23, #3
65 vadd.u8 d0, d3, d22
66 vext.8 d6, d22, d23, #6
67 vadd.u8 d1, d0, d5
68 vext.8 d7, d23, d23, #1
69 vld1.8 {q11}, [r0], r12
70 vst1.32 {d0[0]}, [r1,:32], r2
71 vadd.u8 d2, d1, d6
72 vst1.32 {d1[0]}, [r1], r2
73 vadd.u8 d3, d2, d7
74 vst1.32 {d2[0]}, [r1], r2
75 vst1.32 {d3[0]}, [r1], r2
76 subs r3, r3, #12
77 bgt 1b
78
79 bx lr
80 endfunc
81
82 func png_read_filter_row_up_neon, export=1
83 ldr r3, [r0, #4] @ rowbytes
84 1:
85 vld1.8 {q0}, [r1,:128]
86 vld1.8 {q1}, [r2,:128]!
87 vadd.u8 q0, q0, q1
88 vst1.8 {q0}, [r1,:128]!
89 subs r3, r3, #16
90 bgt 1b
91
92 bx lr
93 endfunc
94
95 func png_read_filter_row_avg4_neon, export=1
96 ldr r12, [r0, #4] @ rowbytes
97 vmov.i8 d3, #0
98 1:
99 vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128]
100 vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]!
101 vhadd.u8 d0, d3, d16
102 vadd.u8 d0, d0, d4
103 vhadd.u8 d1, d0, d17
104 vadd.u8 d1, d1, d5
105 vhadd.u8 d2, d1, d18
106 vadd.u8 d2, d2, d6
107 vhadd.u8 d3, d2, d19
108 vadd.u8 d3, d3, d7
109 vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
110 subs r12, r12, #16
111 bgt 1b
112
113 bx lr
114 endfunc
115
116 func png_read_filter_row_avg3_neon, export=1
117 push {r4,lr}
118 ldr r12, [r0, #4] @ rowbytes
119 vmov.i8 d3, #0
120 mov r0, r1
121 mov r4, #3
122 mov lr, #12
123 vld1.8 {q11}, [r0], lr
124 1:
125 vld1.8 {q10}, [r2], lr
126 vext.8 d5, d22, d23, #3
127 vhadd.u8 d0, d3, d20
128 vext.8 d17, d20, d21, #3
129 vadd.u8 d0, d0, d22
130 vext.8 d6, d22, d23, #6
131 vhadd.u8 d1, d0, d17
132 vext.8 d18, d20, d21, #6
133 vadd.u8 d1, d1, d5
134 vext.8 d7, d23, d23, #1
135 vld1.8 {q11}, [r0], lr
136 vst1.32 {d0[0]}, [r1,:32], r4
137 vhadd.u8 d2, d1, d18
138 vst1.32 {d1[0]}, [r1], r4
139 vext.8 d19, d21, d21, #1
140 vadd.u8 d2, d2, d6
141 vhadd.u8 d3, d2, d19
142 vst1.32 {d2[0]}, [r1], r4
143 vadd.u8 d3, d3, d7
144 vst1.32 {d3[0]}, [r1], r4
145 subs r12, r12, #12
146 bgt 1b
147
148 pop {r4,pc}
149 endfunc
150
151 .macro paeth rx, ra, rb, rc
152 vaddl.u8 q12, \ra, \rb @ a + b
153 vaddl.u8 q15, \rc, \rc @ 2*c
154 vabdl.u8 q13, \rb, \rc @ pa
155 vabdl.u8 q14, \ra, \rc @ pb
156 vabd.u16 q15, q12, q15 @ pc
157 vcle.u16 q12, q13, q14 @ pa <= pb
158 vcle.u16 q13, q13, q15 @ pa <= pc
159 vcle.u16 q14, q14, q15 @ pb <= pc
160 vand q12, q12, q13 @ pa <= pb && pa <= pc
161 vmovn.u16 d28, q14
162 vmovn.u16 \rx, q12
163 vbsl d28, \rb, \rc
164 vbsl \rx, \ra, d28
165 .endm
166
167 func png_read_filter_row_paeth4_neon, export=1
168 ldr r12, [r0, #4] @ rowbytes
169 vmov.i8 d3, #0
170 vmov.i8 d20, #0
171 1:
172 vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128]
173 vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]!
174 paeth d0, d3, d16, d20
175 vadd.u8 d0, d0, d4
176 paeth d1, d0, d17, d16
177 vadd.u8 d1, d1, d5
178 paeth d2, d1, d18, d17
179 vadd.u8 d2, d2, d6
180 paeth d3, d2, d19, d18
181 vmov d20, d19
182 vadd.u8 d3, d3, d7
183 vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
184 subs r12, r12, #16
185 bgt 1b
186
187 bx lr
188 endfunc
189
190 func png_read_filter_row_paeth3_neon, export=1
191 push {r4,lr}
192 ldr r12, [r0, #4] @ rowbytes
193 vmov.i8 d3, #0
194 vmov.i8 d4, #0
195 mov r0, r1
196 mov r4, #3
197 mov lr, #12
198 vld1.8 {q11}, [r0], lr
199 1:
200 vld1.8 {q10}, [r2], lr
201 paeth d0, d3, d20, d4
202 vext.8 d5, d22, d23, #3
203 vadd.u8 d0, d0, d22
204 vext.8 d17, d20, d21, #3
205 paeth d1, d0, d17, d20
206 vst1.32 {d0[0]}, [r1,:32], r4
207 vext.8 d6, d22, d23, #6
208 vadd.u8 d1, d1, d5
209 vext.8 d18, d20, d21, #6
210 paeth d2, d1, d18, d17
211 vext.8 d7, d23, d23, #1
212 vld1.8 {q11}, [r0], lr
213 vst1.32 {d1[0]}, [r1], r4
214 vadd.u8 d2, d2, d6
215 vext.8 d19, d21, d21, #1
216 paeth d3, d2, d19, d18
217 vst1.32 {d2[0]}, [r1], r4
218 vmov d4, d19
219 vadd.u8 d3, d3, d7
220 vst1.32 {d3[0]}, [r1], r4
221 subs r12, r12, #12
222 bgt 1b
223
224 pop {r4,pc}
225 endfunc