]>
Commit | Line | Data |
---|---|---|
72281370 DS |
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 |