]>
git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/bit.c
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
22 return (*ptr
& mask
) >> shift
;
62 p
= (char *)obj
+ byteize(bitoff
);
63 bit
= bitoffs(bitoff
);
64 signext
= (flags
& BVSIGNED
) != 0;
65 z4
= ((intptr_t)p
& 0xf) == 0 && bit
== 0;
66 if (nbits
== 64 && z4
)
67 return be64_to_cpu(*(__be64
*)p
);
68 z3
= ((intptr_t)p
& 0x7) == 0 && bit
== 0;
69 if (nbits
== 32 && z3
) {
71 return (__s32
)be32_to_cpu(*(__be32
*)p
);
73 return (__u32
)be32_to_cpu(*(__be32
*)p
);
75 z2
= ((intptr_t)p
& 0x3) == 0 && bit
== 0;
76 if (nbits
== 16 && z2
) {
78 return (__s16
)be16_to_cpu(*(__be16
*)p
);
80 return (__u16
)be16_to_cpu(*(__be16
*)p
);
82 z1
= ((intptr_t)p
& 0x1) == 0 && bit
== 0;
83 if (nbits
== 8 && z1
) {
91 for (i
= 0, rval
= 0LL; i
< nbits
; i
++) {
92 if (getbit_l(p
, bit
+ i
)) {
93 /* If the last bit is on and we care about sign
94 * bits and we don't have a full 64 bit
95 * container, turn all bits on between the
96 * sign bit and the most sig bit.
99 /* handle endian swap here */
100 #if __BYTE_ORDER == LITTLE_ENDIAN
101 if (i
== 0 && signext
&& nbits
< 64)
102 rval
= (~0ULL) << nbits
;
103 rval
|= 1ULL << (nbits
- i
- 1);
105 if ((i
== (nbits
- 1)) && signext
&& nbits
< 64)
106 rval
|= ((~0ULL) << nbits
);
107 rval
|= 1ULL << (nbits
- i
- 1);
115 * The input data can be 8, 16, 32, and 64 sized numeric values
116 * aligned on a byte boundry, or odd sized numbers stored on odd
117 * aligned offset (for example the bmbt fields).
119 * The input data sent to this routine has been converted to big endian
120 * and has been adjusted in the array so that the first input bit is to
121 * be written in the first bit in the output.
123 * If the field length and the output buffer are byte aligned, then use
124 * memcpy from the input to the output, but if either entries are not byte
125 * aligned, then loop over the entire bit range reading the input value
126 * and set/clear the matching bit in the output.
128 * example when ibuf is not multiple of a byte in length:
130 * ibuf: | BBBBBBBB | bbbxxxxx |
132 * obuf+bitoff: | xBBBBBBB | Bbbbxxxx |
137 void *obuf
, /* start of buffer to write into */
138 int bitoff
, /* bit offset into the output buffer */
139 int nbits
, /* number of bits to write */
140 void *ibuf
) /* source bits */
146 if (bitoff
% NBBY
|| nbits
% NBBY
) {
147 for (bit
= 0; bit
< nbits
; bit
++)
148 setbit_l(out
, bit
+ bitoff
, getbit_l(in
, bit
));
150 memcpy(out
+ byteize(bitoff
), in
, byteize(nbits
));