2 .TH bits 3 "20 June 1999" "Straylight/Edgeware" "mLib utilities library"
12 bits \- portable bit manipulation macros
177 .B "#include <mLib/bits.h>"
179 .BR "typedef " ... " octet;"
180 .BR "typedef " ... " uint16;"
181 .BR "typedef " ... " uint24;"
182 .BR "typedef " ... " uint32;"
183 .BR "typedef " ... " uint64;"
184 .BR "typedef " ... " kludge64;"
186 .BI "#define TY_" we " " type
187 .BI "#define SZ_" we " \fR..."
188 .BI "#define MASK_" we " \fR..."
190 .BI "#define DOUINTSZ(" f ") \fR..."
191 .BI "#define DOUINTCONV(" f ") \fR..."
193 .IB type " U" w ( v );
195 .IB type " LSL" w ( type " " v ", int " s );
196 .IB type " LSR" w ( type " " v ", int " s );
197 .IB type " ROL" w ( type " " v ", int " s );
198 .IB type " ROR" w ( type " " v ", int " s );
200 .BI "octet GETBYTE(void *" p ", size_t " o );
201 .BI "void PUTBYTE(void *" p ", size_t " o ", octet " v );
203 .IB type " LOAD" we "(void *" p );
204 .BI "void STORE" we "(void *" p ", " type " " v );
206 .BI "void SET64(kludge64 &" d ", uint32 " h ", uint32 " l );
207 .BI "kludge64 X64(" hexh ", " hexl );
208 .BI "void ASSIGN64(kludge64 &" d ", " x );
209 .BI "uint32 HI64(kludge64" x );
210 .BI "uint32 LO64(kludge64" x );
211 .IB ty " GET64(" ty ", kludge64 " x );
212 .BI "void AND64(kludge64 &" d ", kludge64 " x ", kludge64 " y );
213 .BI "void OR64(kludge64 &" d ", kludge64 " x ", kludge64 " y );
214 .BI "void XOR64(kludge64 &" d ", kludge64 " x ", kludge64 " y );
215 .BI "void CPL64(kludge64 &" d ", kludge64 " x );
216 .BI "void ADD64(kludge64 &" d ", kludge64 " x ", kludge64 " y );
217 .BI "void SUB64(kludge64 &" d ", kludge64 " x ", kludge64 " y );
218 .BI "int CMP64(kludge64 " x ", " op ", kludge64 " y );
219 .BI "int ZERO64(kludge64 " x );
224 contains a number of useful definitions for portably dealing with bit-
225 and byte-level manipulation of larger quantities. The various macros
226 and types are named fairly systematically.
228 The header provides utilities for working with 64-bit quantities, but a
229 64-bit integer type is not guaranteed to exist under C89 rules. This
230 header takes two approaches. Firstly, if a 64-bit type is found, the
231 header defines the macro
233 and defines the various
235 macros as described below. Secondly, it unconditionally defines a type
237 and a family of macros for working with them. See below for details.
239 .SS "Type definitions"
240 A number of types are defined.
244 .BR "unsigned char" .
245 This is intended to be used when a character array is used to represent
246 the octets of some external data format. Note that on some
249 type may occupy more than 8 bits.
253 .BR "unsigned short" .
254 Intended to be used when a 16-bit value is required. This type is
255 always capable of representing any 16-bit unsigned value, but the actual
256 type may be wider than 16 bits and will require masking.
259 Equivalent to some (architecture-dependent) standard type. Capable of
260 representing any unsigned 24-bit value, although the the actual type may
261 be wider than 24 bits.
264 Equivalent to some (architecture-dependent) standard type. Capable of
265 representing any unsigned 32-bit value, although the the actual type may
266 be wider than 32 bits.
269 Equivalent to some (architecture-dependent) standard type, if it exists.
270 Capable of representing any unsigned 64-bit value, although the the
271 actual type may be wider than 64 bits.
273 .SS "Size/endianness suffixes"
276 be one of the size suffixes: 8, 16, 24, 32, and (if available) 64.
279 be one of the size-and-endian suffixes
288 denotes little-endian (Intel, VAX) representation, and
290 denotes big-endian (IBM, network) representation; omitting an explicit
291 suffix gives big-endian order by default, since this is most common in
292 portable data formats.
296 invokes a given macro
306 invokes a given macro
309 .IR f ( w ", " we ", " suff )
312 ranges over size-and-endian suffixes as described above,
314 is just the corresponding bit width, as an integer, and
321 suitable for a C function name.
323 These macros are intended to be used to define families of related
327 For each size-and-endian suffix
329 the following macros are defined.
332 A synonym for the appropriate one of the types
338 The number of octets needed to represent a value of the corresponding
343 The largest integer representable in the corresponding type; i.e., this
345 .RI 2\*(ss w \*(se\~\-\~1.
347 (Note that the endianness suffix is irrelevant in the above
356 to the appropriate type; specifically, it returns the smallest
357 nonnegative integer congruent to
362 .SS "Shift and rotate"
365 the macro invocations
366 .BI LSL w ( x ", " n )
368 .BI LSR w ( x ", " n )
373 left or right, respectively, by
381 (This behaviour is unfortunate, but (a) it's what a number of CPUs
382 provide natively, and (b) it's a cheap way to prevent undefined
383 behaviour.) Similarly,
384 .BI ROL w ( x ", " n )
386 .BI ROR w ( x ", " n )
391 left or right, respectively, by
395 .SS "Byte order conversions"
404 with its bytes reversed. The
406 macro does nothing (except truncate its operand to 8 bits), but is
407 provided for the sake of completeness.
411 representation stores the most significant octet of an integer at the
412 lowest address, with the following octets in decreasing order of
415 representation instead stores the
417 significant octet at the lowest address, with the following octets in
418 increasing order of significance. An environment has a preferred order
419 for arranging the constituent octets of an integer of some given size in
420 memory; this might be either the big- or little-endian representation
421 just described, or something else strange.
423 It might be possible to rearrange the bits in an integer so that, when
424 that integer is stored to memory in the environment's preferred manner,
425 you end up with the big- or little-endian representation of the original
426 integer; and, similarly, it might be possible to load a big- or
427 little-endian representation of an integer into a variable using the
428 environment's preferred ordering and then rearrange the bits so as to
429 recover the integer value originally represented. If the environment is
430 sufficiently strange, these things might not be possible, but this is
433 Say that an integer has been converted to
436 .I "little-endian form"
437 if, when it is stored in memory in the environment's preferred manner,
438 one ends up with a big- or little-endian representation of the original
439 integer. Equivalently, if one starts with a big- or little-endian
440 representation of some integer, and loads it into a variable using the
441 environment's preferred manner, one ends up with the big- or
442 little-endian form of the original integer.
444 If these things are possible, then the following macros are defined.
451 to little-endian form.
465 from little-endian form.
472 from big-endian form.
476 .BI GETBYTE( p ", " o )
479 octet following the address
482 .BI PUTBYTE( p ", " o ", " v)
487 byte following the address
489 These macros always operate on byte offsets regardless of the type of
495 there may be a macro such that the invocation
497 is an lvalue designating the
499 octets starting at address
501 interpreted according to the environment's preferred representation,
504 need not be aligned in any particular fashion. There are many reasons
505 why this might not be possible; programmers are not normally expected to
506 use these macros directly, and they are documented in case they are
507 useful for special effects.
509 For each size-and-endian suffix
513 loads and returns a value in the corresponding format at address
516 .BI STORE we ( p ", " x )
521 in the corresponding format.
524 For portability to environments without native 64-bit integers, the
527 is defined. If the target platform is known to have an unsigned 64-bit
528 integer type, then this structure merely encapsulates a native integer,
529 and a decent optimizing compiler can be expected to handle this exactly
530 as if it were the native type. Otherwise, it contains two 32-bit halves
531 which are processed the hard way.
533 For each of the above macros with a suffix
538 an additional `kludge' macro is defined, whose name has an additional
539 final underscore; e.g., the kludge macro corresponding to
543 and that corresponding to
547 If the original macro would have
551 then the kludge macro has an additional first argument, denoted
553 which should be an lvalue of type
555 and the kludge macro will store its result in
557 The kludge macro's remaining arguments are the same as the original
558 macro, except that where the original macro accepts an argument of type
560 the kludge macro accepts an argument of type
564 Finally, a number of additional macros are provided, to make working
569 .BI SET64( d ", " h ", " l )
570 Set the high 32 bits of
574 and the low 32 bits to be
580 may be arbitrary integers.
582 .BI X64( hexh ", " hexl )
583 Expands to an initializer for an object of type
589 encode the high and low 32-bit halves in hexadecimal, without any
593 .BI ASSIGN( d ", " x )
601 Return the high 32 bits of
605 Return the low 32 bits of
608 .BI GET64( t ", " x )
615 is an unsigned integer type, then the value will be truncated to fit as
618 is a signed integer type, then the behaviour is undefined if the value
623 .BI AND64( d ", " x ", " y )
626 to be the bitwise-and of the two
633 .BI OR64( d ", " x ", " y )
636 to be the bitwise-or of the two
643 .BI XOR64( d ", " x ", " y )
646 to be the bitwise-exclusive-or of the two
653 .BI CPL64( d ", " x )
656 to be the bitwise complement of the
661 .BI ADD64( d ", " x ", " y )
664 to be the sum of the two
671 .BI SUB64( d ", " x ", " y )
674 to be the difference of the two
681 .BI CMP64( x ", " op ", " y )
686 should be arguments of type
690 should be one of the relational operators
704 Evaluates nonzero if the
712 Mark Wooding, <mdw@distorted.org.uk>