d57557c0 |
1 | /* |
2 | * (C) GraÅžvydas "notaz" Ignotas, 2013 |
3 | * |
4 | * This work is licensed under the terms of GNU GPL version 2 or later. |
5 | * See the COPYING file in the top-level directory. |
6 | */ |
7 | |
8 | #include "arm_features.h" |
9 | |
10 | .text |
11 | .align 2 |
12 | |
13 | @ lr=0x001f001f |
14 | @ trashes r11, r12 |
15 | .macro bgr555_to_rgb565_one rn |
16 | and r11, lr, \rn |
17 | and r12, lr, \rn, lsr #5 |
18 | and \rn, lr, \rn, lsr #10 |
19 | orr r12, r11, lsl #5 |
20 | orr \rn, r12, lsl #6 |
21 | .endm |
22 | |
8e6b6291 |
23 | .macro bgr555_to_rgb565_one_i rn1 rn2 |
24 | and r12, lr, \rn1, lsr #5 |
25 | and \rn1,lr, \rn1, lsr #10 |
26 | orr r12, r11, lsl #5 |
27 | and r11, lr, \rn2 |
28 | orr \rn1,r12, lsl #6 |
29 | .endm |
30 | |
d57557c0 |
31 | .macro pld_ reg offs=#0 |
32 | #ifdef HAVE_ARMV6 |
33 | pld [\reg, \offs] |
34 | #endif |
35 | .endm |
36 | |
5c6457c3 |
37 | FUNCTION(bgr555_to_rgb565): @ void *dst, const void *src, int bytes |
d57557c0 |
38 | push {r4-r11,lr} |
39 | mov lr, #0x001f |
40 | subs r2, #4*8 |
41 | orr lr, lr, lsl #16 |
42 | blt 1f |
43 | |
f189413e |
44 | @ src can be unaligned, but that's very rare, so just force it. |
45 | @ The manual says unaligned ldm should fault, and it does on |
46 | @ cortex-a78's 32bit mode, but curiously on cortex-a8 it just |
47 | @ works and loads the data correctly. |
48 | bic r1, r1, #3 |
49 | |
d57557c0 |
50 | 0: |
51 | ldmia r1!, {r3-r10} |
52 | subs r2, #4*8 |
8e6b6291 |
53 | bic r12, r1, #0x1f |
54 | pld_ r12, #32*1 |
55 | and r11, lr, r3 |
56 | bgr555_to_rgb565_one_i r3 r4 |
57 | bgr555_to_rgb565_one_i r4 r5 |
58 | bgr555_to_rgb565_one_i r5 r6 |
59 | bgr555_to_rgb565_one_i r6 r7 |
60 | bgr555_to_rgb565_one_i r7 r8 |
61 | bgr555_to_rgb565_one_i r8 r9 |
62 | bgr555_to_rgb565_one_i r9 r10 |
63 | bgr555_to_rgb565_one_i r10 r10 |
d57557c0 |
64 | stmia r0!, {r3-r10} |
65 | bge 0b |
66 | |
67 | 1: |
68 | adds r2, #4*8 |
69 | popeq {r4-r11,pc} |
70 | |
71 | 2: |
72 | ldr r3, [r1], #4 |
73 | subs r2, #4 |
74 | bgr555_to_rgb565_one r3 |
75 | str r3, [r0], #4 |
76 | bgt 2b |
77 | |
78 | pop {r4-r11,pc} |
b06f78f1 |
79 | |
80 | |
81 | #ifdef HAVE_ARMV6 /* v6-only due to potential misaligned reads */ |
82 | |
83 | # r1b0g0r0 g2r2b1g1 b3g3r3b2 |
84 | FUNCTION(bgr888_to_rgb565): |
85 | pld [r1] |
86 | push {r4-r10,lr} |
87 | |
88 | mov r10, #0x001f @ b mask |
89 | mov r12, #0x07e0 @ g mask |
90 | mov lr, #0xf800 @ r mask |
91 | |
92 | 0: |
93 | ldr r3, [r1], #4 @ may be unaligned |
94 | ldr r4, [r1], #4 |
95 | ldr r5, [r1], #4 |
96 | pld [r1, #32*1] |
97 | and r6, r10,r3, lsr #16+3 @ b0 |
98 | and r7, r12,r3, lsr #5 @ g0 |
99 | and r8, lr, r3, lsl #8 @ r0 |
100 | and r9, lr, r3, lsr #16 @ r1 |
101 | orr r6, r6, r7 |
102 | orr r6, r6, r8 @ r0g0b0 |
103 | |
104 | and r7, r12,r4, lsl #3 @ g1 |
105 | and r8, r10,r4, lsr #11 @ b1 |
106 | orr r9, r9, r7 |
107 | orr r9, r9, r8 @ r1g1b1 |
108 | and r7, lr, r4, lsr #8 @ r2 |
109 | and r8, r12,r4, lsr #21 @ g2 |
110 | pkhbt r9, r6, r9, lsl #16 |
111 | str r9, [r0], #4 |
112 | |
113 | and r6, r10,r5, lsr #3 @ b2 |
114 | orr r7, r7, r8 |
115 | orr r6, r6, r7 @ r2g2b2 |
116 | and r7, lr, r5 @ r3 |
117 | and r8, r12,r5, lsr #13 @ g3 |
118 | orr r7, r7, r5, lsr #27 @ r3b3 |
119 | orr r7, r7, r8 @ r3g3b3 |
120 | pkhbt r7, r6, r7, lsl #16 |
121 | str r7, [r0], #4 |
122 | subs r2, r2, #12 |
123 | bgt 0b |
124 | |
125 | pop {r4-r10,pc} |
126 | |
127 | #endif /* HAVE_ARMV6 */ |