neon filters: support optional color space conversion
[libpicofe.git] / arm / neon_normalxx.Sinc
1 @@\r
2 @@  Copyright (C) 2012 Roman Pauer\r
3 @@\r
4 @@  Permission is hereby granted, free of charge, to any person obtaining a copy of\r
5 @@  this software and associated documentation files (the "Software"), to deal in\r
6 @@  the Software without restriction, including without limitation the rights to\r
7 @@  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\r
8 @@  of the Software, and to permit persons to whom the Software is furnished to do\r
9 @@  so, subject to the following conditions:\r
10 @@\r
11 @@  The above copyright notice and this permission notice shall be included in all\r
12 @@  copies or substantial portions of the Software.\r
13 @@\r
14 @@  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
15 @@  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
16 @@  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
17 @@  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
18 @@  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
19 @@  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
20 @@  SOFTWARE.\r
21 @@\r
22 \r
23 \r
24 #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4)\r
25 /* can't use because gas wants ',' before ':' */\r
26 #define A128\r
27 #define A256\r
28 #else\r
29 #define A128 :128\r
30 #define A256 :256\r
31 #endif\r
32 \r
33 .macro bgr1555_to_rgb565 dr0 dr1 t0 t1 t2\r
34         str r0, [sp, #-4]\r
35         mov r0, #0x07c0\r
36         vshl.u16 \t0, \dr0, #11\r
37         vshl.u16 \t1, \dr1, #11\r
38         vshl.u16 \dr0, \dr0, #1\r
39         vshl.u16 \dr1, \dr1, #1\r
40         vdup.16 \t2, r0\r
41         vsri.u16 \t0, \dr0, #11\r
42         vsri.u16 \t1, \dr1, #11\r
43         ldr r0, [sp, #-4]\r
44         vbif \dr0, \t0, \t2\r
45         vbif \dr1, \t1, \t2\r
46 .endm\r
47 \r
48 .macro _neon_normalxx_8_16_line_middle src, dst, pal, counter, reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9, dststride, dA, dB\r
49         ldr \reg1, [\src]                   @ reg1 = src[0-3]\r
50 \r
51         ldr \reg2, [\src, #4]               @ reg2 = src[4-7]\r
52 \r
53         ldr \reg3, [\src, #8]               @ reg3 = src[8-11]\r
54 \r
55         ldr \reg4, [\src, #12]              @ reg4 = src[12-15]\r
56         ubfx \reg5, \reg1, #0, #8           @ reg5 = src[0]\r
57 \r
58         ldr \reg5, [\pal, \reg5, lsl #2]    @ reg5 = pal[src[0]]\r
59         ubfx \reg6, \reg1, #8, #8           @ reg6 = src[1]\r
60 \r
61         ldr \reg6, [\pal, \reg6, lsl #2]    @ reg6 = pal[src[1]]\r
62         ubfx \reg7, \reg1, #16, #8          @ reg7 = src[2]\r
63 \r
64         ldr \reg7, [\pal, \reg7, lsl #2]    @ reg7 = pal[src[2]]\r
65         lsr     \reg1, \reg1, #24               @ reg1 = src[3]\r
66 \r
67         ldr \reg1, [\pal, \reg1, lsl #2]    @ reg1 = pal[src[3]]\r
68         ubfx \reg8, \reg2, #0, #8           @ reg8 = src[4]\r
69 \r
70         ldr \reg8, [\pal, \reg8, lsl #2]    @ reg8 = pal[src[4]]\r
71         ubfx \reg9, \reg2, #8, #8           @ reg9 = src[5]\r
72 \r
73         ldr \reg9, [\pal, \reg9, lsl #2]    @ reg9 = pal[src[5]]\r
74         bfi \reg5, \reg6, #16, #16          @ reg5 = pal[src[0]] | pal[src[1]] << 16\r
75 \r
76         bfi \reg7, \reg1, #16, #16          @ reg7 = pal[src[2]] | pal[src[3]] << 16\r
77         ubfx \reg6, \reg2, #16, #8          @ reg6 = src[6]\r
78 \r
79         vmov d16, \reg5, \reg7              @ d16 = pal[src[0-3]]\r
80         lsr     \reg2, \reg2, #24               @ reg2 = src[7]\r
81 \r
82         ldr \reg6, [\pal, \reg6, lsl #2]    @ reg6 = pal[src[6]]\r
83         bfi \reg8, \reg9, #16, #16          @ reg8 = pal[src[4]] | pal[src[5]] << 16\r
84 \r
85         ldr \reg2, [\pal, \reg2, lsl #2]    @ reg2 = pal[src[7]]\r
86         ubfx \reg1, \reg3, #0, #8           @ reg1 = src[8]\r
87 \r
88         ldr \reg1, [\pal, \reg1, lsl #2]    @ reg1 = pal[src[8]]\r
89         ubfx \reg5, \reg3, #8, #8           @ reg5 = src[9]\r
90 \r
91         ldr \reg5, [\pal, \reg5, lsl #2]    @ reg5 = pal[src[9]]\r
92         ubfx \reg7, \reg3, #16, #8          @ reg7 = src[10]\r
93 \r
94         ldr \reg7, [\pal, \reg7, lsl #2]    @ reg7 = pal[src[10]]\r
95         bfi \reg6, \reg2, #16, #16          @ reg6 = pal[src[6]] | pal[src[7]] << 16\r
96 \r
97         vmov d17, \reg8, \reg6              @ d17 = pal[src[4-7]]\r
98         lsr     \reg3, \reg3, #24               @ reg3 = src[11]\r
99 \r
100         ldr \reg3, [\pal, \reg3, lsl #2]    @ reg3 = pal[src[11]]\r
101         ubfx \reg2, \reg4, #0, #8           @ reg2 = src[12]\r
102 \r
103         ldr \reg2, [\pal, \reg2, lsl #2]    @ reg2 = pal[src[12]]\r
104         ubfx \reg6, \reg4, #8, #8           @ reg6 = src[13]\r
105 \r
106         ldr \reg6, [\pal, \reg6, lsl #2]    @ reg6 = pal[src[13]]\r
107         ubfx \reg8, \reg4, #16, #8          @ reg8 = src[14]\r
108 \r
109         ldr \reg8, [\pal, \reg8, lsl #2]    @ reg8 = pal[src[14]]\r
110         lsr     \reg4, \reg4, #24               @ reg4 = src[15]\r
111 \r
112         ldr \reg4, [\pal, \reg4, lsl #2]    @ reg4 = pal[src[15]]\r
113         bfi \reg1, \reg5, #16, #16          @ reg1 = pal[src[8]] | pal[src[9]] << 16\r
114 \r
115         bfi \reg7, \reg3, #16, #16          @ reg7 = pal[src[10]] | pal[src[11]] << 16\r
116         bfi \reg2, \reg6, #16, #16          @ reg2 = pal[src[12]] | pal[src[13]] << 16\r
117 \r
118         vmov \dA, \reg1, \reg7              @ dA = pal[src[8-11]]\r
119         sub \counter, \counter, #16         @ counter -= 16\r
120 \r
121         bfi \reg8, \reg4, #16, #16          @ reg8 = pal[src[14]] | pal[src[15]] << 16\r
122         add \src, \src, #16                 @ src += 16\r
123 \r
124         vmov \dB, \reg2, \reg8              @ dB = pal[src[12-15]]\r
125         cmp \counter, #16\r
126 .endm\r
127 \r
128 .macro neon_normal1x_8_16_line src, dst, pal, counter, reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9\r
129     @ align src to 4 bytes\r
130         andS \reg5, \src, #3                @ reg5 = src & 3\r
131         beq 10f\r
132 \r
133     @ first 1-3 pixels\r
134         ldr \reg1, [\src]                   @ reg1 = src[0-3]\r
135         rsb \reg5, \reg5, #4                @ reg5 = 4 - (src & 3)\r
136 \r
137         add \src, \src, \reg5               @ src += reg5\r
138         sub \counter, \counter, \reg5       @ counter -= reg5\r
139 \r
140         subS \reg5, \reg5, #1               @ reg5--\r
141 \r
142         ubfx \reg2, \reg1, #0, #8           @ reg2 = src[0]\r
143         ubfxne \reg3, \reg1, #8, #8         @ reg3 = src[1]\r
144 \r
145         ldr \reg2, [\pal, \reg2, lsl #2]    @ reg2 = pal[reg2]\r
146 \r
147         ldrne \reg3, [\pal, \reg3, lsl #2]  @ reg3 = pal[reg3]\r
148 \r
149         strh \reg2, [\dst]                  @ dst[0] = reg2\r
150 \r
151         strneh \reg3, [\dst, #2]!           @ dst[1] = reg3; dst++\r
152         subneS \reg5, \reg5, #1             @ reg5--\r
153 \r
154         ubfxne \reg4, \reg1, #16, #8        @ reg4 = src[2]\r
155         add \dst, \dst, #2                  @ dst++\r
156 \r
157         ldrne \reg4, [\pal, \reg4, lsl #2]  @ reg4 = pal[reg4]\r
158 \r
159         strneh \reg4, [\dst], #2            @ dst[2] = reg4; dst++\r
160 \r
161     @ middle pixels (16 per iteration)\r
162     10:\r
163         _neon_normalxx_8_16_line_middle \src, \dst, \pal, \counter, \reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8, \reg9, , d18, d19\r
164 \r
165         vst1.16 {d16-d19}, [\dst]!          @ dst[0-15] = d16-d19; dst += 2*16\r
166         bhs 10b\r
167 \r
168     @ last 0-15 bytes\r
169 \r
170         cmp \counter, #0\r
171         beq 40f\r
172 \r
173         cmp \counter, #4\r
174         blo 30f\r
175 \r
176     @ 4-12 pixels (4 pre iteration)\r
177     20:\r
178         ldr \reg1, [\src]                   @ reg1 = src[0-3]\r
179         sub \counter, \counter, #4          @ counter -= 4\r
180 \r
181         add \src, \src, #4                  @ src += 4\r
182         add \dst, \dst, #(2*4)              @ dst += 4\r
183 \r
184         ubfx \reg2, \reg1, #0, #8           @ reg2 = src[0]\r
185         cmp \counter, #4\r
186 \r
187         ldr \reg2, [\pal, \reg2, lsl #2]    @ reg2 = pal[src[0]]\r
188         ubfx \reg3, \reg1, #8, #8           @ reg3 = src[1]\r
189 \r
190         ldr \reg3, [\pal, \reg3, lsl #2]    @ reg3 = pal[src[1]]\r
191         ubfx \reg4, \reg1, #16, #8          @ reg4 = src[2]\r
192 \r
193         ldr \reg4, [\pal, \reg4, lsl #2]    @ reg4 = pal[src[2]]\r
194         lsr     \reg1, \reg1, #24               @ reg1 = src[3]\r
195 \r
196         ldr \reg1, [\pal, \reg1, lsl #2]    @ reg1 = pal[src[3]]\r
197 \r
198         strh \reg2, [\dst, #-8]             @ dst[0] = reg2\r
199 \r
200         strh \reg3, [\dst, #-6]             @ dst[1] = reg3\r
201 \r
202         strh \reg4, [\dst, #-4]             @ dst[2] = reg4\r
203 \r
204         strh \reg1, [\dst, #-2]             @ dst[3] = reg1\r
205         bhs 20b\r
206 \r
207         cmp \counter, #0\r
208         beq 40f\r
209 \r
210     @ last 1-3 pixels\r
211     30:\r
212         ldrb \reg1, [\src]                  @ reg1 = src[0]\r
213         subS \counter, \counter, #1         @ counter--\r
214 \r
215         ldrneb \reg2, [\src, #1]!           @ reg2 = src[1]; src++\r
216 \r
217         add \src, \src, #1                  @ src++\r
218 \r
219         ldr \reg1, [\pal, \reg1, lsl #2]    @ reg1 = pal[src[0]]\r
220 \r
221         ldrne \reg2, [\pal, \reg2, lsl #2]  @ reg2 = pal[src[1]]\r
222 \r
223         strh \reg1, [\dst]                  @ dst[0] = reg1\r
224 \r
225         strneh \reg2, [\dst, #2]!           @ dst[1] = reg2; dst++\r
226         subneS \counter, \counter, #1       @ counter--\r
227 \r
228         ldrneb \reg3, [\src], #1            @ reg3 = src[2]; src++\r
229         add \dst, \dst, #2                  @ dst++\r
230 \r
231         ldrne \reg3, [\pal, \reg3, lsl #2]  @ reg3 = pal[src[2]]\r
232 \r
233         strneh \reg3, [\dst], #2            @ dst[2] = reg3; dst++\r
234 \r
235     40:\r
236 .endm\r
237 \r
238 .macro neon_normal2x_8_16_line src, dst, pal, counter, reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9, dststride\r
239     @ align src to 4 bytes\r
240         andS \reg5, \src, #3                @ reg5 = src & 3\r
241         beq 10f\r
242 \r
243     @ first 1-3 pixels\r
244         rsb \reg5, \reg5, #4                @ reg5 = 4 - (src & 3)\r
245     1:\r
246         ldrb \reg1, [\src], #1              @ reg1 = src[0]; src++\r
247         add \reg2, \dst, \dststride\r
248 \r
249         add \dst, \dst, #4                  @ dst += 2*2\r
250         sub \counter, \counter, #1          @ counter--\r
251 \r
252         ldr \reg1, [\pal, \reg1, lsl #2]    @ reg1 = pal[src[0]]\r
253         subS \reg5, \reg5, #1               @ reg5--\r
254 \r
255         strh \reg1, [\dst, #-4]             @ dst[0] = reg1\r
256 \r
257         strh \reg1, [\dst, #-2]             @ dst[1] = reg1\r
258 \r
259         strh \reg1, [\reg2]                 @ dst1[0] = reg1\r
260 \r
261         strh \reg1, [\reg2, #2]             @ dst1[1] = reg1\r
262         bne 1b\r
263 \r
264     @ middle pixels (16 per iteration)\r
265     10:\r
266         _neon_normalxx_8_16_line_middle \src, \dst, \pal, \counter, \reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8, \reg9, \dststride, d20, d21\r
267 \r
268         vmov q9, q8\r
269         add \reg1, \dst, \dststride         @ reg1 = dst + dststride\r
270 \r
271         vmov q11, q10\r
272         vst2.16 {q8,q9}, [\dst]!            @ dst[0-7] = q8-q9; dst += 2*2*8\r
273 \r
274         vst2.16 {q10,q11}, [\dst]!          @ dst[8-15] = q10-q11; dst += 2*2*8\r
275 \r
276         vst2.16 {q8,q9}, [\reg1]!           @ dst1[0-7] = q8-q9; dst1 += 2*2*8\r
277 \r
278         vst2.16 {q10,q11}, [\reg1]!         @ dst1[8-15] = q10-q11; dst1 += 2*2*8\r
279         bhs 10b\r
280 \r
281     @ last 0-15 bytes\r
282 \r
283         cmp \counter, #0\r
284         beq 40f\r
285 \r
286         cmp \counter, #4\r
287         blo 30f\r
288 \r
289     @ 4-12 pixels (4 pre iteration)\r
290     20:\r
291         ldr \reg1, [\src]                   @ reg1 = src[0-3]\r
292         sub \counter, \counter, #4          @ counter -= 4\r
293 \r
294         add \src, \src, #4                  @ src += 4\r
295 \r
296         ubfx \reg2, \reg1, #0, #8           @ reg2 = src[0]\r
297         cmp \counter, #4\r
298 \r
299         ldr \reg2, [\pal, \reg2, lsl #2]    @ reg2 = pal[src[0]]\r
300         ubfx \reg3, \reg1, #8, #8           @ reg3 = src[1]\r
301 \r
302         ldr \reg3, [\pal, \reg3, lsl #2]    @ reg3 = pal[src[1]]\r
303         ubfx \reg4, \reg1, #16, #8          @ reg4 = src[2]\r
304 \r
305         ldr \reg4, [\pal, \reg4, lsl #2]    @ reg4 = pal[src[2]]\r
306         lsr     \reg1, \reg1, #24               @ reg1 = src[3]\r
307 \r
308         ldr \reg1, [\pal, \reg1, lsl #2]    @ reg1 = pal[src[3]]\r
309 \r
310         add \reg5, \dst, \dststride\r
311         bfi \reg2, \reg3, #16, #16          @ reg2 = reg2 | reg3 << 16\r
312 \r
313         vmov.32 d16[0], \reg2\r
314 \r
315         bfi \reg4, \reg1, #16, #16          @ reg4 = reg4 | reg1 << 16\r
316 \r
317         vmov.32 d16[1], \reg4\r
318 \r
319         vmov d17, d16\r
320 \r
321         vst2.16 {d16,d17}, [\dst]!          @ dst[0-7] = d16-d17; dst += 2*2*4\r
322 \r
323         vst2.16 {d16,d17}, [\reg5]          @ dst1[0-7] = d16-d17\r
324         bhs 20b\r
325 \r
326         cmp \counter, #0\r
327         beq 40f\r
328 \r
329     @ last 1-3 pixels\r
330     30:\r
331         ldrb \reg1, [\src], #1              @ reg1 = src[0]; src++\r
332         add \reg2, \dst, \dststride\r
333 \r
334         add \dst, \dst, #4                  @ dst += 2*2\r
335 \r
336         ldr \reg1, [\pal, \reg1, lsl #2]    @ reg1 = pal[src[0]]\r
337         subS \counter, \counter, #1         @ counter--\r
338 \r
339         strh \reg1, [\dst, #-4]             @ dst[0] = reg1\r
340 \r
341         strh \reg1, [\dst, #-2]             @ dst[1] = reg1\r
342 \r
343         strh \reg1, [\reg2]                 @ dst1[0] = reg1\r
344 \r
345         strh \reg1, [\reg2, #2]             @ dst1[1] = reg1\r
346         bne 30b\r
347 \r
348     40:\r
349 .endm\r
350 \r
351 .macro neon_normal3x_8_16_line src, dst, pal, counter, reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9, dststride\r
352     @ align src to 4 bytes\r
353         andS \reg5, \src, #3                @ reg5 = src & 3\r
354         beq 10f\r
355 \r
356     @ first 1-3 pixels\r
357         rsb \reg5, \reg5, #4                @ reg5 = 4 - (src & 3)\r
358     1:\r
359         ldrb \reg1, [\src], #1              @ reg1 = src[0]; src++\r
360         add \reg2, \dst, \dststride\r
361 \r
362         add \reg3, \reg2, \dststride\r
363         add \dst, \dst, #6                  @ dst += 3*2\r
364 \r
365         sub \counter, \counter, #1          @ counter--\r
366 \r
367         ldr \reg1, [\pal, \reg1, lsl #2]    @ reg1 = pal[src[0]]\r
368         subS \reg5, \reg5, #1               @ reg5--\r
369 \r
370         strh \reg1, [\dst, #-6]             @ dst[0] = reg1\r
371 \r
372         strh \reg1, [\dst, #-4]             @ dst[1] = reg1\r
373 \r
374         strh \reg1, [\dst, #-2]             @ dst[2] = reg1\r
375         bfi \reg1, \reg1, #16, #16          @ reg1 = reg1 | reg1 << 16\r
376 \r
377         strh \reg1, [\reg2]                 @ dst1[0] = reg1\r
378 \r
379         str \reg1, [\reg2, #2]              @ dst1[1-2] = reg1\r
380 \r
381         strh \reg1, [\reg3]                 @ dst2[0] = reg1\r
382 \r
383         str \reg1, [\reg3, #2]              @ dst2[1-2] = reg1\r
384         bne 1b\r
385 \r
386     @ middle pixels (16 per iteration)\r
387     10:\r
388         _neon_normalxx_8_16_line_middle \src, \dst, \pal, \counter, \reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8, \reg9, \dststride, d22, d23\r
389 \r
390         vmov q9, q8\r
391         add \reg1, \dst, \dststride         @ reg1 = dst + dststride\r
392 \r
393         vmov q10, q8\r
394         add \reg2, \dst, \dststride, lsl #1 @ reg1 = dst + 2 * dststride\r
395 \r
396         vmov q12, q11\r
397         vst3.16 {d16,d18,d20}, [\dst]!      @ dst[0-3] = q8-q10[0]; dst += 3*2*4\r
398 \r
399         vmov q13, q11\r
400         vst3.16 {d17,d19,d21}, [\dst]!      @ dst[4-7] = q8-q10[1]; dst += 3*2*4\r
401 \r
402         vst3.16 {d22,d24,d26}, [\dst]!      @ dst[8-11] = q11-q13[0]; dst += 3*2*4\r
403 \r
404         vst3.16 {d23,d25,d27}, [\dst]!      @ dst[12-15] = q11-q13[1]; dst += 3*2*4\r
405 \r
406         vst3.16 {d16,d18,d20}, [\reg1]!     @ dst1[0-3] = q8-q10[0]; dst1 += 3*2*4\r
407 \r
408         vst3.16 {d17,d19,d21}, [\reg1]!     @ dst1[4-7] = q8-q10[1]; dst1 += 3*2*4\r
409 \r
410         vst3.16 {d22,d24,d26}, [\reg1]!     @ dst1[8-11] = q11-q13[0]; dst1 += 3*2*4\r
411 \r
412         vst3.16 {d23,d25,d27}, [\reg1]!     @ dst1[12-15] = q11-q13[1]; dst1 += 3*2*4\r
413 \r
414         vst3.16 {d16,d18,d20}, [\reg2]!     @ dst2[0-3] = q8-q10[0]; dst2 += 3*2*4\r
415 \r
416         vst3.16 {d17,d19,d21}, [\reg2]!     @ dst2[4-7] = q8-q10[1]; dst2 += 3*2*4\r
417 \r
418         vst3.16 {d22,d24,d26}, [\reg2]!     @ dst2[8-11] = q11-q13[0]; dst2 += 3*2*4\r
419 \r
420         vst3.16 {d23,d25,d27}, [\reg2]!     @ dst2[12-15] = q11-q13[1]; dst2 += 3*2*4\r
421         bhs 10b\r
422 \r
423     @ last 0-15 bytes\r
424 \r
425         cmp \counter, #0\r
426         beq 40f\r
427 \r
428         cmp \counter, #4\r
429         blo 30f\r
430 \r
431     @ 4-12 pixels (4 pre iteration)\r
432     20:\r
433         ldr \reg1, [\src]                   @ reg1 = src[0-3]\r
434         sub \counter, \counter, #4          @ counter -= 4\r
435 \r
436         add \src, \src, #4                  @ src += 4\r
437 \r
438         ubfx \reg2, \reg1, #0, #8           @ reg2 = src[0]\r
439         cmp \counter, #4\r
440 \r
441         ldr \reg2, [\pal, \reg2, lsl #2]    @ reg2 = pal[src[0]]\r
442         ubfx \reg3, \reg1, #8, #8           @ reg3 = src[1]\r
443 \r
444         ldr \reg3, [\pal, \reg3, lsl #2]    @ reg3 = pal[src[1]]\r
445         ubfx \reg4, \reg1, #16, #8          @ reg4 = src[2]\r
446 \r
447         ldr \reg4, [\pal, \reg4, lsl #2]    @ reg4 = pal[src[2]]\r
448         lsr     \reg1, \reg1, #24               @ reg1 = src[3]\r
449 \r
450         ldr \reg1, [\pal, \reg1, lsl #2]    @ reg1 = pal[src[3]]\r
451 \r
452         add \reg5, \dst, \dststride\r
453         bfi \reg2, \reg3, #16, #16          @ reg2 = reg2 | reg3 << 16\r
454 \r
455         vmov.32 d16[0], \reg2\r
456         add \reg6, \reg5, \dststride\r
457 \r
458         bfi \reg4, \reg1, #16, #16          @ reg4 = reg4 | reg1 << 16\r
459 \r
460         vmov.32 d16[1], \reg4\r
461 \r
462         vmov d17, d16\r
463 \r
464         vmov d18, d16\r
465 \r
466         vst3.16 {d16,d17,d18}, [\dst]!      @ dst[0-11] = d16-d18; dst += 3*2*4\r
467 \r
468         vst3.16 {d16,d17,d18}, [\reg5]      @ dst1[0-11] = d16-d18\r
469 \r
470         vst3.16 {d16,d17,d18}, [\reg6]      @ dst2[0-11] = d16-d18\r
471         bhs 20b\r
472 \r
473         cmp \counter, #0\r
474         beq 40f\r
475 \r
476     @ last 1-3 pixels\r
477     30:\r
478         ldrb \reg1, [\src], #1              @ reg1 = src[0]; src++\r
479         add \reg2, \dst, \dststride\r
480 \r
481         add \reg3, \reg2, \dststride\r
482         add \dst, \dst, #6                  @ dst += 3*2\r
483 \r
484         ldr \reg1, [\pal, \reg1, lsl #2]    @ reg1 = pal[src[0]]\r
485         subS \counter, \counter, #1         @ counter--\r
486 \r
487         strh \reg1, [\dst, #-6]             @ dst[0] = reg1\r
488 \r
489         strh \reg1, [\dst, #-4]             @ dst[1] = reg1\r
490 \r
491         strh \reg1, [\dst, #-2]             @ dst[2] = reg1\r
492         bfi \reg1, \reg1, #16, #16          @ reg1 = reg1 | reg1 << 16\r
493 \r
494         strh \reg1, [\reg2]                 @ dst1[0] = reg1\r
495 \r
496         str \reg1, [\reg2, #2]              @ dst1[1-2] = reg1\r
497 \r
498         strh \reg1, [\reg3]                 @ dst2[0] = reg1\r
499 \r
500         str \reg1, [\reg3, #2]              @ dst2[1-2] = reg1\r
501         bne 30b\r
502 \r
503     40:\r
504 .endm\r
505 \r
506 .macro neon_normal4x_8_16_line src, dst, pal, counter, reg1, reg2, reg3, reg4, reg5, reg6, reg7, reg8, reg9, dststride\r
507     @ align src to 4 bytes\r
508         andS \reg5, \src, #3                @ reg5 = src & 3\r
509         beq 10f\r
510 \r
511     @ first 1-3 pixels\r
512         rsb \reg5, \reg5, #4                @ reg5 = 4 - (src & 3)\r
513     1:\r
514         ldrb \reg1, [\src], #1              @ reg1 = src[0]; src++\r
515         add \reg2, \dst, \dststride\r
516 \r
517         add \reg3, \reg2, \dststride\r
518         add \dst, \dst, #8                  @ dst += 4*2\r
519 \r
520         sub \counter, \counter, #1          @ counter--\r
521 \r
522         ldr \reg1, [\pal, \reg1, lsl #2]    @ reg1 = pal[src[0]]\r
523         add \reg4, \reg3, \dststride\r
524 \r
525         strh \reg1, [\dst, #-8]             @ dst[0] = reg1\r
526         subS \reg5, \reg5, #1               @ reg5--\r
527 \r
528         strh \reg1, [\dst, #-6]             @ dst[1] = reg1\r
529 \r
530         bfi \reg1, \reg1, #16, #16          @ reg1 = reg1 | reg1 << 16\r
531         str \reg1, [\dst, #-4]              @ dst[2-3] = reg1\r
532 \r
533         str \reg1, [\reg2]                  @ dst1[0-1] = reg1\r
534 \r
535         str \reg1, [\reg2, #4]              @ dst1[2-3] = reg1\r
536 \r
537         str \reg1, [\reg3]                  @ dst2[0-1] = reg1\r
538 \r
539         str \reg1, [\reg3, #4]              @ dst2[2-3] = reg1\r
540 \r
541         str \reg1, [\reg4]                  @ dst3[0-1] = reg1\r
542 \r
543         str \reg1, [\reg4, #4]              @ dst3[2-3] = reg1\r
544         bne 1b\r
545 \r
546     @ middle pixels (16 per iteration)\r
547     10:\r
548         _neon_normalxx_8_16_line_middle \src, \dst, \pal, \counter, \reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8, \reg9, \dststride, d24, d25\r
549 \r
550         vmov q9, q8\r
551         add \reg1, \dst, \dststride         @ reg1 = dst + dststride\r
552 \r
553         vmov q10, q8\r
554         add \reg2, \dst, \dststride, lsl #1 @ reg2 = dst + 2 * dststride\r
555 \r
556         vmov q11, q8\r
557         add \reg3, \reg1, \dststride,lsl #1 @ reg3 = dst + 3 * dststride\r
558 \r
559         vmov q13, q12\r
560         vst4.16 {d16,d18,d20,d22}, [\dst]!  @ dst[0-3] = q8-q11[0]; dst += 4*2*4\r
561 \r
562         vmov q14, q12\r
563 \r
564         vmov q15, q12\r
565         vst4.16 {d17,d19,d21,d23}, [\dst]!  @ dst[4-7] = q8-q11[1]; dst += 4*2*4\r
566 \r
567         vst4.16 {d24,d26,d28,d30}, [\dst]!  @ dst[8-11] = q12-q15[0]; dst += 4*2*4\r
568 \r
569         vst4.16 {d25,d27,d29,d31}, [\dst]!  @ dst[12-15] = q12-q15[1]; dst += 4*2*4\r
570 \r
571         vst4.16 {d16,d18,d20,d22}, [\reg1]! @ dst1[0-3] = q8-q11[0]; dst1 += 4*2*4\r
572 \r
573         vst4.16 {d17,d19,d21,d23}, [\reg1]! @ dst1[4-7] = q8-q11[1]; dst1 += 4*2*4\r
574 \r
575         vst4.16 {d24,d26,d28,d30}, [\reg1]! @ dst1[8-11] = q12-q15[0]; dst1 += 4*2*4\r
576 \r
577         vst4.16 {d25,d27,d29,d31}, [\reg1]! @ dst1[12-15] = q12-q15[1]; dst1 += 4*2*4\r
578 \r
579         vst4.16 {d16,d18,d20,d22}, [\reg2]! @ dst2[0-3] = q8-q11[0]; dst2 += 4*2*4\r
580 \r
581         vst4.16 {d17,d19,d21,d23}, [\reg2]! @ dst2[4-7] = q8-q11[1]; dst2 += 4*2*4\r
582 \r
583         vst4.16 {d24,d26,d28,d30}, [\reg2]! @ dst2[8-11] = q12-q15[0]; dst2 += 4*2*4\r
584 \r
585         vst4.16 {d25,d27,d29,d31}, [\reg2]! @ dst2[12-15] = q12-q15[1]; dst2 += 4*2*4\r
586 \r
587         vst4.16 {d16,d18,d20,d22}, [\reg3]! @ dst3[0-3] = q8-q11[0]; dst3 += 4*2*4\r
588 \r
589         vst4.16 {d17,d19,d21,d23}, [\reg3]! @ dst3[4-7] = q8-q11[1]; dst3 += 4*2*4\r
590 \r
591         vst4.16 {d24,d26,d28,d30}, [\reg3]! @ dst3[8-11] = q12-q15[0]; dst3 += 4*2*4\r
592 \r
593         vst4.16 {d25,d27,d29,d31}, [\reg3]! @ dst3[12-15] = q12-q15[1]; dst3 += 4*2*4\r
594         bhs 10b\r
595 \r
596     @ last 0-15 bytes\r
597 \r
598         cmp \counter, #0\r
599         beq 40f\r
600 \r
601         cmp \counter, #4\r
602         blo 30f\r
603 \r
604     @ 4-12 pixels (4 pre iteration)\r
605     20:\r
606         ldr \reg1, [\src]                   @ reg1 = src[0-3]\r
607         sub \counter, \counter, #4          @ counter -= 4\r
608 \r
609         add \src, \src, #4                  @ src += 4\r
610 \r
611         ubfx \reg2, \reg1, #0, #8           @ reg2 = src[0]\r
612         cmp \counter, #4\r
613 \r
614         ldr \reg2, [\pal, \reg2, lsl #2]    @ reg2 = pal[src[0]]\r
615         ubfx \reg3, \reg1, #8, #8           @ reg3 = src[1]\r
616 \r
617         ldr \reg3, [\pal, \reg3, lsl #2]    @ reg3 = pal[src[1]]\r
618         ubfx \reg4, \reg1, #16, #8          @ reg4 = src[2]\r
619 \r
620         ldr \reg4, [\pal, \reg4, lsl #2]    @ reg4 = pal[src[2]]\r
621         lsr     \reg1, \reg1, #24               @ reg1 = src[3]\r
622 \r
623         ldr \reg1, [\pal, \reg1, lsl #2]    @ reg1 = pal[src[3]]\r
624 \r
625         add \reg5, \dst, \dststride\r
626         bfi \reg2, \reg3, #16, #16          @ reg2 = reg2 | reg3 << 16\r
627 \r
628         vmov.32 d16[0], \reg2\r
629         add \reg6, \reg5, \dststride\r
630 \r
631         bfi \reg4, \reg1, #16, #16          @ reg4 = reg4 | reg1 << 16\r
632         add \reg7, \reg6, \dststride\r
633 \r
634         vmov.32 d16[1], \reg4\r
635 \r
636         vmov d17, d16\r
637 \r
638         vmov d18, d16\r
639 \r
640         vmov d19, d16\r
641 \r
642         vst4.16 {d16,d17,d18,d19}, [\dst]!  @ dst[0-15] = d16-d19; dst += 4*2*4\r
643 \r
644         vst4.16 {d16,d17,d18,d19}, [\reg5]  @ dst1[0-15] = d16-d19\r
645 \r
646         vst4.16 {d16,d17,d18,d19}, [\reg6]  @ dst2[0-15] = d16-d19\r
647 \r
648         vst4.16 {d16,d17,d18,d19}, [\reg7]  @ dst3[0-15] = d16-d19\r
649         bhs 20b\r
650 \r
651         cmp \counter, #0\r
652         beq 40f\r
653 \r
654     @ last 1-3 pixels\r
655     30:\r
656         ldrb \reg1, [\src], #1              @ reg1 = src[0]; src++\r
657         add \reg2, \dst, \dststride\r
658 \r
659         add \reg3, \reg2, \dststride\r
660         add \dst, \dst, #8                  @ dst += 4*2\r
661 \r
662         ldr \reg1, [\pal, \reg1, lsl #2]    @ reg1 = pal[src[0]]\r
663         add \reg4, \reg3, \dststride\r
664 \r
665         strh \reg1, [\dst, #-8]             @ dst[0] = reg1\r
666         subS \counter, \counter, #1         @ counter--\r
667 \r
668         strh \reg1, [\dst, #-6]             @ dst[1] = reg1\r
669 \r
670         bfi \reg1, \reg1, #16, #16          @ reg1 = reg1 | reg1 << 16\r
671         str \reg1, [\dst, #-4]              @ dst[2-3] = reg1\r
672 \r
673         str \reg1, [\reg2]                  @ dst1[0-1] = reg1\r
674 \r
675         str \reg1, [\reg2, #4]              @ dst1[2-3] = reg1\r
676 \r
677         str \reg1, [\reg3]                  @ dst2[0-1] = reg1\r
678 \r
679         str \reg1, [\reg3, #4]              @ dst2[2-3] = reg1\r
680 \r
681         str \reg1, [\reg4]                  @ dst3[0-1] = reg1\r
682 \r
683         str \reg1, [\reg4, #4]              @ dst3[2-3] = reg1\r
684         bne 30b\r
685 \r
686     40:\r
687 .endm\r
688 \r