4 #include <osmocom/core/bits.h>
11 * \brief Osmocom bit level support code
15 /*! \brief convert unpacked bits to packed bits, return length in bytes
16 * \param[out] out output buffer of packed bits
17 * \param[in] in input buffer of unpacked bits
18 * \param[in] num_bits number of bits
20 int osmo_ubit2pbit(pbit_t
*out
, const ubit_t
*in
, unsigned int num_bits
)
26 for (i
= 0; i
< num_bits
; i
++) {
27 uint8_t bitnum
= 7 - (i
% 8);
29 curbyte
|= (in
[i
] << bitnum
);
36 /* we have a non-modulo-8 bitcount */
43 /*! \brief convert packed bits to unpacked bits, return length in bytes
44 * \param[out] out output buffer of unpacked bits
45 * \param[in] in input buffer of packed bits
46 * \param[in] num_bits number of bits
48 int osmo_pbit2ubit(ubit_t
*out
, const pbit_t
*in
, unsigned int num_bits
)
52 ubit_t
*limit
= out
+ num_bits
;
54 for (i
= 0; i
< (num_bits
/8)+1; i
++) {
56 *cur
++ = (byte
>> 7) & 1;
59 *cur
++ = (byte
>> 6) & 1;
62 *cur
++ = (byte
>> 5) & 1;
65 *cur
++ = (byte
>> 4) & 1;
68 *cur
++ = (byte
>> 3) & 1;
71 *cur
++ = (byte
>> 2) & 1;
74 *cur
++ = (byte
>> 1) & 1;
77 *cur
++ = (byte
>> 0) & 1;
84 /*! \brief convert unpacked bits to packed bits (extended options)
85 * \param[out] out output buffer of packed bits
86 * \param[in] out_ofs offset into output buffer
87 * \param[in] in input buffer of unpacked bits
88 * \param[in] in_ofs offset into input buffer
89 * \param[in] num_bits number of bits
90 * \param[in] lsb_mode Encode bits in LSB orde instead of MSB
91 * \returns length in bytes (max written offset of output buffer + 1)
93 int osmo_ubit2pbit_ext(pbit_t
*out
, unsigned int out_ofs
,
94 const ubit_t
*in
, unsigned int in_ofs
,
95 unsigned int num_bits
, int lsb_mode
)
98 for (i
=0; i
<num_bits
; i
++) {
100 bn
= lsb_mode
? (op
&7) : (7-(op
&7));
102 out
[op
>>3] |= 1 << bn
;
104 out
[op
>>3] &= ~(1 << bn
);
106 return ((out_ofs
+ num_bits
- 1) >> 3) + 1;
109 /*! \brief convert packed bits to unpacked bits (extended options)
110 * \param[out] out output buffer of unpacked bits
111 * \param[in] out_ofs offset into output buffer
112 * \param[in] in input buffer of packed bits
113 * \param[in] in_ofs offset into input buffer
114 * \param[in] num_bits number of bits
115 * \param[in] lsb_mode Encode bits in LSB orde instead of MSB
116 * \returns length in bytes (max written offset of output buffer + 1)
118 int osmo_pbit2ubit_ext(ubit_t
*out
, unsigned int out_ofs
,
119 const pbit_t
*in
, unsigned int in_ofs
,
120 unsigned int num_bits
, int lsb_mode
)
123 for (i
=0; i
<num_bits
; i
++) {
125 bn
= lsb_mode
? (ip
&7) : (7-(ip
&7));
126 out
[out_ofs
+i
] = !!(in
[ip
>>3] & (1<<bn
));
128 return out_ofs
+ num_bits
;
131 /* generalized bit reversal function, Chapter 7 "Hackers Delight" */
132 uint32_t osmo_bit_reversal(uint32_t x
, enum osmo_br_mode k
)
134 if (k
& 1) x
= (x
& 0x55555555) << 1 | (x
& 0xAAAAAAAA) >> 1;
135 if (k
& 2) x
= (x
& 0x33333333) << 2 | (x
& 0xCCCCCCCC) >> 2;
136 if (k
& 4) x
= (x
& 0x0F0F0F0F) << 4 | (x
& 0xF0F0F0F0) >> 4;
137 if (k
& 8) x
= (x
& 0x00FF00FF) << 8 | (x
& 0xFF00FF00) >> 8;
138 if (k
& 16) x
= (x
& 0x0000FFFF) << 16 | (x
& 0xFFFF0000) >> 16;
143 /* generalized bit reversal function, Chapter 7 "Hackers Delight" */
144 uint32_t osmo_revbytebits_32(uint32_t x
)
146 x
= (x
& 0x55555555) << 1 | (x
& 0xAAAAAAAA) >> 1;
147 x
= (x
& 0x33333333) << 2 | (x
& 0xCCCCCCCC) >> 2;
148 x
= (x
& 0x0F0F0F0F) << 4 | (x
& 0xF0F0F0F0) >> 4;
153 uint32_t osmo_revbytebits_8(uint8_t x
)
155 x
= (x
& 0x55) << 1 | (x
& 0xAA) >> 1;
156 x
= (x
& 0x33) << 2 | (x
& 0xCC) >> 2;
157 x
= (x
& 0x0F) << 4 | (x
& 0xF0) >> 4;
162 void osmo_revbytebits_buf(uint8_t *buf
, int len
)
165 unsigned int unaligned_cnt
;
166 int len_remain
= len
;
168 unaligned_cnt
= ((unsigned long)buf
& 3);
169 for (i
= 0; i
< unaligned_cnt
; i
++) {
170 buf
[i
] = osmo_revbytebits_8(buf
[i
]);
176 for (i
= unaligned_cnt
; i
< len
; i
+= 4) {
177 uint32_t *cur
= (uint32_t *) (buf
+ i
);
178 *cur
= osmo_revbytebits_32(*cur
);
182 for (i
= len
- len_remain
; i
< len
; i
++) {
183 buf
[i
] = osmo_revbytebits_8(buf
[i
]);