linux-user: stack_base is now mandatory on all targets
[qemu.git] / hw / pxa2xx_template.h
1 /*
2 * Intel XScale PXA255/270 LCDC emulation.
3 *
4 * Copyright (c) 2006 Openedhand Ltd.
5 * Written by Andrzej Zaborowski <balrog@zabor.org>
6 *
7 * This code is licensed under the GPLv2.
8 *
9 * Framebuffer format conversion routines.
10 */
11
12 # define SKIP_PIXEL(to) to += deststep
13 #if BITS == 8
14 # define COPY_PIXEL(to, from) *to = from; SKIP_PIXEL(to)
15 #elif BITS == 15 || BITS == 16
16 # define COPY_PIXEL(to, from) *(uint16_t *) to = from; SKIP_PIXEL(to)
17 #elif BITS == 24
18 # define COPY_PIXEL(to, from) \
19 *(uint16_t *) to = from; *(to + 2) = (from) >> 16; SKIP_PIXEL(to)
20 #elif BITS == 32
21 # define COPY_PIXEL(to, from) *(uint32_t *) to = from; SKIP_PIXEL(to)
22 #else
23 # error unknown bit depth
24 #endif
25
26 #ifdef HOST_WORDS_BIGENDIAN
27 # define SWAP_WORDS 1
28 #endif
29
30 #define FN_2(x) FN(x + 1) FN(x)
31 #define FN_4(x) FN_2(x + 2) FN_2(x)
32
33 static void glue(pxa2xx_draw_line2_, BITS)(void *opaque,
34 uint8_t *dest, const uint8_t *src, int width, int deststep)
35 {
36 uint32_t *palette = opaque;
37 uint32_t data;
38 while (width > 0) {
39 data = *(uint32_t *) src;
40 #define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
41 #ifdef SWAP_WORDS
42 FN_4(12)
43 FN_4(8)
44 FN_4(4)
45 FN_4(0)
46 #else
47 FN_4(0)
48 FN_4(4)
49 FN_4(8)
50 FN_4(12)
51 #endif
52 #undef FN
53 width -= 16;
54 src += 4;
55 }
56 }
57
58 static void glue(pxa2xx_draw_line4_, BITS)(void *opaque,
59 uint8_t *dest, const uint8_t *src, int width, int deststep)
60 {
61 uint32_t *palette = opaque;
62 uint32_t data;
63 while (width > 0) {
64 data = *(uint32_t *) src;
65 #define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
66 #ifdef SWAP_WORDS
67 FN_2(6)
68 FN_2(4)
69 FN_2(2)
70 FN_2(0)
71 #else
72 FN_2(0)
73 FN_2(2)
74 FN_2(4)
75 FN_2(6)
76 #endif
77 #undef FN
78 width -= 8;
79 src += 4;
80 }
81 }
82
83 static void glue(pxa2xx_draw_line8_, BITS)(void *opaque,
84 uint8_t *dest, const uint8_t *src, int width, int deststep)
85 {
86 uint32_t *palette = opaque;
87 uint32_t data;
88 while (width > 0) {
89 data = *(uint32_t *) src;
90 #define FN(x) COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
91 #ifdef SWAP_WORDS
92 FN(24)
93 FN(16)
94 FN(8)
95 FN(0)
96 #else
97 FN(0)
98 FN(8)
99 FN(16)
100 FN(24)
101 #endif
102 #undef FN
103 width -= 4;
104 src += 4;
105 }
106 }
107
108 static void glue(pxa2xx_draw_line16_, BITS)(void *opaque,
109 uint8_t *dest, const uint8_t *src, int width, int deststep)
110 {
111 uint32_t data;
112 unsigned int r, g, b;
113 while (width > 0) {
114 data = *(uint32_t *) src;
115 #ifdef SWAP_WORDS
116 data = bswap32(data);
117 #endif
118 b = (data & 0x1f) << 3;
119 data >>= 5;
120 g = (data & 0x3f) << 2;
121 data >>= 6;
122 r = (data & 0x1f) << 3;
123 data >>= 5;
124 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
125 b = (data & 0x1f) << 3;
126 data >>= 5;
127 g = (data & 0x3f) << 2;
128 data >>= 6;
129 r = (data & 0x1f) << 3;
130 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
131 width -= 2;
132 src += 4;
133 }
134 }
135
136 static void glue(pxa2xx_draw_line16t_, BITS)(void *opaque,
137 uint8_t *dest, const uint8_t *src, int width, int deststep)
138 {
139 uint32_t data;
140 unsigned int r, g, b;
141 while (width > 0) {
142 data = *(uint32_t *) src;
143 #ifdef SWAP_WORDS
144 data = bswap32(data);
145 #endif
146 b = (data & 0x1f) << 3;
147 data >>= 5;
148 g = (data & 0x1f) << 3;
149 data >>= 5;
150 r = (data & 0x1f) << 3;
151 data >>= 5;
152 if (data & 1)
153 SKIP_PIXEL(dest);
154 else
155 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
156 data >>= 1;
157 b = (data & 0x1f) << 3;
158 data >>= 5;
159 g = (data & 0x1f) << 3;
160 data >>= 5;
161 r = (data & 0x1f) << 3;
162 data >>= 5;
163 if (data & 1)
164 SKIP_PIXEL(dest);
165 else
166 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
167 width -= 2;
168 src += 4;
169 }
170 }
171
172 static void glue(pxa2xx_draw_line18_, BITS)(void *opaque,
173 uint8_t *dest, const uint8_t *src, int width, int deststep)
174 {
175 uint32_t data;
176 unsigned int r, g, b;
177 while (width > 0) {
178 data = *(uint32_t *) src;
179 #ifdef SWAP_WORDS
180 data = bswap32(data);
181 #endif
182 b = (data & 0x3f) << 2;
183 data >>= 6;
184 g = (data & 0x3f) << 2;
185 data >>= 6;
186 r = (data & 0x3f) << 2;
187 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
188 width -= 1;
189 src += 4;
190 }
191 }
192
193 /* The wicked packed format */
194 static void glue(pxa2xx_draw_line18p_, BITS)(void *opaque,
195 uint8_t *dest, const uint8_t *src, int width, int deststep)
196 {
197 uint32_t data[3];
198 unsigned int r, g, b;
199 while (width > 0) {
200 data[0] = *(uint32_t *) src;
201 src += 4;
202 data[1] = *(uint32_t *) src;
203 src += 4;
204 data[2] = *(uint32_t *) src;
205 src += 4;
206 #ifdef SWAP_WORDS
207 data[0] = bswap32(data[0]);
208 data[1] = bswap32(data[1]);
209 data[2] = bswap32(data[2]);
210 #endif
211 b = (data[0] & 0x3f) << 2;
212 data[0] >>= 6;
213 g = (data[0] & 0x3f) << 2;
214 data[0] >>= 6;
215 r = (data[0] & 0x3f) << 2;
216 data[0] >>= 12;
217 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
218 b = (data[0] & 0x3f) << 2;
219 data[0] >>= 6;
220 g = ((data[1] & 0xf) << 4) | (data[0] << 2);
221 data[1] >>= 4;
222 r = (data[1] & 0x3f) << 2;
223 data[1] >>= 12;
224 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
225 b = (data[1] & 0x3f) << 2;
226 data[1] >>= 6;
227 g = (data[1] & 0x3f) << 2;
228 data[1] >>= 6;
229 r = ((data[2] & 0x3) << 6) | (data[1] << 2);
230 data[2] >>= 8;
231 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
232 b = (data[2] & 0x3f) << 2;
233 data[2] >>= 6;
234 g = (data[2] & 0x3f) << 2;
235 data[2] >>= 6;
236 r = data[2] << 2;
237 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
238 width -= 4;
239 }
240 }
241
242 static void glue(pxa2xx_draw_line19_, BITS)(void *opaque,
243 uint8_t *dest, const uint8_t *src, int width, int deststep)
244 {
245 uint32_t data;
246 unsigned int r, g, b;
247 while (width > 0) {
248 data = *(uint32_t *) src;
249 #ifdef SWAP_WORDS
250 data = bswap32(data);
251 #endif
252 b = (data & 0x3f) << 2;
253 data >>= 6;
254 g = (data & 0x3f) << 2;
255 data >>= 6;
256 r = (data & 0x3f) << 2;
257 data >>= 6;
258 if (data & 1)
259 SKIP_PIXEL(dest);
260 else
261 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
262 width -= 1;
263 src += 4;
264 }
265 }
266
267 /* The wicked packed format */
268 static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
269 uint8_t *dest, const uint8_t *src, int width, int deststep)
270 {
271 uint32_t data[3];
272 unsigned int r, g, b;
273 while (width > 0) {
274 data[0] = *(uint32_t *) src;
275 src += 4;
276 data[1] = *(uint32_t *) src;
277 src += 4;
278 data[2] = *(uint32_t *) src;
279 src += 4;
280 # ifdef SWAP_WORDS
281 data[0] = bswap32(data[0]);
282 data[1] = bswap32(data[1]);
283 data[2] = bswap32(data[2]);
284 # endif
285 b = (data[0] & 0x3f) << 2;
286 data[0] >>= 6;
287 g = (data[0] & 0x3f) << 2;
288 data[0] >>= 6;
289 r = (data[0] & 0x3f) << 2;
290 data[0] >>= 6;
291 if (data[0] & 1)
292 SKIP_PIXEL(dest);
293 else
294 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
295 data[0] >>= 6;
296 b = (data[0] & 0x3f) << 2;
297 data[0] >>= 6;
298 g = ((data[1] & 0xf) << 4) | (data[0] << 2);
299 data[1] >>= 4;
300 r = (data[1] & 0x3f) << 2;
301 data[1] >>= 6;
302 if (data[1] & 1)
303 SKIP_PIXEL(dest);
304 else
305 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
306 data[1] >>= 6;
307 b = (data[1] & 0x3f) << 2;
308 data[1] >>= 6;
309 g = (data[1] & 0x3f) << 2;
310 data[1] >>= 6;
311 r = ((data[2] & 0x3) << 6) | (data[1] << 2);
312 data[2] >>= 2;
313 if (data[2] & 1)
314 SKIP_PIXEL(dest);
315 else
316 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
317 data[2] >>= 6;
318 b = (data[2] & 0x3f) << 2;
319 data[2] >>= 6;
320 g = (data[2] & 0x3f) << 2;
321 data[2] >>= 6;
322 r = data[2] << 2;
323 data[2] >>= 6;
324 if (data[2] & 1)
325 SKIP_PIXEL(dest);
326 else
327 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
328 width -= 4;
329 }
330 }
331
332 static void glue(pxa2xx_draw_line24_, BITS)(void *opaque,
333 uint8_t *dest, const uint8_t *src, int width, int deststep)
334 {
335 uint32_t data;
336 unsigned int r, g, b;
337 while (width > 0) {
338 data = *(uint32_t *) src;
339 #ifdef SWAP_WORDS
340 data = bswap32(data);
341 #endif
342 b = data & 0xff;
343 data >>= 8;
344 g = data & 0xff;
345 data >>= 8;
346 r = data & 0xff;
347 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
348 width -= 1;
349 src += 4;
350 }
351 }
352
353 static void glue(pxa2xx_draw_line24t_, BITS)(void *opaque,
354 uint8_t *dest, const uint8_t *src, int width, int deststep)
355 {
356 uint32_t data;
357 unsigned int r, g, b;
358 while (width > 0) {
359 data = *(uint32_t *) src;
360 #ifdef SWAP_WORDS
361 data = bswap32(data);
362 #endif
363 b = (data & 0x7f) << 1;
364 data >>= 7;
365 g = data & 0xff;
366 data >>= 8;
367 r = data & 0xff;
368 data >>= 8;
369 if (data & 1)
370 SKIP_PIXEL(dest);
371 else
372 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
373 width -= 1;
374 src += 4;
375 }
376 }
377
378 static void glue(pxa2xx_draw_line25_, BITS)(void *opaque,
379 uint8_t *dest, const uint8_t *src, int width, int deststep)
380 {
381 uint32_t data;
382 unsigned int r, g, b;
383 while (width > 0) {
384 data = *(uint32_t *) src;
385 #ifdef SWAP_WORDS
386 data = bswap32(data);
387 #endif
388 b = data & 0xff;
389 data >>= 8;
390 g = data & 0xff;
391 data >>= 8;
392 r = data & 0xff;
393 data >>= 8;
394 if (data & 1)
395 SKIP_PIXEL(dest);
396 else
397 COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
398 width -= 1;
399 src += 4;
400 }
401 }
402
403 /* Overlay planes disabled, no transparency */
404 static drawfn glue(pxa2xx_draw_fn_, BITS)[16] =
405 {
406 [0 ... 0xf] = NULL,
407 [pxa_lcdc_2bpp] = glue(pxa2xx_draw_line2_, BITS),
408 [pxa_lcdc_4bpp] = glue(pxa2xx_draw_line4_, BITS),
409 [pxa_lcdc_8bpp] = glue(pxa2xx_draw_line8_, BITS),
410 [pxa_lcdc_16bpp] = glue(pxa2xx_draw_line16_, BITS),
411 [pxa_lcdc_18bpp] = glue(pxa2xx_draw_line18_, BITS),
412 [pxa_lcdc_18pbpp] = glue(pxa2xx_draw_line18p_, BITS),
413 [pxa_lcdc_24bpp] = glue(pxa2xx_draw_line24_, BITS),
414 };
415
416 /* Overlay planes enabled, transparency used */
417 static drawfn glue(glue(pxa2xx_draw_fn_, BITS), t)[16] =
418 {
419 [0 ... 0xf] = NULL,
420 [pxa_lcdc_4bpp] = glue(pxa2xx_draw_line4_, BITS),
421 [pxa_lcdc_8bpp] = glue(pxa2xx_draw_line8_, BITS),
422 [pxa_lcdc_16bpp] = glue(pxa2xx_draw_line16t_, BITS),
423 [pxa_lcdc_19bpp] = glue(pxa2xx_draw_line19_, BITS),
424 [pxa_lcdc_19pbpp] = glue(pxa2xx_draw_line19p_, BITS),
425 [pxa_lcdc_24bpp] = glue(pxa2xx_draw_line24t_, BITS),
426 [pxa_lcdc_25bpp] = glue(pxa2xx_draw_line25_, BITS),
427 };
428
429 #undef BITS
430 #undef COPY_PIXEL
431 #undef SKIP_PIXEL
432
433 #ifdef SWAP_WORDS
434 # undef SWAP_WORDS
435 #endif