2 .TH bits 3 "20 June 1999" "Straylight/Edgeware" "mLib utilities library"
12 bits \- portable bit manipulation macros
155 .B "#include <mLib/bits.h>"
157 .BR "typedef " ... " octet;"
158 .BR "typedef " ... " uint16;"
159 .BR "typedef " ... " uint24;"
160 .BR "typedef " ... " uint32;"
161 .BR "typedef " ... " uint64;"
162 .BR "typedef " ... " kludge64;"
164 .BI "#define TY_" we " " type
165 .BI "#define SZ_" we " \fR..."
166 .BI "#define MASK_" we " \fR..."
168 .BI "#define DOUINTSZ(" f ") \fR..."
169 .BI "#define DOUINTCONV(" f ") \fR..."
171 .IB type " U" w ( v );
173 .IB type " LSL" w ( type " " v ", int " s );
174 .IB type " LSR" w ( type " " v ", int " s );
175 .IB type " ROL" w ( type " " v ", int " s );
176 .IB type " ROR" w ( type " " v ", int " s );
178 .BI "octet GETBYTE(void *" p ", size_t " o );
179 .BI "void PUTBYTE(void *" p ", size_t " o ", octet " v );
181 .IB type " LOAD" we "(void *" p );
182 .BI "void STORE" we "(void *" p ", " type " " v );
184 .BI "void SET64(kludge64 &" d ", uint32 " h ", uint32 " l );
185 .BI "kludge64 X64(" hexh ", " hexl );
186 .BI "void ASSIGN64(kludge64 &" d ", " x );
187 .BI "uint32 HI64(kludge64" x );
188 .BI "uint32 LO64(kludge64" x );
189 .IB ty " GET64(" ty ", kludge64 " x );
190 .BI "void AND64(kludge64 &" d ", kludge64 " x ", kludge64 " y );
191 .BI "void OR64(kludge64 &" d ", kludge64 " x ", kludge64 " y );
192 .BI "void XOR64(kludge64 &" d ", kludge64 " x ", kludge64 " y );
193 .BI "void CPL64(kludge64 &" d ", kludge64 " x );
194 .BI "void ADD64(kludge64 &" d ", kludge64 " x ", kludge64 " y );
195 .BI "void SUB64(kludge64 &" d ", kludge64 " x ", kludge64 " y );
196 .BI "int CMP64(kludge64 " x ", " op ", kludge64 " y );
197 .BI "int ZERO64(kludge64 " x );
202 contains a number of useful definitions for portably dealing with bit-
203 and byte-level manipulation of larger quantities. The various macros
204 and types are named fairly systematically.
206 The header provides utilities for working with 64-bit quantities, but a
207 64-bit integer type is not guaranteed to exist under C89 rules. This
208 header takes two approaches. Firstly, if a 64-bit type is found, the
209 header defines the macro
211 and defines the various
213 macros as described below. Secondly, it unconditionally defines a type
215 and a family of macros for working with them. See below for details.
217 .SS "Type definitions"
218 A number of types are defined.
222 .BR "unsigned char" .
223 This is intended to be used when a character array is used to represent
224 the octets of some external data format. Note that on some
227 type may occupy more than 8 bits.
231 .BR "unsigned short" .
232 Intended to be used when a 16-bit value is required. This type is
233 always capable of representing any 16-bit unsigned value, but the actual
234 type may be wider than 16 bits and will require masking.
237 Equivalent to some (architecture-dependent) standard type. Capable of
238 representing any unsigned 24-bit value, although the the actual type may
239 be wider than 24 bits.
242 Equivalent to some (architecture-dependent) standard type. Capable of
243 representing any unsigned 32-bit value, although the the actual type may
244 be wider than 32 bits.
247 Equivalent to some (architecture-dependent) standard type, if it exists.
248 Capable of representing any unsigned 64-bit value, although the the
249 actual type may be wider than 64 bits.
251 .SS "Size/endianness suffixes"
254 be one of the size suffixes: 8, 16, 24, 32, and (if available) 64.
257 be one of the size-and-endian suffixes
266 denotes little-endian (Intel, VAX) representation, and
268 denotes big-endian (IBM, network) representation; omitting an explicit
269 suffix gives big-endian order by default, since this is most common in
270 portable data formats.
274 invokes a given macro
284 invokes a given macro
287 .IR f ( w ", " we ", " suff )
290 ranges over size-and-endian suffixes as described above,
292 is just the corresponding bit width, as an integer, and
299 suitable for a C function name.
301 These macros are intended to be used to define families of related
305 For each size-and-endian suffix
307 the following macros are defined.
310 A synonym for the appropriate one of the types
316 The number of octets needed to represent a value of the corresponding
321 The largest integer representable in the corresponding type; i.e., this
323 .RI 2\*(ss w \*(se\~\-\~1.
325 (Note that the endianness suffix is irrelevant in the above
334 to the appropriate type; specifically, it returns the smallest
335 nonnegative integer congruent to
340 .SS "Shift and rotate"
343 the macro invocations
344 .BI LSL w ( x ", " n )
346 .BI LSR w ( x ", " n )
351 left or right, respectively, by
359 (This behaviour is unfortunate, but (a) it's what a number of CPUs
360 provide natively, and (b) it's a cheap way to prevent undefined
361 behaviour.) Similarly,
362 .BI ROL w ( x ", " n )
364 .BI ROR w ( x ", " n )
369 left or right, respectively, by
375 .BI GETBYTE( p ", " o )
378 octet following the address
381 .BI PUTBYTE( p ", " o ", " v)
386 byte following the address
388 These macros always operate on byte offsets regardless of the type of
392 For each size-and-endian suffix
396 loads and returns a value in the corresponding format at address
399 .BI STORE we ( p ", " x )
404 in the corresponding format.
407 For portability to environments without native 64-bit integers, the
410 is defined. If the target platform is known to have an unsigned 64-bit
411 integer type, then this structure merely encapsulates a native integer,
412 and a decent optimizing compiler can be expected to handle this exactly
413 as if it were the native type. Otherwise, it contains two 32-bit halves
414 which are processed the hard way.
416 For each of the above macros with a suffix
421 an additional `kludge' macro is defined, whose name has an additional
422 final underscore; e.g., the kludge macro corresponding to
426 and that corresponding to
430 If the original macro would have
434 then the kludge macro has an additional first argument, denoted
436 which should be an lvalue of type
438 and the kludge macro will store its result in
440 The kludge macro's remaining arguments are the same as the original
441 macro, except that where the original macro accepts an argument of type
443 the kludge macro accepts an argument of type
447 Finally, a number of additional macros are provided, to make working
452 .BI SET64( d ", " h ", " l )
453 Set the high 32 bits of
457 and the low 32 bits to be
463 may be arbitrary integers.
465 .BI X64( hexh ", " hexl )
466 Expands to an initializer for an object of type
472 encode the high and low 32-bit halves in hexadecimal, without any
476 .BI ASSIGN( d ", " x )
484 Return the high 32 bits of
488 Return the low 32 bits of
491 .BI GET64( t ", " x )
498 is an unsigned integer type, then the value will be truncated to fit as
501 is a signed integer type, then the behaviour is undefined if the value
506 .BI AND64( d ", " x ", " y )
509 to be the bitwise-and of the two
516 .BI OR64( d ", " x ", " y )
519 to be the bitwise-or of the two
526 .BI XOR64( d ", " x ", " y )
529 to be the bitwise-exclusive-or of the two
536 .BI CPL64( d ", " x )
539 to be the bitwise complement of the
544 .BI ADD64( d ", " x ", " y )
547 to be the sum of the two
554 .BI SUB64( d ", " x ", " y )
557 to be the difference of the two
564 .BI CMP64( x ", " op ", " y )
569 should be arguments of type
573 should be one of the relational operators
587 Evaluates nonzero if the
595 Mark Wooding, <mdw@distorted.org.uk>