ARM: optimization for scaled src_0565_0565 with nearest filter
[profile/ivi/pixman.git] / pixman / pixman-arm-simd-asm.S
1 /*
2  * Copyright © 2008 Mozilla Corporation
3  * Copyright © 2010 Nokia Corporation
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and its
6  * documentation for any purpose is hereby granted without fee, provided that
7  * the above copyright notice appear in all copies and that both that
8  * copyright notice and this permission notice appear in supporting
9  * documentation, and that the name of Mozilla Corporation not be used in
10  * advertising or publicity pertaining to distribution of the software without
11  * specific, written prior permission.  Mozilla Corporation makes no
12  * representations about the suitability of this software for any purpose.  It
13  * is provided "as is" without express or implied warranty.
14  *
15  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
16  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
18  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
20  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
21  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
22  * SOFTWARE.
23  *
24  * Author:  Jeff Muizelaar (jeff@infidigm.net)
25  *
26  */
27
28 /* Prevent the stack from becoming executable */
29 #if defined(__linux__) && defined(__ELF__)
30 .section .note.GNU-stack,"",%progbits
31 #endif
32
33         .text
34         .arch armv6
35         .object_arch armv4
36         .arm
37         .altmacro
38
39 /* Supplementary macro for setting function attributes */
40 .macro pixman_asm_function fname
41         .func fname
42         .global fname
43 #ifdef __ELF__
44         .hidden fname
45         .type fname, %function
46 #endif
47 fname:
48 .endm
49
50 /*
51  * The code below was generated by gcc 4.3.4 from the commented out
52  * functions in 'pixman-arm-simd.c' file with the following optimization
53  * options: "-O3 -mcpu=arm1136jf-s -fomit-frame-pointer"
54  *
55  * TODO: replace gcc generated code with hand tuned versions because
56  * the code quality is not very good, introduce symbolic register
57  * aliases for better readability and maintainability.
58  */
59
60 pixman_asm_function pixman_composite_add_8_8_asm_armv6
61         push    {r4, r5, r6, r7, r8, r9, r10, r11}
62         mov     r10, r1
63         sub     sp, sp, #4
64         subs    r10, r10, #1
65         mov     r11, r0
66         mov     r8, r2
67         str     r3, [sp]
68         ldr     r7, [sp, #36]
69         bcc     0f
70 6:      cmp     r11, #0
71         beq     1f
72         orr     r3, r8, r7
73         tst     r3, #3
74         beq     2f
75         mov     r1, r8
76         mov     r0, r7
77         mov     r12, r11
78         b       3f
79 5:      tst     r3, #3
80         beq     4f
81 3:      ldrb    r2, [r0], #1
82         subs    r12, r12, #1
83         ldrb    r3, [r1]
84         uqadd8  r3, r2, r3
85         strb    r3, [r1], #1
86         orr     r3, r1, r0
87         bne     5b
88 1:      ldr     r3, [sp]
89         add     r8, r8, r3
90         ldr     r3, [sp, #40]
91         add     r7, r7, r3
92 10:     subs    r10, r10, #1
93         bcs     6b
94 0:      add     sp, sp, #4
95         pop     {r4, r5, r6, r7, r8, r9, r10, r11}
96         bx      lr
97 2:      mov     r12, r11
98         mov     r1, r8
99         mov     r0, r7
100 4:      cmp     r12, #3
101         subgt   r6, r12, #4
102         movgt   r9, r12
103         lsrgt   r5, r6, #2
104         addgt   r3, r5, #1
105         movgt   r12, #0
106         lslgt   r4, r3, #2
107         ble     7f
108 8:      ldr     r3, [r0, r12]
109         ldr     r2, [r1, r12]
110         uqadd8  r3, r3, r2
111         str     r3, [r1, r12]
112         add     r12, r12, #4
113         cmp     r12, r4
114         bne     8b
115         sub     r3, r9, #4
116         bic     r3, r3, #3
117         add     r3, r3, #4
118         subs    r12, r6, r5, lsl #2
119         add     r1, r1, r3
120         add     r0, r0, r3
121         beq     1b
122 7:      mov     r4, #0
123 9:      ldrb    r3, [r1, r4]
124         ldrb    r2, [r0, r4]
125         uqadd8  r3, r2, r3
126         strb    r3, [r1, r4]
127         add     r4, r4, #1
128         cmp     r4, r12
129         bne     9b
130         ldr     r3, [sp]
131         add     r8, r8, r3
132         ldr     r3, [sp, #40]
133         add     r7, r7, r3
134         b       10b
135 .endfunc
136
137 pixman_asm_function pixman_composite_over_8888_8888_asm_armv6
138         push    {r4, r5, r6, r7, r8, r9, r10, r11}
139         sub     sp, sp, #20
140         cmp     r1, #0
141         mov     r12, r2
142         str     r1, [sp, #12]
143         str     r0, [sp, #16]
144         ldr     r2, [sp, #52]
145         beq     0f
146         lsl     r3, r3, #2
147         str     r3, [sp]
148         ldr     r3, [sp, #56]
149         mov     r10, #0
150         lsl     r3, r3, #2
151         str     r3, [sp, #8]
152         mov     r11, r3
153         b       1f
154 6:      ldr     r11, [sp, #8]
155 1:      ldr     r9, [sp]
156         mov     r0, r12
157         add     r12, r12, r9
158         mov     r1, r2
159         str     r12, [sp, #4]
160         add     r2, r2, r11
161         ldr     r12, [sp, #16]
162         ldr     r3, =0x00800080
163         ldr     r9, =0xff00ff00
164         mov     r11, #255
165         cmp     r12, #0
166         beq     4f
167 5:      ldr     r5, [r1], #4
168         ldr     r4, [r0]
169         sub     r8, r11, r5, lsr #24
170         uxtb16  r6, r4
171         uxtb16  r7, r4, ror #8
172         mla     r6, r6, r8, r3
173         mla     r7, r7, r8, r3
174         uxtab16 r6, r6, r6, ror #8
175         uxtab16 r7, r7, r7, ror #8
176         and     r7, r7, r9
177         uxtab16 r6, r7, r6, ror #8
178         uqadd8  r5, r6, r5
179         str     r5, [r0], #4
180         subs    r12, r12, #1
181         bne     5b
182 4:      ldr     r3, [sp, #12]
183         add     r10, r10, #1
184         cmp     r10, r3
185         ldr     r12, [sp, #4]
186         bne     6b
187 0:      add     sp, sp, #20
188         pop     {r4, r5, r6, r7, r8, r9, r10, r11}
189         bx      lr
190 .endfunc
191
192 pixman_asm_function pixman_composite_over_8888_n_8888_asm_armv6
193         push    {r4, r5, r6, r7, r8, r9, r10, r11}
194         sub     sp, sp, #28
195         cmp     r1, #0
196         str     r1, [sp, #12]
197         ldrb    r1, [sp, #71]
198         mov     r12, r2
199         str     r0, [sp, #16]
200         ldr     r2, [sp, #60]
201         str     r1, [sp, #24]
202         beq     0f
203         lsl     r3, r3, #2
204         str     r3, [sp, #20]
205         ldr     r3, [sp, #64]
206         mov     r10, #0
207         lsl     r3, r3, #2
208         str     r3, [sp, #8]
209         mov     r11, r3
210         b       1f
211 5:      ldr     r11, [sp, #8]
212 1:      ldr     r4, [sp, #20]
213         mov     r0, r12
214         mov     r1, r2
215         add     r12, r12, r4
216         add     r2, r2, r11
217         str     r12, [sp]
218         str     r2, [sp, #4]
219         ldr     r12, [sp, #16]
220         ldr     r2, =0x00800080
221         ldr     r3, [sp, #24]
222         mov     r11, #255
223         cmp     r12, #0
224         beq     3f
225 4:      ldr     r5, [r1], #4
226         ldr     r4, [r0]
227         uxtb16  r6, r5
228         uxtb16  r7, r5, ror #8
229         mla     r6, r6, r3, r2
230         mla     r7, r7, r3, r2
231         uxtab16 r6, r6, r6, ror #8
232         uxtab16 r7, r7, r7, ror #8
233         uxtb16  r6, r6, ror #8
234         uxtb16  r7, r7, ror #8
235         orr     r5, r6, r7, lsl #8
236         uxtb16  r6, r4
237         uxtb16  r7, r4, ror #8
238         sub     r8, r11, r5, lsr #24
239         mla     r6, r6, r8, r2
240         mla     r7, r7, r8, r2
241         uxtab16 r6, r6, r6, ror #8
242         uxtab16 r7, r7, r7, ror #8
243         uxtb16  r6, r6, ror #8
244         uxtb16  r7, r7, ror #8
245         orr     r6, r6, r7, lsl #8
246         uqadd8  r5, r6, r5
247         str     r5, [r0], #4
248         subs    r12, r12, #1
249         bne     4b
250 3:      ldr     r1, [sp, #12]
251         add     r10, r10, #1
252         cmp     r10, r1
253         ldr     r12, [sp]
254         ldr     r2, [sp, #4]
255         bne     5b
256 0:      add     sp, sp, #28
257         pop     {r4, r5, r6, r7, r8, r9, r10, r11}
258         bx      lr
259 .endfunc
260
261 pixman_asm_function pixman_composite_over_n_8_8888_asm_armv6
262         push    {r4, r5, r6, r7, r8, r9, r10, r11}
263         sub     sp, sp, #28
264         cmp     r1, #0
265         ldr     r9, [sp, #60]
266         str     r1, [sp, #12]
267         bic     r1, r9, #-16777216
268         str     r1, [sp, #20]
269         mov     r12, r2
270         lsr     r1, r9, #8
271         ldr     r2, [sp, #20]
272         bic     r1, r1, #-16777216
273         bic     r2, r2, #65280
274         bic     r1, r1, #65280
275         str     r2, [sp, #20]
276         str     r0, [sp, #16]
277         str     r1, [sp, #4]
278         ldr     r2, [sp, #68]
279         beq     0f
280         lsl     r3, r3, #2
281         str     r3, [sp, #24]
282         mov     r0, #0
283         b       1f
284 5:      ldr     r3, [sp, #24]
285 1:      ldr     r4, [sp, #72]
286         mov     r10, r12
287         mov     r1, r2
288         add     r12, r12, r3
289         add     r2, r2, r4
290         str     r12, [sp, #8]
291         str     r2, [sp]
292         ldr     r12, [sp, #16]
293         ldr     r11, =0x00800080
294         ldr     r2, [sp, #4]
295         ldr     r3, [sp, #20]
296         cmp     r12, #0
297         beq     3f
298 4:      ldrb    r5, [r1], #1
299         ldr     r4, [r10]
300         mla     r6, r3, r5, r11
301         mla     r7, r2, r5, r11
302         uxtab16 r6, r6, r6, ror #8
303         uxtab16 r7, r7, r7, ror #8
304         uxtb16  r6, r6, ror #8
305         uxtb16  r7, r7, ror #8
306         orr     r5, r6, r7, lsl #8
307         uxtb16  r6, r4
308         uxtb16  r7, r4, ror #8
309         mvn     r8, r5
310         lsr     r8, r8, #24
311         mla     r6, r6, r8, r11
312         mla     r7, r7, r8, r11
313         uxtab16 r6, r6, r6, ror #8
314         uxtab16 r7, r7, r7, ror #8
315         uxtb16  r6, r6, ror #8
316         uxtb16  r7, r7, ror #8
317         orr     r6, r6, r7, lsl #8
318         uqadd8  r5, r6, r5
319         str     r5, [r10], #4
320         subs    r12, r12, #1
321         bne     4b
322 3:      ldr     r4, [sp, #12]
323         add     r0, r0, #1
324         cmp     r0, r4
325         ldr     r12, [sp, #8]
326         ldr     r2, [sp]
327         bne     5b
328 0:      add     sp, sp, #28
329         pop     {r4, r5, r6, r7, r8, r9, r10, r11}
330         bx      lr
331 .endfunc
332
333 /*
334  * Note: This function is only using armv4t instructions (not even armv6),
335  *       but is scheduled for ARM Cortex-A8 pipeline. So it might need to
336  *       be split into a few variants, tuned for each microarchitecture.
337  *
338  * TODO: In order to get good performance on ARM9/ARM11 cores (which don't
339  * have efficient write combining), it needs to be changed to use 16-byte
340  * aligned writes using STM instruction.
341  */
342 pixman_asm_function pixman_scaled_nearest_scanline_0565_0565_SRC_asm_armv6
343         W       .req    r0
344         DST     .req    r1
345         SRC     .req    r2
346         VX      .req    r3
347         UNIT_X  .req    ip
348         TMP1    .req    r4
349         TMP2    .req    r5
350         VXMASK  .req    r6
351
352         ldr     UNIT_X, [sp]
353         push    {r4, r5, r6, r7}
354         mvn     VXMASK, #1
355
356         /* define helper macro */
357         .macro  scale_2_pixels
358                 ldrh    TMP1, [SRC, TMP1]
359                 and     TMP2, VXMASK, VX, lsr #15
360                 add     VX, VX, UNIT_X
361                 strh    TMP1, [DST], #2
362
363                 ldrh    TMP2, [SRC, TMP2]
364                 and     TMP1, VXMASK, VX, lsr #15
365                 add     VX, VX, UNIT_X
366                 strh    TMP2, [DST], #2
367         .endm
368
369         /* now do the scaling */
370         and     TMP1, VXMASK, VX, lsr #15
371         add     VX, VX, UNIT_X
372         subs    W, #4
373         blt     2f
374 1: /* main loop, process 4 pixels per iteration */
375         scale_2_pixels
376         scale_2_pixels
377         subs    W, W, #4
378         bge     1b
379 2:
380         tst     W, #2
381         beq     2f
382         scale_2_pixels
383 2:
384         tst     W, #1
385         ldrneh  TMP1, [SRC, TMP1]
386         strneh  TMP1, [DST], #2
387         /* cleanup helper macro */
388         .purgem scale_2_pixels
389         .unreq  DST
390         .unreq  SRC
391         .unreq  W
392         .unreq  VX
393         .unreq  UNIT_X
394         .unreq  TMP1
395         .unreq  TMP2
396         .unreq  VXMASK
397         /* return */
398         pop     {r4, r5, r6, r7}
399         bx      lr
400 .endfunc