|
@@ -402,3 +402,88 @@ void bitmap_to_le(unsigned long *dst, const unsigned long *src,
|
|
|
{
|
|
|
bitmap_to_from_le(dst, src, nbits);
|
|
|
}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Copy "src" bitmap with a positive offset and put it into the "dst"
|
|
|
+ * bitmap. The caller needs to make sure the bitmap size of "src"
|
|
|
+ * is bigger than (shift + nbits).
|
|
|
+ */
|
|
|
+void bitmap_copy_with_src_offset(unsigned long *dst, const unsigned long *src,
|
|
|
+ unsigned long shift, unsigned long nbits)
|
|
|
+{
|
|
|
+ unsigned long left_mask, right_mask, last_mask;
|
|
|
+
|
|
|
+ /* Proper shift src pointer to the first word to copy from */
|
|
|
+ src += BIT_WORD(shift);
|
|
|
+ shift %= BITS_PER_LONG;
|
|
|
+
|
|
|
+ if (!shift) {
|
|
|
+ /* Fast path */
|
|
|
+ bitmap_copy(dst, src, nbits);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ right_mask = (1ul << shift) - 1;
|
|
|
+ left_mask = ~right_mask;
|
|
|
+
|
|
|
+ while (nbits >= BITS_PER_LONG) {
|
|
|
+ *dst = (*src & left_mask) >> shift;
|
|
|
+ *dst |= (src[1] & right_mask) << (BITS_PER_LONG - shift);
|
|
|
+ dst++;
|
|
|
+ src++;
|
|
|
+ nbits -= BITS_PER_LONG;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (nbits > BITS_PER_LONG - shift) {
|
|
|
+ *dst = (*src & left_mask) >> shift;
|
|
|
+ nbits -= BITS_PER_LONG - shift;
|
|
|
+ last_mask = (1ul << nbits) - 1;
|
|
|
+ *dst |= (src[1] & last_mask) << (BITS_PER_LONG - shift);
|
|
|
+ } else if (nbits) {
|
|
|
+ last_mask = (1ul << nbits) - 1;
|
|
|
+ *dst = (*src >> shift) & last_mask;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Copy "src" bitmap into the "dst" bitmap with an offset in the
|
|
|
+ * "dst". The caller needs to make sure the bitmap size of "dst" is
|
|
|
+ * bigger than (shift + nbits).
|
|
|
+ */
|
|
|
+void bitmap_copy_with_dst_offset(unsigned long *dst, const unsigned long *src,
|
|
|
+ unsigned long shift, unsigned long nbits)
|
|
|
+{
|
|
|
+ unsigned long left_mask, right_mask, last_mask;
|
|
|
+
|
|
|
+ /* Proper shift dst pointer to the first word to copy from */
|
|
|
+ dst += BIT_WORD(shift);
|
|
|
+ shift %= BITS_PER_LONG;
|
|
|
+
|
|
|
+ if (!shift) {
|
|
|
+ /* Fast path */
|
|
|
+ bitmap_copy(dst, src, nbits);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ right_mask = (1ul << (BITS_PER_LONG - shift)) - 1;
|
|
|
+ left_mask = ~right_mask;
|
|
|
+
|
|
|
+ *dst &= (1ul << shift) - 1;
|
|
|
+ while (nbits >= BITS_PER_LONG) {
|
|
|
+ *dst |= (*src & right_mask) << shift;
|
|
|
+ dst[1] = (*src & left_mask) >> (BITS_PER_LONG - shift);
|
|
|
+ dst++;
|
|
|
+ src++;
|
|
|
+ nbits -= BITS_PER_LONG;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (nbits > BITS_PER_LONG - shift) {
|
|
|
+ *dst |= (*src & right_mask) << shift;
|
|
|
+ nbits -= BITS_PER_LONG - shift;
|
|
|
+ last_mask = ((1ul << nbits) - 1) << (BITS_PER_LONG - shift);
|
|
|
+ dst[1] = (*src & last_mask) >> (BITS_PER_LONG - shift);
|
|
|
+ } else if (nbits) {
|
|
|
+ last_mask = (1ul << nbits) - 1;
|
|
|
+ *dst |= (*src & last_mask) << shift;
|
|
|
+ }
|
|
|
+}
|