2 .TH bits 3 "20 June 1999" "Straylight/Edgeware" "mLib utilities library"
12 bits \- portable bit manipulation macros
172 .B "#include <mLib/bits.h>"
174 .BR "typedef " ... " octet;"
175 .BR "typedef " ... " uint16;"
176 .BR "typedef " ... " uint24;"
177 .BR "typedef " ... " uint32;"
178 .BR "typedef " ... " uint64;"
179 .BR "typedef " ... " kludge64;"
181 .BI "#define TY_" we " " type
182 .BI "#define SZ_" we " \fR..."
183 .BI "#define MASK_" we " \fR..."
185 .BI "#define DOUINTSZ(" f ") \fR..."
186 .BI "#define DOUINTCONV(" f ") \fR..."
188 .IB type " U" w ( v );
190 .IB type " LSL" w ( type " " v ", int " s );
191 .IB type " LSR" w ( type " " v ", int " s );
192 .IB type " ROL" w ( type " " v ", int " s );
193 .IB type " ROR" w ( type " " v ", int " s );
195 .BI "octet GETBYTE(void *" p ", size_t " o );
196 .BI "void PUTBYTE(void *" p ", size_t " o ", octet " v );
198 .IB type " LOAD" we "(void *" p );
199 .BI "void STORE" we "(void *" p ", " type " " v );
201 .BI "void SET64(kludge64 &" d ", uint32 " h ", uint32 " l );
202 .BI "kludge64 X64(" hexh ", " hexl );
203 .BI "void ASSIGN64(kludge64 &" d ", " x );
204 .BI "uint32 HI64(kludge64" x );
205 .BI "uint32 LO64(kludge64" x );
206 .IB ty " GET64(" ty ", kludge64 " x );
207 .BI "void AND64(kludge64 &" d ", kludge64 " x ", kludge64 " y );
208 .BI "void OR64(kludge64 &" d ", kludge64 " x ", kludge64 " y );
209 .BI "void XOR64(kludge64 &" d ", kludge64 " x ", kludge64 " y );
210 .BI "void CPL64(kludge64 &" d ", kludge64 " x );
211 .BI "void ADD64(kludge64 &" d ", kludge64 " x ", kludge64 " y );
212 .BI "void SUB64(kludge64 &" d ", kludge64 " x ", kludge64 " y );
213 .BI "int CMP64(kludge64 " x ", " op ", kludge64 " y );
214 .BI "int ZERO64(kludge64 " x );
219 contains a number of useful definitions for portably dealing with bit-
220 and byte-level manipulation of larger quantities. The various macros
221 and types are named fairly systematically.
223 The header provides utilities for working with 64-bit quantities, but a
224 64-bit integer type is not guaranteed to exist under C89 rules. This
225 header takes two approaches. Firstly, if a 64-bit type is found, the
226 header defines the macro
228 and defines the various
230 macros as described below. Secondly, it unconditionally defines a type
232 and a family of macros for working with them. See below for details.
234 .SS "Type definitions"
235 A number of types are defined.
239 .BR "unsigned char" .
240 This is intended to be used when a character array is used to represent
241 the octets of some external data format. Note that on some
244 type may occupy more than 8 bits.
248 .BR "unsigned short" .
249 Intended to be used when a 16-bit value is required. This type is
250 always capable of representing any 16-bit unsigned value, but the actual
251 type may be wider than 16 bits and will require masking.
254 Equivalent to some (architecture-dependent) standard type. Capable of
255 representing any unsigned 24-bit value, although the the actual type may
256 be wider than 24 bits.
259 Equivalent to some (architecture-dependent) standard type. Capable of
260 representing any unsigned 32-bit value, although the the actual type may
261 be wider than 32 bits.
264 Equivalent to some (architecture-dependent) standard type, if it exists.
265 Capable of representing any unsigned 64-bit value, although the the
266 actual type may be wider than 64 bits.
268 .SS "Size/endianness suffixes"
271 be one of the size suffixes: 8, 16, 24, 32, and (if available) 64.
274 be one of the size-and-endian suffixes
283 denotes little-endian (Intel, VAX) representation, and
285 denotes big-endian (IBM, network) representation; omitting an explicit
286 suffix gives big-endian order by default, since this is most common in
287 portable data formats.
291 invokes a given macro
301 invokes a given macro
304 .IR f ( w ", " we ", " suff )
307 ranges over size-and-endian suffixes as described above,
309 is just the corresponding bit width, as an integer, and
316 suitable for a C function name.
318 These macros are intended to be used to define families of related
322 For each size-and-endian suffix
324 the following macros are defined.
327 A synonym for the appropriate one of the types
333 The number of octets needed to represent a value of the corresponding
338 The largest integer representable in the corresponding type; i.e., this
340 .RI 2\*(ss w \*(se\~\-\~1.
342 (Note that the endianness suffix is irrelevant in the above
351 to the appropriate type; specifically, it returns the smallest
352 nonnegative integer congruent to
357 .SS "Shift and rotate"
360 the macro invocations
361 .BI LSL w ( x ", " n )
363 .BI LSR w ( x ", " n )
368 left or right, respectively, by
376 (This behaviour is unfortunate, but (a) it's what a number of CPUs
377 provide natively, and (b) it's a cheap way to prevent undefined
378 behaviour.) Similarly,
379 .BI ROL w ( x ", " n )
381 .BI ROR w ( x ", " n )
386 left or right, respectively, by
390 .SS "Byte order conversions"
399 with its bytes reversed. The
401 macro does nothing (except truncate its operand to 8 bits), but is
402 provided for the sake of completeness.
406 representation stores the most significant octet of an integer at the
407 lowest address, with the following octets in decreasing order of
410 representation instead stores the
412 significant octet at the lowest address, with the following octets in
413 increasing order of significance. An environment has a preferred order
414 for arranging the constituent octets of an integer of some given size in
415 memory; this might be either the big- or little-endian representation
416 just described, or something else strange.
418 It might be possible to rearrange the bits in an integer so that, when
419 that integer is stored to memory in the environment's preferred manner,
420 you end up with the big- or little-endian representation of the original
421 integer; and, similarly, it might be possible to load a big- or
422 little-endian representation of an integer into a variable using the
423 environment's preferred ordering and then rearrange the bits so as to
424 recover the integer value originally represented. If the environment is
425 sufficiently strange, these things might not be possible, but this is
428 Say that an integer has been converted to
431 .I "little-endian form"
432 if, when it is stored in memory in the environment's preferred manner,
433 one ends up with a big- or little-endian representation of the original
434 integer. Equivalently, if one starts with a big- or little-endian
435 representation of some integer, and loads it into a variable using the
436 environment's preferred manner, one ends up with the big- or
437 little-endian form of the original integer.
439 If these things are possible, then the following macros are defined.
446 to little-endian form.
460 from little-endian form.
467 from big-endian form.
471 .BI GETBYTE( p ", " o )
474 octet following the address
477 .BI PUTBYTE( p ", " o ", " v)
482 byte following the address
484 These macros always operate on byte offsets regardless of the type of
488 For each size-and-endian suffix
492 loads and returns a value in the corresponding format at address
495 .BI STORE we ( p ", " x )
500 in the corresponding format.
503 For portability to environments without native 64-bit integers, the
506 is defined. If the target platform is known to have an unsigned 64-bit
507 integer type, then this structure merely encapsulates a native integer,
508 and a decent optimizing compiler can be expected to handle this exactly
509 as if it were the native type. Otherwise, it contains two 32-bit halves
510 which are processed the hard way.
512 For each of the above macros with a suffix
517 an additional `kludge' macro is defined, whose name has an additional
518 final underscore; e.g., the kludge macro corresponding to
522 and that corresponding to
526 If the original macro would have
530 then the kludge macro has an additional first argument, denoted
532 which should be an lvalue of type
534 and the kludge macro will store its result in
536 The kludge macro's remaining arguments are the same as the original
537 macro, except that where the original macro accepts an argument of type
539 the kludge macro accepts an argument of type
543 Finally, a number of additional macros are provided, to make working
548 .BI SET64( d ", " h ", " l )
549 Set the high 32 bits of
553 and the low 32 bits to be
559 may be arbitrary integers.
561 .BI X64( hexh ", " hexl )
562 Expands to an initializer for an object of type
568 encode the high and low 32-bit halves in hexadecimal, without any
572 .BI ASSIGN( d ", " x )
580 Return the high 32 bits of
584 Return the low 32 bits of
587 .BI GET64( t ", " x )
594 is an unsigned integer type, then the value will be truncated to fit as
597 is a signed integer type, then the behaviour is undefined if the value
602 .BI AND64( d ", " x ", " y )
605 to be the bitwise-and of the two
612 .BI OR64( d ", " x ", " y )
615 to be the bitwise-or of the two
622 .BI XOR64( d ", " x ", " y )
625 to be the bitwise-exclusive-or of the two
632 .BI CPL64( d ", " x )
635 to be the bitwise complement of the
640 .BI ADD64( d ", " x ", " y )
643 to be the sum of the two
650 .BI SUB64( d ", " x ", " y )
653 to be the difference of the two
660 .BI CMP64( x ", " op ", " y )
665 should be arguments of type
669 should be one of the relational operators
683 Evaluates nonzero if the
691 Mark Wooding, <mdw@distorted.org.uk>