1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2f7018c21STomi Valkeinen #ifndef _VIDEO_ATAFB_UTILS_H
3f7018c21STomi Valkeinen #define _VIDEO_ATAFB_UTILS_H
4f7018c21STomi Valkeinen 
5f7018c21STomi Valkeinen /* ================================================================= */
6f7018c21STomi Valkeinen /*                      Utility Assembler Functions                  */
7f7018c21STomi Valkeinen /* ================================================================= */
8f7018c21STomi Valkeinen 
9f7018c21STomi Valkeinen /* ====================================================================== */
10f7018c21STomi Valkeinen 
11f7018c21STomi Valkeinen /* Those of a delicate disposition might like to skip the next couple of
12f7018c21STomi Valkeinen  * pages.
13f7018c21STomi Valkeinen  *
14f7018c21STomi Valkeinen  * These functions are drop in replacements for memmove and
15f7018c21STomi Valkeinen  * memset(_, 0, _). However their five instances add at least a kilobyte
16f7018c21STomi Valkeinen  * to the object file. You have been warned.
17f7018c21STomi Valkeinen  *
18f7018c21STomi Valkeinen  * Not a great fan of assembler for the sake of it, but I think
19f7018c21STomi Valkeinen  * that these routines are at least 10 times faster than their C
20f7018c21STomi Valkeinen  * equivalents for large blits, and that's important to the lowest level of
21f7018c21STomi Valkeinen  * a graphics driver. Question is whether some scheme with the blitter
22f7018c21STomi Valkeinen  * would be faster. I suspect not for simple text system - not much
23f7018c21STomi Valkeinen  * asynchrony.
24f7018c21STomi Valkeinen  *
25f7018c21STomi Valkeinen  * Code is very simple, just gruesome expansion. Basic strategy is to
26f7018c21STomi Valkeinen  * increase data moved/cleared at each step to 16 bytes to reduce
27f7018c21STomi Valkeinen  * instruction per data move overhead. movem might be faster still
28f7018c21STomi Valkeinen  * For more than 15 bytes, we try to align the write direction on a
29f7018c21STomi Valkeinen  * longword boundary to get maximum speed. This is even more gruesome.
30f7018c21STomi Valkeinen  * Unaligned read/write used requires 68020+ - think this is a problem?
31f7018c21STomi Valkeinen  *
32f7018c21STomi Valkeinen  * Sorry!
33f7018c21STomi Valkeinen  */
34f7018c21STomi Valkeinen 
35f7018c21STomi Valkeinen 
36f7018c21STomi Valkeinen /* ++roman: I've optimized Robert's original versions in some minor
37f7018c21STomi Valkeinen  * aspects, e.g. moveq instead of movel, let gcc choose the registers,
38f7018c21STomi Valkeinen  * use movem in some places...
39f7018c21STomi Valkeinen  * For other modes than 1 plane, lots of more such assembler functions
40f7018c21STomi Valkeinen  * were needed (e.g. the ones using movep or expanding color values).
41f7018c21STomi Valkeinen  */
42f7018c21STomi Valkeinen 
43f7018c21STomi Valkeinen /* ++andreas: more optimizations:
44f7018c21STomi Valkeinen    subl #65536,d0 replaced by clrw d0; subql #1,d0 for dbcc
45f7018c21STomi Valkeinen    addal is faster than addaw
46f7018c21STomi Valkeinen    movep is rather expensive compared to ordinary move's
47f7018c21STomi Valkeinen    some functions rewritten in C for clarity, no speed loss */
48f7018c21STomi Valkeinen 
fb_memclear_small(void * s,size_t count)49f7018c21STomi Valkeinen static inline void *fb_memclear_small(void *s, size_t count)
50f7018c21STomi Valkeinen {
51f7018c21STomi Valkeinen 	if (!count)
52f7018c21STomi Valkeinen 		return 0;
53f7018c21STomi Valkeinen 
54f7018c21STomi Valkeinen 	asm volatile ("\n"
55f7018c21STomi Valkeinen 		"	lsr.l	#1,%1 ; jcc 1f ; move.b %2,-(%0)\n"
56f7018c21STomi Valkeinen 		"1:	lsr.l	#1,%1 ; jcc 1f ; move.w %2,-(%0)\n"
57f7018c21STomi Valkeinen 		"1:	lsr.l	#1,%1 ; jcc 1f ; move.l %2,-(%0)\n"
58f7018c21STomi Valkeinen 		"1:	lsr.l	#1,%1 ; jcc 1f ; move.l %2,-(%0) ; move.l %2,-(%0)\n"
59f7018c21STomi Valkeinen 		"1:"
60f7018c21STomi Valkeinen 		: "=a" (s), "=d" (count)
61f7018c21STomi Valkeinen 		: "d" (0), "0" ((char *)s + count), "1" (count));
62f7018c21STomi Valkeinen 	asm volatile ("\n"
63f7018c21STomi Valkeinen 		"	subq.l  #1,%1\n"
64f7018c21STomi Valkeinen 		"	jcs	3f\n"
65f7018c21STomi Valkeinen 		"	move.l	%2,%%d4; move.l %2,%%d5; move.l %2,%%d6\n"
66f7018c21STomi Valkeinen 		"2:	movem.l	%2/%%d4/%%d5/%%d6,-(%0)\n"
67f7018c21STomi Valkeinen 		"	dbra	%1,2b\n"
68f7018c21STomi Valkeinen 		"3:"
69f7018c21STomi Valkeinen 		: "=a" (s), "=d" (count)
70f7018c21STomi Valkeinen 		: "d" (0), "0" (s), "1" (count)
71f7018c21STomi Valkeinen 		: "d4", "d5", "d6"
72f7018c21STomi Valkeinen 		);
73f7018c21STomi Valkeinen 
74f7018c21STomi Valkeinen 	return 0;
75f7018c21STomi Valkeinen }
76f7018c21STomi Valkeinen 
77f7018c21STomi Valkeinen 
fb_memclear(void * s,size_t count)78f7018c21STomi Valkeinen static inline void *fb_memclear(void *s, size_t count)
79f7018c21STomi Valkeinen {
80f7018c21STomi Valkeinen 	if (!count)
81f7018c21STomi Valkeinen 		return 0;
82f7018c21STomi Valkeinen 
83f7018c21STomi Valkeinen 	if (count < 16) {
84f7018c21STomi Valkeinen 		asm volatile ("\n"
85f7018c21STomi Valkeinen 			"	lsr.l	#1,%1 ; jcc 1f ; clr.b (%0)+\n"
86f7018c21STomi Valkeinen 			"1:	lsr.l	#1,%1 ; jcc 1f ; clr.w (%0)+\n"
87f7018c21STomi Valkeinen 			"1:	lsr.l	#1,%1 ; jcc 1f ; clr.l (%0)+\n"
88f7018c21STomi Valkeinen 			"1:	lsr.l	#1,%1 ; jcc 1f ; clr.l (%0)+ ; clr.l (%0)+\n"
89f7018c21STomi Valkeinen 			"1:"
90f7018c21STomi Valkeinen 			: "=a" (s), "=d" (count)
91f7018c21STomi Valkeinen 			: "0" (s), "1" (count));
92f7018c21STomi Valkeinen 	} else {
93f7018c21STomi Valkeinen 		long tmp;
94f7018c21STomi Valkeinen 		asm volatile ("\n"
95f7018c21STomi Valkeinen 			"	move.l	%1,%2\n"
96f7018c21STomi Valkeinen 			"	lsr.l	#1,%2 ; jcc 1f ; clr.b (%0)+ ; subq.w #1,%1\n"
97f7018c21STomi Valkeinen 			"	lsr.l	#1,%2 ; jcs 2f\n"  /* %0 increased=>bit 2 switched*/
98f7018c21STomi Valkeinen 			"	clr.w	(%0)+  ; subq.w  #2,%1 ; jra 2f\n"
99f7018c21STomi Valkeinen 			"1:	lsr.l	#1,%2 ; jcc 2f\n"
100f7018c21STomi Valkeinen 			"	clr.w	(%0)+  ; subq.w  #2,%1\n"
101f7018c21STomi Valkeinen 			"2:	move.w	%1,%2; lsr.l #2,%1 ; jeq 6f\n"
102f7018c21STomi Valkeinen 			"	lsr.l	#1,%1 ; jcc 3f ; clr.l (%0)+\n"
103f7018c21STomi Valkeinen 			"3:	lsr.l	#1,%1 ; jcc 4f ; clr.l (%0)+ ; clr.l (%0)+\n"
104f7018c21STomi Valkeinen 			"4:	subq.l	#1,%1 ; jcs 6f\n"
105f7018c21STomi Valkeinen 			"5:	clr.l	(%0)+; clr.l (%0)+ ; clr.l (%0)+ ; clr.l (%0)+\n"
106f7018c21STomi Valkeinen 			"	dbra	%1,5b ; clr.w %1; subq.l #1,%1; jcc 5b\n"
107f7018c21STomi Valkeinen 			"6:	move.w	%2,%1; btst #1,%1 ; jeq 7f ; clr.w (%0)+\n"
108f7018c21STomi Valkeinen 			"7:	btst	#0,%1 ; jeq 8f ; clr.b (%0)+\n"
109f7018c21STomi Valkeinen 			"8:"
110f7018c21STomi Valkeinen 			: "=a" (s), "=d" (count), "=d" (tmp)
111f7018c21STomi Valkeinen 			: "0" (s), "1" (count));
112f7018c21STomi Valkeinen 	}
113f7018c21STomi Valkeinen 
114f7018c21STomi Valkeinen 	return 0;
115f7018c21STomi Valkeinen }
116f7018c21STomi Valkeinen 
117f7018c21STomi Valkeinen 
fb_memset255(void * s,size_t count)118f7018c21STomi Valkeinen static inline void *fb_memset255(void *s, size_t count)
119f7018c21STomi Valkeinen {
120f7018c21STomi Valkeinen 	if (!count)
121f7018c21STomi Valkeinen 		return 0;
122f7018c21STomi Valkeinen 
123f7018c21STomi Valkeinen 	asm volatile ("\n"
124f7018c21STomi Valkeinen 		"	lsr.l	#1,%1 ; jcc 1f ; move.b %2,-(%0)\n"
125f7018c21STomi Valkeinen 		"1:	lsr.l	#1,%1 ; jcc 1f ; move.w %2,-(%0)\n"
126f7018c21STomi Valkeinen 		"1:	lsr.l	#1,%1 ; jcc 1f ; move.l %2,-(%0)\n"
127f7018c21STomi Valkeinen 		"1:	lsr.l	#1,%1 ; jcc 1f ; move.l %2,-(%0) ; move.l %2,-(%0)\n"
128f7018c21STomi Valkeinen 		"1:"
129f7018c21STomi Valkeinen 		: "=a" (s), "=d" (count)
130f7018c21STomi Valkeinen 		: "d" (-1), "0" ((char *)s+count), "1" (count));
131f7018c21STomi Valkeinen 	asm volatile ("\n"
132f7018c21STomi Valkeinen 		"	subq.l	#1,%1 ; jcs 3f\n"
133f7018c21STomi Valkeinen 		"	move.l	%2,%%d4; move.l %2,%%d5; move.l %2,%%d6\n"
134f7018c21STomi Valkeinen 		"2:	movem.l	%2/%%d4/%%d5/%%d6,-(%0)\n"
135f7018c21STomi Valkeinen 		"	dbra	%1,2b\n"
136f7018c21STomi Valkeinen 		"3:"
137f7018c21STomi Valkeinen 		: "=a" (s), "=d" (count)
138f7018c21STomi Valkeinen 		: "d" (-1), "0" (s), "1" (count)
139f7018c21STomi Valkeinen 		: "d4", "d5", "d6");
140f7018c21STomi Valkeinen 
141f7018c21STomi Valkeinen 	return 0;
142f7018c21STomi Valkeinen }
143f7018c21STomi Valkeinen 
144f7018c21STomi Valkeinen 
fb_memmove(void * d,const void * s,size_t count)145f7018c21STomi Valkeinen static inline void *fb_memmove(void *d, const void *s, size_t count)
146f7018c21STomi Valkeinen {
147f7018c21STomi Valkeinen 	if (d < s) {
148f7018c21STomi Valkeinen 		if (count < 16) {
149f7018c21STomi Valkeinen 			asm volatile ("\n"
150f7018c21STomi Valkeinen 				"	lsr.l	#1,%2 ; jcc 1f ; move.b (%1)+,(%0)+\n"
151f7018c21STomi Valkeinen 				"1:	lsr.l	#1,%2 ; jcc 1f ; move.w (%1)+,(%0)+\n"
152f7018c21STomi Valkeinen 				"1:	lsr.l	#1,%2 ; jcc 1f ; move.l (%1)+,(%0)+\n"
153f7018c21STomi Valkeinen 				"1:	lsr.l	#1,%2 ; jcc 1f ; move.l (%1)+,(%0)+ ; move.l (%1)+,(%0)+\n"
154f7018c21STomi Valkeinen 				"1:"
155f7018c21STomi Valkeinen 				: "=a" (d), "=a" (s), "=d" (count)
156f7018c21STomi Valkeinen 				: "0" (d), "1" (s), "2" (count));
157f7018c21STomi Valkeinen 		} else {
158f7018c21STomi Valkeinen 			long tmp;
159f7018c21STomi Valkeinen 			asm volatile ("\n"
160f7018c21STomi Valkeinen 				"	move.l	%0,%3\n"
161f7018c21STomi Valkeinen 				"	lsr.l	#1,%3 ; jcc 1f ; move.b (%1)+,(%0)+ ; subqw #1,%2\n"
162f7018c21STomi Valkeinen 				"	lsr.l	#1,%3 ; jcs 2f\n"  /* %0 increased=>bit 2 switched*/
163f7018c21STomi Valkeinen 				"	move.w	(%1)+,(%0)+  ; subqw  #2,%2 ; jra 2f\n"
164f7018c21STomi Valkeinen 				"1:	lsr.l   #1,%3 ; jcc 2f\n"
165f7018c21STomi Valkeinen 				"	move.w	(%1)+,(%0)+  ; subqw  #2,%2\n"
166f7018c21STomi Valkeinen 				"2:	move.w	%2,%-; lsr.l #2,%2 ; jeq 6f\n"
167f7018c21STomi Valkeinen 				"	lsr.l	#1,%2 ; jcc 3f ; move.l (%1)+,(%0)+\n"
168f7018c21STomi Valkeinen 				"3:	lsr.l	#1,%2 ; jcc 4f ; move.l (%1)+,(%0)+ ; move.l (%1)+,(%0)+\n"
169f7018c21STomi Valkeinen 				"4:	subq.l	#1,%2 ; jcs 6f\n"
170f7018c21STomi Valkeinen 				"5:	move.l	(%1)+,(%0)+; move.l (%1)+,(%0)+\n"
171f7018c21STomi Valkeinen 				"	move.l	(%1)+,(%0)+; move.l (%1)+,(%0)+\n"
172f7018c21STomi Valkeinen 				"	dbra	%2,5b ; clr.w %2; subq.l #1,%2; jcc 5b\n"
173f7018c21STomi Valkeinen 				"6:	move.w	%+,%2; btst #1,%2 ; jeq 7f ; move.w (%1)+,(%0)+\n"
174f7018c21STomi Valkeinen 				"7:	btst	#0,%2 ; jeq 8f ; move.b (%1)+,(%0)+\n"
175f7018c21STomi Valkeinen 				"8:"
176f7018c21STomi Valkeinen 				: "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
177f7018c21STomi Valkeinen 				: "0" (d), "1" (s), "2" (count));
178f7018c21STomi Valkeinen 		}
179f7018c21STomi Valkeinen 	} else {
180f7018c21STomi Valkeinen 		if (count < 16) {
181f7018c21STomi Valkeinen 			asm volatile ("\n"
182f7018c21STomi Valkeinen 				"	lsr.l	#1,%2 ; jcc 1f ; move.b -(%1),-(%0)\n"
183f7018c21STomi Valkeinen 				"1:	lsr.l	#1,%2 ; jcc 1f ; move.w -(%1),-(%0)\n"
184f7018c21STomi Valkeinen 				"1:	lsr.l	#1,%2 ; jcc 1f ; move.l -(%1),-(%0)\n"
185f7018c21STomi Valkeinen 				"1:	lsr.l	#1,%2 ; jcc 1f ; move.l -(%1),-(%0) ; move.l -(%1),-(%0)\n"
186f7018c21STomi Valkeinen 				"1:"
187f7018c21STomi Valkeinen 				: "=a" (d), "=a" (s), "=d" (count)
188f7018c21STomi Valkeinen 				: "0" ((char *) d + count), "1" ((char *) s + count), "2" (count));
189f7018c21STomi Valkeinen 		} else {
190f7018c21STomi Valkeinen 			long tmp;
191f7018c21STomi Valkeinen 
192f7018c21STomi Valkeinen 			asm volatile ("\n"
193f7018c21STomi Valkeinen 				"	move.l	%0,%3\n"
194f7018c21STomi Valkeinen 				"	lsr.l	#1,%3 ; jcc 1f ; move.b -(%1),-(%0) ; subqw #1,%2\n"
195f7018c21STomi Valkeinen 				"	lsr.l	#1,%3 ; jcs 2f\n"  /* %0 increased=>bit 2 switched*/
196f7018c21STomi Valkeinen 				"	move.w	-(%1),-(%0) ; subqw  #2,%2 ; jra 2f\n"
197f7018c21STomi Valkeinen 				"1:	lsr.l	#1,%3 ; jcc 2f\n"
198f7018c21STomi Valkeinen 				"	move.w	-(%1),-(%0) ; subqw  #2,%2\n"
199f7018c21STomi Valkeinen 				"2:	move.w	%2,%-; lsr.l #2,%2 ; jeq 6f\n"
200f7018c21STomi Valkeinen 				"	lsr.l	#1,%2 ; jcc 3f ; move.l -(%1),-(%0)\n"
201f7018c21STomi Valkeinen 				"3:	lsr.l	#1,%2 ; jcc 4f ; move.l -(%1),-(%0) ; move.l -(%1),-(%0)\n"
202f7018c21STomi Valkeinen 				"4:	subq.l	#1,%2 ; jcs 6f\n"
203f7018c21STomi Valkeinen 				"5:	move.l	-(%1),-(%0); move.l -(%1),-(%0)\n"
204f7018c21STomi Valkeinen 				"	move.l	-(%1),-(%0); move.l -(%1),-(%0)\n"
205f7018c21STomi Valkeinen 				"	dbra	%2,5b ; clr.w %2; subq.l #1,%2; jcc 5b\n"
206f7018c21STomi Valkeinen 				"6:	move.w	%+,%2; btst #1,%2 ; jeq 7f ; move.w -(%1),-(%0)\n"
207f7018c21STomi Valkeinen 				"7:	btst	#0,%2 ; jeq 8f ; move.b -(%1),-(%0)\n"
208f7018c21STomi Valkeinen 				"8:"
209f7018c21STomi Valkeinen 				: "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
210f7018c21STomi Valkeinen 				: "0" ((char *) d + count), "1" ((char *) s + count), "2" (count));
211f7018c21STomi Valkeinen 		}
212f7018c21STomi Valkeinen 	}
213f7018c21STomi Valkeinen 
214f7018c21STomi Valkeinen 	return 0;
215f7018c21STomi Valkeinen }
216f7018c21STomi Valkeinen 
217f7018c21STomi Valkeinen 
218f7018c21STomi Valkeinen /* ++andreas: Simple and fast version of memmove, assumes size is
219f7018c21STomi Valkeinen    divisible by 16, suitable for moving the whole screen bitplane */
fast_memmove(char * dst,const char * src,size_t size)220f7018c21STomi Valkeinen static inline void fast_memmove(char *dst, const char *src, size_t size)
221f7018c21STomi Valkeinen {
222f7018c21STomi Valkeinen 	if (!size)
223f7018c21STomi Valkeinen 		return;
224f7018c21STomi Valkeinen 	if (dst < src)
225f7018c21STomi Valkeinen 		asm volatile ("\n"
226f7018c21STomi Valkeinen 			"1:	movem.l	(%0)+,%%d0/%%d1/%%a0/%%a1\n"
227f7018c21STomi Valkeinen 			"	movem.l	%%d0/%%d1/%%a0/%%a1,%1@\n"
228f7018c21STomi Valkeinen 			"	addq.l	#8,%1; addq.l #8,%1\n"
229f7018c21STomi Valkeinen 			"	dbra	%2,1b\n"
230f7018c21STomi Valkeinen 			"	clr.w	%2; subq.l #1,%2\n"
231f7018c21STomi Valkeinen 			"	jcc	1b"
232f7018c21STomi Valkeinen 			: "=a" (src), "=a" (dst), "=d" (size)
233f7018c21STomi Valkeinen 			: "0" (src), "1" (dst), "2" (size / 16 - 1)
234f7018c21STomi Valkeinen 			: "d0", "d1", "a0", "a1", "memory");
235f7018c21STomi Valkeinen 	else
236f7018c21STomi Valkeinen 		asm volatile ("\n"
237f7018c21STomi Valkeinen 			"1:	subq.l	#8,%0; subq.l #8,%0\n"
238f7018c21STomi Valkeinen 			"	movem.l	%0@,%%d0/%%d1/%%a0/%%a1\n"
239f7018c21STomi Valkeinen 			"	movem.l	%%d0/%%d1/%%a0/%%a1,-(%1)\n"
240f7018c21STomi Valkeinen 			"	dbra	%2,1b\n"
241f7018c21STomi Valkeinen 			"	clr.w	%2; subq.l #1,%2\n"
242f7018c21STomi Valkeinen 			"	jcc 1b"
243f7018c21STomi Valkeinen 			: "=a" (src), "=a" (dst), "=d" (size)
244f7018c21STomi Valkeinen 			: "0" (src + size), "1" (dst + size), "2" (size / 16 - 1)
245f7018c21STomi Valkeinen 			: "d0", "d1", "a0", "a1", "memory");
246f7018c21STomi Valkeinen }
247f7018c21STomi Valkeinen 
248f7018c21STomi Valkeinen #ifdef BPL
249f7018c21STomi Valkeinen 
250f7018c21STomi Valkeinen /*
251f7018c21STomi Valkeinen  * This expands a up to 8 bit color into two longs
252f7018c21STomi Valkeinen  * for movel operations.
253f7018c21STomi Valkeinen  */
254f7018c21STomi Valkeinen static const u32 four2long[] = {
255f7018c21STomi Valkeinen 	0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
256f7018c21STomi Valkeinen 	0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
257f7018c21STomi Valkeinen 	0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
258f7018c21STomi Valkeinen 	0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff,
259f7018c21STomi Valkeinen };
260f7018c21STomi Valkeinen 
expand8_col2mask(u8 c,u32 m[])261f7018c21STomi Valkeinen static inline void expand8_col2mask(u8 c, u32 m[])
262f7018c21STomi Valkeinen {
263f7018c21STomi Valkeinen 	m[0] = four2long[c & 15];
264f7018c21STomi Valkeinen #if BPL > 4
265f7018c21STomi Valkeinen 	m[1] = four2long[c >> 4];
266f7018c21STomi Valkeinen #endif
267f7018c21STomi Valkeinen }
268f7018c21STomi Valkeinen 
expand8_2col2mask(u8 fg,u8 bg,u32 fgm[],u32 bgm[])269f7018c21STomi Valkeinen static inline void expand8_2col2mask(u8 fg, u8 bg, u32 fgm[], u32 bgm[])
270f7018c21STomi Valkeinen {
271f7018c21STomi Valkeinen 	fgm[0] = four2long[fg & 15] ^ (bgm[0] = four2long[bg & 15]);
272f7018c21STomi Valkeinen #if BPL > 4
273f7018c21STomi Valkeinen 	fgm[1] = four2long[fg >> 4] ^ (bgm[1] = four2long[bg >> 4]);
274f7018c21STomi Valkeinen #endif
275f7018c21STomi Valkeinen }
276f7018c21STomi Valkeinen 
277f7018c21STomi Valkeinen /*
278f7018c21STomi Valkeinen  * set an 8bit value to a color
279f7018c21STomi Valkeinen  */
fill8_col(u8 * dst,u32 m[])280f7018c21STomi Valkeinen static inline void fill8_col(u8 *dst, u32 m[])
281f7018c21STomi Valkeinen {
282f7018c21STomi Valkeinen 	u32 tmp = m[0];
283f7018c21STomi Valkeinen 	dst[0] = tmp;
284f7018c21STomi Valkeinen 	dst[2] = (tmp >>= 8);
285f7018c21STomi Valkeinen #if BPL > 2
286f7018c21STomi Valkeinen 	dst[4] = (tmp >>= 8);
287f7018c21STomi Valkeinen 	dst[6] = tmp >> 8;
288f7018c21STomi Valkeinen #endif
289f7018c21STomi Valkeinen #if BPL > 4
290f7018c21STomi Valkeinen 	tmp = m[1];
291f7018c21STomi Valkeinen 	dst[8] = tmp;
292f7018c21STomi Valkeinen 	dst[10] = (tmp >>= 8);
293f7018c21STomi Valkeinen 	dst[12] = (tmp >>= 8);
294f7018c21STomi Valkeinen 	dst[14] = tmp >> 8;
295f7018c21STomi Valkeinen #endif
296f7018c21STomi Valkeinen }
297f7018c21STomi Valkeinen 
298f7018c21STomi Valkeinen /*
299f7018c21STomi Valkeinen  * set an 8bit value according to foreground/background color
300f7018c21STomi Valkeinen  */
fill8_2col(u8 * dst,u8 fg,u8 bg,u32 mask)301f7018c21STomi Valkeinen static inline void fill8_2col(u8 *dst, u8 fg, u8 bg, u32 mask)
302f7018c21STomi Valkeinen {
303f7018c21STomi Valkeinen 	u32 fgm[2], bgm[2], tmp;
304f7018c21STomi Valkeinen 
305f7018c21STomi Valkeinen 	expand8_2col2mask(fg, bg, fgm, bgm);
306f7018c21STomi Valkeinen 
307f7018c21STomi Valkeinen 	mask |= mask << 8;
308f7018c21STomi Valkeinen #if BPL > 2
309f7018c21STomi Valkeinen 	mask |= mask << 16;
310f7018c21STomi Valkeinen #endif
311f7018c21STomi Valkeinen 	tmp = (mask & fgm[0]) ^ bgm[0];
312f7018c21STomi Valkeinen 	dst[0] = tmp;
313f7018c21STomi Valkeinen 	dst[2] = (tmp >>= 8);
314f7018c21STomi Valkeinen #if BPL > 2
315f7018c21STomi Valkeinen 	dst[4] = (tmp >>= 8);
316f7018c21STomi Valkeinen 	dst[6] = tmp >> 8;
317f7018c21STomi Valkeinen #endif
318f7018c21STomi Valkeinen #if BPL > 4
319f7018c21STomi Valkeinen 	tmp = (mask & fgm[1]) ^ bgm[1];
320f7018c21STomi Valkeinen 	dst[8] = tmp;
321f7018c21STomi Valkeinen 	dst[10] = (tmp >>= 8);
322f7018c21STomi Valkeinen 	dst[12] = (tmp >>= 8);
323f7018c21STomi Valkeinen 	dst[14] = tmp >> 8;
324f7018c21STomi Valkeinen #endif
325f7018c21STomi Valkeinen }
326f7018c21STomi Valkeinen 
327f7018c21STomi Valkeinen static const u32 two2word[] = {
328f7018c21STomi Valkeinen 	0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
329f7018c21STomi Valkeinen };
330f7018c21STomi Valkeinen 
expand16_col2mask(u8 c,u32 m[])331f7018c21STomi Valkeinen static inline void expand16_col2mask(u8 c, u32 m[])
332f7018c21STomi Valkeinen {
333f7018c21STomi Valkeinen 	m[0] = two2word[c & 3];
334f7018c21STomi Valkeinen #if BPL > 2
335f7018c21STomi Valkeinen 	m[1] = two2word[(c >> 2) & 3];
336f7018c21STomi Valkeinen #endif
337f7018c21STomi Valkeinen #if BPL > 4
338f7018c21STomi Valkeinen 	m[2] = two2word[(c >> 4) & 3];
339f7018c21STomi Valkeinen 	m[3] = two2word[c >> 6];
340f7018c21STomi Valkeinen #endif
341f7018c21STomi Valkeinen }
342f7018c21STomi Valkeinen 
expand16_2col2mask(u8 fg,u8 bg,u32 fgm[],u32 bgm[])343f7018c21STomi Valkeinen static inline void expand16_2col2mask(u8 fg, u8 bg, u32 fgm[], u32 bgm[])
344f7018c21STomi Valkeinen {
345f7018c21STomi Valkeinen 	bgm[0] = two2word[bg & 3];
346f7018c21STomi Valkeinen 	fgm[0] = two2word[fg & 3] ^ bgm[0];
347f7018c21STomi Valkeinen #if BPL > 2
348f7018c21STomi Valkeinen 	bgm[1] = two2word[(bg >> 2) & 3];
349f7018c21STomi Valkeinen 	fgm[1] = two2word[(fg >> 2) & 3] ^ bgm[1];
350f7018c21STomi Valkeinen #endif
351f7018c21STomi Valkeinen #if BPL > 4
352f7018c21STomi Valkeinen 	bgm[2] = two2word[(bg >> 4) & 3];
353f7018c21STomi Valkeinen 	fgm[2] = two2word[(fg >> 4) & 3] ^ bgm[2];
354f7018c21STomi Valkeinen 	bgm[3] = two2word[bg >> 6];
355f7018c21STomi Valkeinen 	fgm[3] = two2word[fg >> 6] ^ bgm[3];
356f7018c21STomi Valkeinen #endif
357f7018c21STomi Valkeinen }
358f7018c21STomi Valkeinen 
fill16_col(u32 * dst,int rows,u32 m[])359f7018c21STomi Valkeinen static inline u32 *fill16_col(u32 *dst, int rows, u32 m[])
360f7018c21STomi Valkeinen {
361f7018c21STomi Valkeinen 	while (rows) {
362f7018c21STomi Valkeinen 		*dst++ = m[0];
363f7018c21STomi Valkeinen #if BPL > 2
364f7018c21STomi Valkeinen 		*dst++ = m[1];
365f7018c21STomi Valkeinen #endif
366f7018c21STomi Valkeinen #if BPL > 4
367f7018c21STomi Valkeinen 		*dst++ = m[2];
368f7018c21STomi Valkeinen 		*dst++ = m[3];
369f7018c21STomi Valkeinen #endif
370f7018c21STomi Valkeinen 		rows--;
371f7018c21STomi Valkeinen 	}
372f7018c21STomi Valkeinen 	return dst;
373f7018c21STomi Valkeinen }
374f7018c21STomi Valkeinen 
memmove32_col(void * dst,void * src,u32 mask,u32 h,u32 bytes)375f7018c21STomi Valkeinen static inline void memmove32_col(void *dst, void *src, u32 mask, u32 h, u32 bytes)
376f7018c21STomi Valkeinen {
377f7018c21STomi Valkeinen 	u32 *s, *d, v;
378f7018c21STomi Valkeinen 
379f7018c21STomi Valkeinen         s = src;
380f7018c21STomi Valkeinen         d = dst;
381f7018c21STomi Valkeinen         do {
382f7018c21STomi Valkeinen                 v = (*s++ & mask) | (*d  & ~mask);
383f7018c21STomi Valkeinen                 *d++ = v;
384f7018c21STomi Valkeinen #if BPL > 2
385f7018c21STomi Valkeinen                 v = (*s++ & mask) | (*d  & ~mask);
386f7018c21STomi Valkeinen                 *d++ = v;
387f7018c21STomi Valkeinen #endif
388f7018c21STomi Valkeinen #if BPL > 4
389f7018c21STomi Valkeinen                 v = (*s++ & mask) | (*d  & ~mask);
390f7018c21STomi Valkeinen                 *d++ = v;
391f7018c21STomi Valkeinen                 v = (*s++ & mask) | (*d  & ~mask);
392f7018c21STomi Valkeinen                 *d++ = v;
393f7018c21STomi Valkeinen #endif
394f7018c21STomi Valkeinen                 d = (u32 *)((u8 *)d + bytes);
395f7018c21STomi Valkeinen                 s = (u32 *)((u8 *)s + bytes);
396f7018c21STomi Valkeinen         } while (--h);
397f7018c21STomi Valkeinen }
398f7018c21STomi Valkeinen 
399f7018c21STomi Valkeinen #endif
400f7018c21STomi Valkeinen 
401f7018c21STomi Valkeinen #endif /* _VIDEO_ATAFB_UTILS_H */
402