|
@@ -94,29 +94,34 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src
|
|
|
FB_WRITEL( comp( FB_READL(src), FB_READL(dst), last), dst);
|
|
|
}
|
|
|
} else {
|
|
|
+ /* Different alignment for source and dest */
|
|
|
unsigned long d0, d1;
|
|
|
int m;
|
|
|
- // Different alignment for source and dest
|
|
|
|
|
|
right = shift & (bits - 1);
|
|
|
left = -shift & (bits - 1);
|
|
|
+ bswapmask &= shift;
|
|
|
|
|
|
if (dst_idx+n <= bits) {
|
|
|
// Single destination word
|
|
|
if (last)
|
|
|
first &= last;
|
|
|
+ d0 = FB_READL(src);
|
|
|
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
|
|
|
if (shift > 0) {
|
|
|
// Single source word
|
|
|
- FB_WRITEL( comp( FB_READL(src) >> right, FB_READL(dst), first), dst);
|
|
|
+ d0 >>= right;
|
|
|
} else if (src_idx+n <= bits) {
|
|
|
// Single source word
|
|
|
- FB_WRITEL( comp(FB_READL(src) << left, FB_READL(dst), first), dst);
|
|
|
+ d0 <<= left;;
|
|
|
} else {
|
|
|
// 2 source words
|
|
|
- d0 = FB_READL(src++);
|
|
|
- d1 = FB_READL(src);
|
|
|
- FB_WRITEL( comp(d0<<left | d1>>right, FB_READL(dst), first), dst);
|
|
|
+ d1 = FB_READL(src + 1);
|
|
|
+ d1 = fb_rev_pixels_in_long(d1, bswapmask);
|
|
|
+ d0 = d0<<left | d1>>right;
|
|
|
}
|
|
|
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
|
|
|
+ FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
|
|
|
} else {
|
|
|
// Multiple destination words
|
|
|
/** We must always remember the last value read, because in case
|
|
@@ -125,25 +130,31 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src
|
|
|
overlap with the current long from SRC. We store this value in
|
|
|
'd0'. */
|
|
|
d0 = FB_READL(src++);
|
|
|
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
|
|
|
// Leading bits
|
|
|
if (shift > 0) {
|
|
|
// Single source word
|
|
|
- FB_WRITEL( comp(d0 >> right, FB_READL(dst), first), dst);
|
|
|
+ d1 = d0;
|
|
|
+ d0 >>= right;
|
|
|
dst++;
|
|
|
n -= bits - dst_idx;
|
|
|
} else {
|
|
|
// 2 source words
|
|
|
d1 = FB_READL(src++);
|
|
|
- FB_WRITEL( comp(d0<<left | d1>>right, FB_READL(dst), first), dst);
|
|
|
- d0 = d1;
|
|
|
+ d1 = fb_rev_pixels_in_long(d1, bswapmask);
|
|
|
+
|
|
|
+ d0 = d0<<left | d1>>right;
|
|
|
dst++;
|
|
|
n -= bits - dst_idx;
|
|
|
}
|
|
|
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
|
|
|
+ FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
|
|
|
+ d0 = d1;
|
|
|
|
|
|
// Main chunk
|
|
|
m = n % bits;
|
|
|
n /= bits;
|
|
|
- while (n >= 4) {
|
|
|
+ while ((n >= 4) && !bswapmask) {
|
|
|
d1 = FB_READL(src++);
|
|
|
FB_WRITEL(d0 << left | d1 >> right, dst++);
|
|
|
d0 = d1;
|
|
@@ -160,7 +171,10 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src
|
|
|
}
|
|
|
while (n--) {
|
|
|
d1 = FB_READL(src++);
|
|
|
- FB_WRITEL(d0 << left | d1 >> right, dst++);
|
|
|
+ d1 = fb_rev_pixels_in_long(d1, bswapmask);
|
|
|
+ d0 = d0 << left | d1 >> right;
|
|
|
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
|
|
|
+ FB_WRITEL(d0, dst++);
|
|
|
d0 = d1;
|
|
|
}
|
|
|
|
|
@@ -168,12 +182,16 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src
|
|
|
if (last) {
|
|
|
if (m <= right) {
|
|
|
// Single source word
|
|
|
- FB_WRITEL( comp(d0 << left, FB_READL(dst), last), dst);
|
|
|
+ d0 <<= left;
|
|
|
} else {
|
|
|
// 2 source words
|
|
|
d1 = FB_READL(src);
|
|
|
- FB_WRITEL( comp(d0<<left | d1>>right, FB_READL(dst), last), dst);
|
|
|
+ d1 = fb_rev_pixels_in_long(d1,
|
|
|
+ bswapmask);
|
|
|
+ d0 = d0<<left | d1>>right;
|
|
|
}
|
|
|
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
|
|
|
+ FB_WRITEL(comp(d0, FB_READL(dst), last), dst);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -247,24 +265,32 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem
|
|
|
}
|
|
|
} else {
|
|
|
// Different alignment for source and dest
|
|
|
+ unsigned long d0, d1;
|
|
|
+ int m;
|
|
|
|
|
|
int const left = -shift & (bits-1);
|
|
|
int const right = shift & (bits-1);
|
|
|
+ bswapmask &= shift;
|
|
|
|
|
|
if ((unsigned long)dst_idx+1 >= n) {
|
|
|
// Single destination word
|
|
|
if (last)
|
|
|
first &= last;
|
|
|
+ d0 = FB_READL(src);
|
|
|
if (shift < 0) {
|
|
|
// Single source word
|
|
|
- FB_WRITEL( comp( FB_READL(src)<<left, FB_READL(dst), first), dst);
|
|
|
+ d0 <<= left;
|
|
|
} else if (1+(unsigned long)src_idx >= n) {
|
|
|
// Single source word
|
|
|
- FB_WRITEL( comp( FB_READL(src)>>right, FB_READL(dst), first), dst);
|
|
|
+ d0 >>= right;
|
|
|
} else {
|
|
|
// 2 source words
|
|
|
- FB_WRITEL( comp( (FB_READL(src)>>right | FB_READL(src-1)<<left), FB_READL(dst), first), dst);
|
|
|
+ d1 = FB_READL(src - 1);
|
|
|
+ d1 = fb_rev_pixels_in_long(d1, bswapmask);
|
|
|
+ d0 = d0>>right | d1<<left;
|
|
|
}
|
|
|
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
|
|
|
+ FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
|
|
|
} else {
|
|
|
// Multiple destination words
|
|
|
/** We must always remember the last value read, because in case
|
|
@@ -272,27 +298,30 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem
|
|
|
1bpp), we always collect one full long for DST and that might
|
|
|
overlap with the current long from SRC. We store this value in
|
|
|
'd0'. */
|
|
|
- unsigned long d0, d1;
|
|
|
- int m;
|
|
|
|
|
|
d0 = FB_READL(src--);
|
|
|
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
|
|
|
// Leading bits
|
|
|
if (shift < 0) {
|
|
|
// Single source word
|
|
|
- FB_WRITEL( comp( (d0 << left), FB_READL(dst), first), dst);
|
|
|
+ d1 = d0;
|
|
|
+ d0 <<= left;
|
|
|
} else {
|
|
|
// 2 source words
|
|
|
d1 = FB_READL(src--);
|
|
|
- FB_WRITEL( comp( (d0>>right | d1<<left), FB_READL(dst), first), dst);
|
|
|
- d0 = d1;
|
|
|
+ d1 = fb_rev_pixels_in_long(d1, bswapmask);
|
|
|
+ d0 = d0>>right | d1<<left;
|
|
|
}
|
|
|
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
|
|
|
+ FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
|
|
|
+ d0 = d1;
|
|
|
dst--;
|
|
|
n -= dst_idx+1;
|
|
|
|
|
|
// Main chunk
|
|
|
m = n % bits;
|
|
|
n /= bits;
|
|
|
- while (n >= 4) {
|
|
|
+ while ((n >= 4) && !bswapmask) {
|
|
|
d1 = FB_READL(src--);
|
|
|
FB_WRITEL(d0 >> right | d1 << left, dst--);
|
|
|
d0 = d1;
|
|
@@ -309,7 +338,10 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem
|
|
|
}
|
|
|
while (n--) {
|
|
|
d1 = FB_READL(src--);
|
|
|
- FB_WRITEL(d0 >> right | d1 << left, dst--);
|
|
|
+ d1 = fb_rev_pixels_in_long(d1, bswapmask);
|
|
|
+ d0 = d0 >> right | d1 << left;
|
|
|
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
|
|
|
+ FB_WRITEL(d0, dst--);
|
|
|
d0 = d1;
|
|
|
}
|
|
|
|
|
@@ -317,12 +349,16 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem
|
|
|
if (last) {
|
|
|
if (m <= left) {
|
|
|
// Single source word
|
|
|
- FB_WRITEL( comp(d0 >> right, FB_READL(dst), last), dst);
|
|
|
+ d0 >>= right;
|
|
|
} else {
|
|
|
// 2 source words
|
|
|
d1 = FB_READL(src);
|
|
|
- FB_WRITEL( comp(d0>>right | d1<<left, FB_READL(dst), last), dst);
|
|
|
+ d1 = fb_rev_pixels_in_long(d1,
|
|
|
+ bswapmask);
|
|
|
+ d0 = d0>>right | d1<<left;
|
|
|
}
|
|
|
+ d0 = fb_rev_pixels_in_long(d0, bswapmask);
|
|
|
+ FB_WRITEL(comp(d0, FB_READL(dst), last), dst);
|
|
|
}
|
|
|
}
|
|
|
}
|