0001
0002 #ifndef _VIDEO_ATAFB_UTILS_H
0003 #define _VIDEO_ATAFB_UTILS_H
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 static inline void *fb_memclear_small(void *s, size_t count)
0050 {
0051 if (!count)
0052 return 0;
0053
0054 asm volatile ("\n"
0055 " lsr.l #1,%1 ; jcc 1f ; move.b %2,-(%0)\n"
0056 "1: lsr.l #1,%1 ; jcc 1f ; move.w %2,-(%0)\n"
0057 "1: lsr.l #1,%1 ; jcc 1f ; move.l %2,-(%0)\n"
0058 "1: lsr.l #1,%1 ; jcc 1f ; move.l %2,-(%0) ; move.l %2,-(%0)\n"
0059 "1:"
0060 : "=a" (s), "=d" (count)
0061 : "d" (0), "0" ((char *)s + count), "1" (count));
0062 asm volatile ("\n"
0063 " subq.l #1,%1\n"
0064 " jcs 3f\n"
0065 " move.l %2,%%d4; move.l %2,%%d5; move.l %2,%%d6\n"
0066 "2: movem.l %2/%%d4/%%d5/%%d6,-(%0)\n"
0067 " dbra %1,2b\n"
0068 "3:"
0069 : "=a" (s), "=d" (count)
0070 : "d" (0), "0" (s), "1" (count)
0071 : "d4", "d5", "d6"
0072 );
0073
0074 return 0;
0075 }
0076
0077
0078 static inline void *fb_memclear(void *s, size_t count)
0079 {
0080 if (!count)
0081 return 0;
0082
0083 if (count < 16) {
0084 asm volatile ("\n"
0085 " lsr.l #1,%1 ; jcc 1f ; clr.b (%0)+\n"
0086 "1: lsr.l #1,%1 ; jcc 1f ; clr.w (%0)+\n"
0087 "1: lsr.l #1,%1 ; jcc 1f ; clr.l (%0)+\n"
0088 "1: lsr.l #1,%1 ; jcc 1f ; clr.l (%0)+ ; clr.l (%0)+\n"
0089 "1:"
0090 : "=a" (s), "=d" (count)
0091 : "0" (s), "1" (count));
0092 } else {
0093 long tmp;
0094 asm volatile ("\n"
0095 " move.l %1,%2\n"
0096 " lsr.l #1,%2 ; jcc 1f ; clr.b (%0)+ ; subq.w #1,%1\n"
0097 " lsr.l #1,%2 ; jcs 2f\n"
0098 " clr.w (%0)+ ; subq.w #2,%1 ; jra 2f\n"
0099 "1: lsr.l #1,%2 ; jcc 2f\n"
0100 " clr.w (%0)+ ; subq.w #2,%1\n"
0101 "2: move.w %1,%2; lsr.l #2,%1 ; jeq 6f\n"
0102 " lsr.l #1,%1 ; jcc 3f ; clr.l (%0)+\n"
0103 "3: lsr.l #1,%1 ; jcc 4f ; clr.l (%0)+ ; clr.l (%0)+\n"
0104 "4: subq.l #1,%1 ; jcs 6f\n"
0105 "5: clr.l (%0)+; clr.l (%0)+ ; clr.l (%0)+ ; clr.l (%0)+\n"
0106 " dbra %1,5b ; clr.w %1; subq.l #1,%1; jcc 5b\n"
0107 "6: move.w %2,%1; btst #1,%1 ; jeq 7f ; clr.w (%0)+\n"
0108 "7: btst #0,%1 ; jeq 8f ; clr.b (%0)+\n"
0109 "8:"
0110 : "=a" (s), "=d" (count), "=d" (tmp)
0111 : "0" (s), "1" (count));
0112 }
0113
0114 return 0;
0115 }
0116
0117
0118 static inline void *fb_memset255(void *s, size_t count)
0119 {
0120 if (!count)
0121 return 0;
0122
0123 asm volatile ("\n"
0124 " lsr.l #1,%1 ; jcc 1f ; move.b %2,-(%0)\n"
0125 "1: lsr.l #1,%1 ; jcc 1f ; move.w %2,-(%0)\n"
0126 "1: lsr.l #1,%1 ; jcc 1f ; move.l %2,-(%0)\n"
0127 "1: lsr.l #1,%1 ; jcc 1f ; move.l %2,-(%0) ; move.l %2,-(%0)\n"
0128 "1:"
0129 : "=a" (s), "=d" (count)
0130 : "d" (-1), "0" ((char *)s+count), "1" (count));
0131 asm volatile ("\n"
0132 " subq.l #1,%1 ; jcs 3f\n"
0133 " move.l %2,%%d4; move.l %2,%%d5; move.l %2,%%d6\n"
0134 "2: movem.l %2/%%d4/%%d5/%%d6,-(%0)\n"
0135 " dbra %1,2b\n"
0136 "3:"
0137 : "=a" (s), "=d" (count)
0138 : "d" (-1), "0" (s), "1" (count)
0139 : "d4", "d5", "d6");
0140
0141 return 0;
0142 }
0143
0144
0145 static inline void *fb_memmove(void *d, const void *s, size_t count)
0146 {
0147 if (d < s) {
0148 if (count < 16) {
0149 asm volatile ("\n"
0150 " lsr.l #1,%2 ; jcc 1f ; move.b (%1)+,(%0)+\n"
0151 "1: lsr.l #1,%2 ; jcc 1f ; move.w (%1)+,(%0)+\n"
0152 "1: lsr.l #1,%2 ; jcc 1f ; move.l (%1)+,(%0)+\n"
0153 "1: lsr.l #1,%2 ; jcc 1f ; move.l (%1)+,(%0)+ ; move.l (%1)+,(%0)+\n"
0154 "1:"
0155 : "=a" (d), "=a" (s), "=d" (count)
0156 : "0" (d), "1" (s), "2" (count));
0157 } else {
0158 long tmp;
0159 asm volatile ("\n"
0160 " move.l %0,%3\n"
0161 " lsr.l #1,%3 ; jcc 1f ; move.b (%1)+,(%0)+ ; subqw #1,%2\n"
0162 " lsr.l #1,%3 ; jcs 2f\n"
0163 " move.w (%1)+,(%0)+ ; subqw #2,%2 ; jra 2f\n"
0164 "1: lsr.l #1,%3 ; jcc 2f\n"
0165 " move.w (%1)+,(%0)+ ; subqw #2,%2\n"
0166 "2: move.w %2,%-; lsr.l #2,%2 ; jeq 6f\n"
0167 " lsr.l #1,%2 ; jcc 3f ; move.l (%1)+,(%0)+\n"
0168 "3: lsr.l #1,%2 ; jcc 4f ; move.l (%1)+,(%0)+ ; move.l (%1)+,(%0)+\n"
0169 "4: subq.l #1,%2 ; jcs 6f\n"
0170 "5: move.l (%1)+,(%0)+; move.l (%1)+,(%0)+\n"
0171 " move.l (%1)+,(%0)+; move.l (%1)+,(%0)+\n"
0172 " dbra %2,5b ; clr.w %2; subq.l #1,%2; jcc 5b\n"
0173 "6: move.w %+,%2; btst #1,%2 ; jeq 7f ; move.w (%1)+,(%0)+\n"
0174 "7: btst #0,%2 ; jeq 8f ; move.b (%1)+,(%0)+\n"
0175 "8:"
0176 : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
0177 : "0" (d), "1" (s), "2" (count));
0178 }
0179 } else {
0180 if (count < 16) {
0181 asm volatile ("\n"
0182 " lsr.l #1,%2 ; jcc 1f ; move.b -(%1),-(%0)\n"
0183 "1: lsr.l #1,%2 ; jcc 1f ; move.w -(%1),-(%0)\n"
0184 "1: lsr.l #1,%2 ; jcc 1f ; move.l -(%1),-(%0)\n"
0185 "1: lsr.l #1,%2 ; jcc 1f ; move.l -(%1),-(%0) ; move.l -(%1),-(%0)\n"
0186 "1:"
0187 : "=a" (d), "=a" (s), "=d" (count)
0188 : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count));
0189 } else {
0190 long tmp;
0191
0192 asm volatile ("\n"
0193 " move.l %0,%3\n"
0194 " lsr.l #1,%3 ; jcc 1f ; move.b -(%1),-(%0) ; subqw #1,%2\n"
0195 " lsr.l #1,%3 ; jcs 2f\n"
0196 " move.w -(%1),-(%0) ; subqw #2,%2 ; jra 2f\n"
0197 "1: lsr.l #1,%3 ; jcc 2f\n"
0198 " move.w -(%1),-(%0) ; subqw #2,%2\n"
0199 "2: move.w %2,%-; lsr.l #2,%2 ; jeq 6f\n"
0200 " lsr.l #1,%2 ; jcc 3f ; move.l -(%1),-(%0)\n"
0201 "3: lsr.l #1,%2 ; jcc 4f ; move.l -(%1),-(%0) ; move.l -(%1),-(%0)\n"
0202 "4: subq.l #1,%2 ; jcs 6f\n"
0203 "5: move.l -(%1),-(%0); move.l -(%1),-(%0)\n"
0204 " move.l -(%1),-(%0); move.l -(%1),-(%0)\n"
0205 " dbra %2,5b ; clr.w %2; subq.l #1,%2; jcc 5b\n"
0206 "6: move.w %+,%2; btst #1,%2 ; jeq 7f ; move.w -(%1),-(%0)\n"
0207 "7: btst #0,%2 ; jeq 8f ; move.b -(%1),-(%0)\n"
0208 "8:"
0209 : "=a" (d), "=a" (s), "=d" (count), "=d" (tmp)
0210 : "0" ((char *) d + count), "1" ((char *) s + count), "2" (count));
0211 }
0212 }
0213
0214 return 0;
0215 }
0216
0217
0218
0219
0220 static inline void fast_memmove(char *dst, const char *src, size_t size)
0221 {
0222 if (!size)
0223 return;
0224 if (dst < src)
0225 asm volatile ("\n"
0226 "1: movem.l (%0)+,%%d0/%%d1/%%a0/%%a1\n"
0227 " movem.l %%d0/%%d1/%%a0/%%a1,%1@\n"
0228 " addq.l #8,%1; addq.l #8,%1\n"
0229 " dbra %2,1b\n"
0230 " clr.w %2; subq.l #1,%2\n"
0231 " jcc 1b"
0232 : "=a" (src), "=a" (dst), "=d" (size)
0233 : "0" (src), "1" (dst), "2" (size / 16 - 1)
0234 : "d0", "d1", "a0", "a1", "memory");
0235 else
0236 asm volatile ("\n"
0237 "1: subq.l #8,%0; subq.l #8,%0\n"
0238 " movem.l %0@,%%d0/%%d1/%%a0/%%a1\n"
0239 " movem.l %%d0/%%d1/%%a0/%%a1,-(%1)\n"
0240 " dbra %2,1b\n"
0241 " clr.w %2; subq.l #1,%2\n"
0242 " jcc 1b"
0243 : "=a" (src), "=a" (dst), "=d" (size)
0244 : "0" (src + size), "1" (dst + size), "2" (size / 16 - 1)
0245 : "d0", "d1", "a0", "a1", "memory");
0246 }
0247
0248 #ifdef BPL
0249
0250
0251
0252
0253
0254 static const u32 four2long[] = {
0255 0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
0256 0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
0257 0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
0258 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff,
0259 };
0260
0261 static inline void expand8_col2mask(u8 c, u32 m[])
0262 {
0263 m[0] = four2long[c & 15];
0264 #if BPL > 4
0265 m[1] = four2long[c >> 4];
0266 #endif
0267 }
0268
0269 static inline void expand8_2col2mask(u8 fg, u8 bg, u32 fgm[], u32 bgm[])
0270 {
0271 fgm[0] = four2long[fg & 15] ^ (bgm[0] = four2long[bg & 15]);
0272 #if BPL > 4
0273 fgm[1] = four2long[fg >> 4] ^ (bgm[1] = four2long[bg >> 4]);
0274 #endif
0275 }
0276
0277
0278
0279
0280 static inline void fill8_col(u8 *dst, u32 m[])
0281 {
0282 u32 tmp = m[0];
0283 dst[0] = tmp;
0284 dst[2] = (tmp >>= 8);
0285 #if BPL > 2
0286 dst[4] = (tmp >>= 8);
0287 dst[6] = tmp >> 8;
0288 #endif
0289 #if BPL > 4
0290 tmp = m[1];
0291 dst[8] = tmp;
0292 dst[10] = (tmp >>= 8);
0293 dst[12] = (tmp >>= 8);
0294 dst[14] = tmp >> 8;
0295 #endif
0296 }
0297
0298
0299
0300
0301 static inline void fill8_2col(u8 *dst, u8 fg, u8 bg, u32 mask)
0302 {
0303 u32 fgm[2], bgm[2], tmp;
0304
0305 expand8_2col2mask(fg, bg, fgm, bgm);
0306
0307 mask |= mask << 8;
0308 #if BPL > 2
0309 mask |= mask << 16;
0310 #endif
0311 tmp = (mask & fgm[0]) ^ bgm[0];
0312 dst[0] = tmp;
0313 dst[2] = (tmp >>= 8);
0314 #if BPL > 2
0315 dst[4] = (tmp >>= 8);
0316 dst[6] = tmp >> 8;
0317 #endif
0318 #if BPL > 4
0319 tmp = (mask & fgm[1]) ^ bgm[1];
0320 dst[8] = tmp;
0321 dst[10] = (tmp >>= 8);
0322 dst[12] = (tmp >>= 8);
0323 dst[14] = tmp >> 8;
0324 #endif
0325 }
0326
0327 static const u32 two2word[] = {
0328 0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
0329 };
0330
0331 static inline void expand16_col2mask(u8 c, u32 m[])
0332 {
0333 m[0] = two2word[c & 3];
0334 #if BPL > 2
0335 m[1] = two2word[(c >> 2) & 3];
0336 #endif
0337 #if BPL > 4
0338 m[2] = two2word[(c >> 4) & 3];
0339 m[3] = two2word[c >> 6];
0340 #endif
0341 }
0342
0343 static inline void expand16_2col2mask(u8 fg, u8 bg, u32 fgm[], u32 bgm[])
0344 {
0345 bgm[0] = two2word[bg & 3];
0346 fgm[0] = two2word[fg & 3] ^ bgm[0];
0347 #if BPL > 2
0348 bgm[1] = two2word[(bg >> 2) & 3];
0349 fgm[1] = two2word[(fg >> 2) & 3] ^ bgm[1];
0350 #endif
0351 #if BPL > 4
0352 bgm[2] = two2word[(bg >> 4) & 3];
0353 fgm[2] = two2word[(fg >> 4) & 3] ^ bgm[2];
0354 bgm[3] = two2word[bg >> 6];
0355 fgm[3] = two2word[fg >> 6] ^ bgm[3];
0356 #endif
0357 }
0358
0359 static inline u32 *fill16_col(u32 *dst, int rows, u32 m[])
0360 {
0361 while (rows) {
0362 *dst++ = m[0];
0363 #if BPL > 2
0364 *dst++ = m[1];
0365 #endif
0366 #if BPL > 4
0367 *dst++ = m[2];
0368 *dst++ = m[3];
0369 #endif
0370 rows--;
0371 }
0372 return dst;
0373 }
0374
0375 static inline void memmove32_col(void *dst, void *src, u32 mask, u32 h, u32 bytes)
0376 {
0377 u32 *s, *d, v;
0378
0379 s = src;
0380 d = dst;
0381 do {
0382 v = (*s++ & mask) | (*d & ~mask);
0383 *d++ = v;
0384 #if BPL > 2
0385 v = (*s++ & mask) | (*d & ~mask);
0386 *d++ = v;
0387 #endif
0388 #if BPL > 4
0389 v = (*s++ & mask) | (*d & ~mask);
0390 *d++ = v;
0391 v = (*s++ & mask) | (*d & ~mask);
0392 *d++ = v;
0393 #endif
0394 d = (u32 *)((u8 *)d + bytes);
0395 s = (u32 *)((u8 *)s + bytes);
0396 } while (--h);
0397 }
0398
0399 #endif
0400
0401 #endif