1*b2441318SGreg 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 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 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 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 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 */ 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 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 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 */ 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 */ 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 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 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 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 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