651ab84243f63df94da8996b743a5d39a5d3bb51
[pcsx_rearmed.git] / frontend / cspace_neon.S
1 /*
2  * (C) GraÅžvydas "notaz" Ignotas, 2010
3  *
4  * This work is licensed under the terms of any of these licenses
5  * (at your option):
6  *  - GNU GPL, version 2 or later.
7  *  - GNU LGPL, version 2.1 or later.
8  * See the COPYING file in the top-level directory.
9  */
10
11 #include "arm_features.h"
12
13 /* sanity check */
14 #ifndef __ARM_NEON__
15 #error Compiling NEON code, but appropriate preprocessor flag is missing
16 #error This usually means -mfpu=neon or -mfloat-abi= is not correctly specified
17 #endif
18
19 .text
20 .align 2
21
22 FUNCTION(bgr555_to_rgb565): @ dst, src, bytes
23     pld         [r1]
24     mov         r3, #0x07c0
25     vdup.16     q15, r3
26     tst         r0, #8
27     beq         0f
28     @ align the dst
29     vld1.16     {d0}, [r1]!
30     vshl.u16    d0, d0, #1
31     vshl.u16    d1, d0, #10
32     vsri.u16    d1, d0, #11
33     vbit        d1, d0, d30
34     vst1.16     {d1}, [r0]!
35 0:
36     subs        r2, r2, #64
37     blt         btr16_end64
38 0:
39     pld         [r1, #64*2]
40     @ Pulls 15-bit BGR color values (which are actually 16 bits) into q0-q3.
41     @ example:  q0 = 0111 1110 0101 0011
42     vldmia      r1!, {q0-q3}
43     @ Shift BGR color 1 bit to the left, discarding MSB and preparing for vbit.
44     @ MSB is used for transparency (not needed here, and can mess with green).
45     @ example:  q0 = 1111 1100 1010 0110
46     vshl.u16    q0,  q0, #1
47     vshl.u16    q1,  q1, #1
48     vshl.u16    q2,  q2, #1
49     vshl.u16    q3,  q3, #1
50     @ Places red value in left most bits, clears bits to the right.
51     @ example:  q8 = 1001 1000 0000 0000
52     vshl.u16    q8,  q0, #10
53     vshl.u16    q9,  q1, #10
54     vshl.u16    q10, q2, #10
55     vshl.u16    q11, q3, #10
56     @ Places blue value in right most bits, leaving bits to the left unchanged.
57     @ example:  q8 = 1001 1000 0001 1111
58     vsri.u16    q8,  q0, #11
59     vsri.u16    q9,  q1, #11
60     vsri.u16    q10, q2, #11
61     vsri.u16    q11, q3, #11
62     @ Sets green value from shifted BGR color by apply a mask.
63     @ example: q15 = 0000 0111 1100 0000
64     @           q8 = 1001 1100 1001 1111
65     vbit        q8,  q0, q15
66     vbit        q9,  q1, q15
67     vbit        q10, q2, q15
68     vbit        q11, q3, q15
69     vstmia      r0!, {q8-q11}
70     subs        r2, r2, #64
71     bge         0b
72
73 btr16_end64:
74     adds        r2, r2, #64
75     bxeq        lr
76     subs        r2, r2, #16
77     blt         btr16_end16
78
79     @ handle the remainder (reasonably rare)
80 0:
81     vld1.16     {q0}, [r1]!
82     vshl.u16    q0, q0, #1
83     vshl.u16    q1, q0, #10
84     vsri.u16    q1, q0, #11
85     vbit        q1, q0, q15
86     subs        r2, r2, #16
87     vst1.16     {q1}, [r0]!
88     bge         0b
89
90 btr16_end16:
91     adds        r2, r2, #16
92     bxeq        lr
93     subs        r2, r2, #8
94     bxlt        lr
95
96     @ very rare
97     vld1.16     {d0}, [r1]!
98     vshl.u16    d0, d0, #1
99     vshl.u16    d1, d0, #10
100     vsri.u16    d1, d0, #11
101     vbit        d1, d0, d30
102     vst1.16     {d1}, [r0]!
103     bx          lr
104
105
106 @ note: may overflow source
107 FUNCTION(bgr555_to_rgb565_b): @ dst, src, bytes, int brightness2k // 0-0x0800
108     pld         [r1]
109     vdup.16     q15, r3
110     vpush       {q4-q7}
111     mov         r3, #0x1f
112     vdup.16     q14, r3
113 0:
114     pld         [r1, #64*2]
115     vldmia      r1!, {q0-q3}
116     vand.u16    q8,  q0, q14
117     vand.u16    q9,  q1, q14
118     vand.u16    q10, q2, q14
119     vand.u16    q11, q3, q14
120     vmul.u16    q4, q8,  q15
121     vmul.u16    q5, q9,  q15
122     vmul.u16    q6, q10, q15
123     vmul.u16    q7, q11, q15
124
125     vshr.u16    q8,  q0, #5
126     vshr.u16    q9,  q1, #5
127     vshr.u16    q10, q2, #5
128     vshr.u16    q11, q3, #5
129     vand.u16    q8,  q14
130     vand.u16    q9,  q14
131     vand.u16    q10, q14
132     vand.u16    q11, q14
133     vmul.u16    q8,  q15
134     vmul.u16    q9,  q15
135     vmul.u16    q10, q15
136     vmul.u16    q11, q15
137     vsri.u16    q4, q8,  #5
138     vsri.u16    q5, q9,  #5
139     vsri.u16    q6, q10, #5
140     vsri.u16    q7, q11, #5
141
142     vshr.u16    q8,  q0, #10
143     vshr.u16    q9,  q1, #10
144     vshr.u16    q10, q2, #10
145     vshr.u16    q11, q3, #10
146     vand.u16    q8,  q14
147     vand.u16    q9,  q14
148     vand.u16    q10, q14
149     vand.u16    q11, q14
150     vmul.u16    q8,  q15
151     vmul.u16    q9,  q15
152     vmul.u16    q10, q15
153     vmul.u16    q11, q15
154     vsri.u16    q4, q8,  #11
155     vsri.u16    q5, q9,  #11
156     vsri.u16    q6, q10, #11
157     vsri.u16    q7, q11, #11
158
159     subs        r2, r2, #64
160     ble         1f
161     vstmia      r0!, {q4-q7}
162     b           0b
163
164 1:
165     blt         0f
166     vstmia      r0!, {q4-q7}
167     b           btr16b_end
168 0:
169     subs        r2, r2, #8
170     blt         btr16b_end
171     vst1.16     {q4}, [r0]!
172     subs        r2, r2, #8
173     blt         btr16b_end
174     vst1.16     {q5}, [r0]!
175     subs        r2, r2, #8
176     blt         btr16b_end
177     vst1.16     {q6}, [r0]!
178     subs        r2, r2, #8
179     blt         btr16b_end
180     vst1.16     {q7}, [r0]!
181
182 btr16b_end:
183     vpop        {q4-q7}
184     bx          lr
185
186
187 FUNCTION(bgr888_to_rgb888): @ dst, src, bytes
188     pld         [r1]
189     @ r2 /= 48
190     mov         r2, r2, lsr #4
191     movw        r3, #0x5556
192     movt        r3, #0x5555
193     umull       r12,r2, r3, r2
194 0:
195     pld         [r1, #48*3]
196     vld3.8      {d0-d2}, [r1]!
197     vld3.8      {d3-d5}, [r1]!
198     vswp        d0, d2
199     vswp        d3, d5
200     vst3.8      {d0-d2}, [r0, :64]!
201     vst3.8      {d3-d5}, [r0, :64]!
202     subs        r2, r2, #1
203     bne         0b
204
205     bx          lr
206
207
208 FUNCTION(bgr888_to_rgb565): @ dst, src, bytes
209     pld         [r1]
210     @ r2 /= 48
211     mov         r2, r2, lsr #4
212     movw        r3, #0x5556
213     movt        r3, #0x5555
214     umull       r12,r2, r3, r2
215
216     mov         r3, #0x07e0
217     vdup.16     q15, r3
218 0:
219     pld         [r1, #48*3]
220     vld3.8      {d1-d3}, [r1]!
221     vld3.8      {d5-d7}, [r1]!
222
223     vshll.u8    q8, d2, #3      @ g
224     vshll.u8    q9, d6, #3
225     vshr.u8     d0, d3, #3      @ b
226     vshr.u8     d4, d7, #3
227     vzip.8      d0, d1          @ rb
228     vzip.8      d4, d5
229     vbit        q0, q8, q15
230     vbit        q2, q9, q15
231
232     vstmia      r0!, {d0,d1}
233     vstmia      r0!, {d4,d5}
234     subs        r2, r2, #1
235     bne         0b
236
237     bx          lr
238
239
240 FUNCTION(rgb888_to_rgb565): @ dst, src, bytes
241     pld         [r1]
242     @ r2 /= 48
243     mov         r2, r2, lsr #4
244     movw        r3, #0x5556
245     movt        r3, #0x5555
246     umull       r12,r2, r3, r2
247
248     mov         r3, #0x07e0
249     vdup.16     q15, r3
250 0:
251     pld         [r1, #48*3]
252     vld3.8      {d1-d3}, [r1, :64]!
253     vld3.8      {d5-d7}, [r1, :64]!
254
255     vshll.u8    q8, d2, #3      @ g
256     vshll.u8    q9, d6, #3
257     vshr.u8     d2, d1, #3      @ b
258     vshr.u8     d6, d5, #3
259     vzip.8      d2, d3          @ rb
260     vzip.8      d6, d7
261     vbit        q1, q8, q15
262     vbit        q3, q9, q15
263
264     vstmia      r0!, {d2,d3}
265     vstmia      r0!, {d6,d7}
266     subs        r2, r2, #1
267     bne         0b
268
269     bx          lr
270
271
272 @ vim:filetype=armasm