sys/fdpass.c: Allocate extra cmsg space to hack around a Qemu bug.
[mLib] / utils / bits.3
... / ...
CommitLineData
1.\" -*-nroff-*-
2.TH bits 3 "20 June 1999" "Straylight/Edgeware" "mLib utilities library"
3.ie t \{\
4. ds ss \s8\u
5. ds se \d\s0
6.\}
7.el \{\
8. ds ss ^
9. ds se
10.\}
11.SH NAME
12bits \- portable bit manipulation macros
13.\" octet
14.\" uint16
15.\" uint24
16.\" uint32
17.\" uint64
18.\" kludge64
19.\"
20.\" MASK_8
21.\" MASK_16
22.\" MASK_16_L
23.\" MASK_16_B
24.\" MASK_24
25.\" MASK_24_L
26.\" MASK_24_B
27.\" MASK_32
28.\" MASK_32_L
29.\" MASK_32_B
30.\" MASK_64
31.\" MASK_64_L
32.\" MASK_64_B
33.\"
34.\" SZ_8
35.\" SZ_16
36.\" SZ_16_L
37.\" SZ_16_B
38.\" SZ_24
39.\" SZ_24_L
40.\" SZ_24_B
41.\" SZ_32
42.\" SZ_32_L
43.\" SZ_32_B
44.\" SZ_64
45.\" SZ_64_L
46.\" SZ_64_B
47.\"
48.\" TY_8
49.\" TY_16
50.\" TY_16_L
51.\" TY_16_B
52.\" TY_24
53.\" TY_24_L
54.\" TY_24_B
55.\" TY_32
56.\" TY_32_L
57.\" TY_32_B
58.\" TY_64
59.\" TY_64_L
60.\" TY_64_B
61.\"
62.\" DOUINTSZ
63.\" DOUINTCONV
64.\"
65.\" @U8
66.\" @U16
67.\" @U24
68.\" @U32
69.\" @U64
70.\" @U64_
71.\"
72.\" @LSL8
73.\" @LSR8
74.\" @LSL16
75.\" @LSR16
76.\" @LSL24
77.\" @LSR24
78.\" @LSL32
79.\" @LSR32
80.\" @LSL64
81.\" @LSR64
82.\" @LSL64_
83.\" @LSR64_
84.\"
85.\" @ROL8
86.\" @ROR8
87.\" @ROL16
88.\" @ROR16
89.\" @ROL24
90.\" @ROR24
91.\" @ROL32
92.\" @ROL32
93.\" @ROL64
94.\" @ROR64
95.\" @ROL64_
96.\" @ROR64_
97.\"
98.\" ENDSWAP16
99.\" ENDSWAP32
100.\" ENDSWAP64
101.\"
102.\" BTOH16
103.\" LTOH16
104.\" HTOB16
105.\" HTOL16
106.\" BTOH32
107.\" LTOH32
108.\" HTOB32
109.\" HTOL32
110.\" BTOH64
111.\" LTOH64
112.\" HTOB64
113.\" HTOL64
114.\"
115.\" RAW8
116.\" RAW16
117.\" RAW32
118.\" RAW64
119.\"
120.\" @GETBYTE
121.\" @PUTBYTE
122.\"
123.\" @LOAD8
124.\" @STORE8
125.\"
126.\" @LOAD16_L
127.\" @LOAD16_B
128.\" @LOAD16
129.\" @STORE16_L
130.\" @STORE16_B
131.\" @STORE16
132.\"
133.\" @LOAD24_L
134.\" @LOAD24_B
135.\" @LOAD24
136.\" @STORE24_L
137.\" @STORE24_B
138.\" @STORE24
139.\"
140.\" @LOAD32_L
141.\" @LOAD32_B
142.\" @LOAD32
143.\" @STORE32_L
144.\" @STORE32_B
145.\" @STORE32
146.\"
147.\" @LOAD64_L
148.\" @LOAD64_B
149.\" @LOAD64
150.\" @STORE64_L
151.\" @STORE64_B
152.\" @STORE64
153.\"
154.\" @LOAD64_L_
155.\" @LOAD64_B_
156.\" @LOAD64_
157.\" @STORE64_L_
158.\" @STORE64_B_
159.\" @STORE64_
160.\"
161.\" @SET64
162.\" @X64
163.\" @ASSIGN64
164.\" @HI64
165.\" @LO64
166.\" @GET64
167.\" @AND64
168.\" @OR64
169.\" @XOR64
170.\" @CPL64
171.\" @ADD64
172.\" @SUB64
173.\" @CMP64
174.\" @ZERO64
175.SH SYNOPSIS
176.nf
177.B "#include <mLib/bits.h>"
178
179.BR "typedef " ... " octet;"
180.BR "typedef " ... " uint16;"
181.BR "typedef " ... " uint24;"
182.BR "typedef " ... " uint32;"
183.BR "typedef " ... " uint64;"
184.BR "typedef " ... " kludge64;"
185
186.BI "#define TY_" we " " type
187.BI "#define SZ_" we " \fR..."
188.BI "#define MASK_" we " \fR..."
189
190.BI "#define DOUINTSZ(" f ") \fR..."
191.BI "#define DOUINTCONV(" f ") \fR..."
192
193.IB type " U" w ( v );
194
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 );
199
200.BI "octet GETBYTE(void *" p ", size_t " o );
201.BI "void PUTBYTE(void *" p ", size_t " o ", octet " v );
202
203.IB type " LOAD" we "(void *" p );
204.BI "void STORE" we "(void *" p ", " type " " v );
205
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 );
220.fi
221.SH DESCRIPTION
222The header file
223.B <mLib/bits.h>
224contains a number of useful definitions for portably dealing with bit-
225and byte-level manipulation of larger quantities. The various macros
226and types are named fairly systematically.
227.PP
228The header provides utilities for working with 64-bit quantities, but a
22964-bit integer type is not guaranteed to exist under C89 rules. This
230header takes two approaches. Firstly, if a 64-bit type is found, the
231header defines the macro
232.B HAVE_UINT64
233and defines the various
234.RB ... 64
235macros as described below. Secondly, it unconditionally defines a type
236.B kludge64
237and a family of macros for working with them. See below for details.
238.
239.SS "Type definitions"
240A number of types are defined.
241.TP
242.B octet
243Equivalent to
244.BR "unsigned char" .
245This is intended to be used when a character array is used to represent
246the octets of some external data format. Note that on some
247architectures the
248.B "unsigned char"
249type may occupy more than 8 bits.
250.TP
251.B uint16
252Equivalent to
253.BR "unsigned short" .
254Intended to be used when a 16-bit value is required. This type is
255always capable of representing any 16-bit unsigned value, but the actual
256type may be wider than 16 bits and will require masking.
257.TP
258.B uint24
259Equivalent to some (architecture-dependent) standard type. Capable of
260representing any unsigned 24-bit value, although the the actual type may
261be wider than 24 bits.
262.TP
263.B uint32
264Equivalent to some (architecture-dependent) standard type. Capable of
265representing any unsigned 32-bit value, although the the actual type may
266be wider than 32 bits.
267pp.TP
268.B uint64
269Equivalent to some (architecture-dependent) standard type, if it exists.
270Capable of representing any unsigned 64-bit value, although the the
271actual type may be wider than 64 bits.
272.
273.SS "Size/endianness suffixes"
274Let
275.I w
276be one of the size suffixes: 8, 16, 24, 32, and (if available) 64.
277Furthermore, let
278.I we
279be one of the size-and-endian suffixes
280.IR w ,
281or, where
282.IR w \~>\~8,
283.IB w _L
284or
285.IB w _B \fR,
286where
287.RB ` _L '
288denotes little-endian (Intel, VAX) representation, and
289.RB ` _B '
290denotes big-endian (IBM, network) representation; omitting an explicit
291suffix gives big-endian order by default, since this is most common in
292portable data formats.
293.PP
294The macro invocation
295.BI DOUINTSZ( f )
296invokes a given macro
297.I f
298repeatedly, as
299.IB f ( w )
300for each size suffix
301.I w
302listed above.
303.PP
304The macro invocation
305.BI DOUINTCONV( f )
306invokes a given macro
307.I f
308repeatedly, as
309.IR f ( w ", " we ", " suff )
310where
311.I we
312ranges over size-and-endian suffixes as described above,
313.I w
314is just the corresponding bit width, as an integer, and
315.I suff
316is a suffix
317.IR w ,
318.IB w l\fR,
319or
320.IB w b\fR,
321suitable for a C function name.
322.PP
323These macros are intended to be used to define families of related
324functions.
325.
326.SS "Utility macros"
327For each size-and-endian suffix
328.IR we ,
329the following macros are defined.
330.TP
331.BI TY_ we
332A synonym for the appropriate one of the types
333.BR octet ,
334.BR uint32 ,
335etc.\& listed above.
336.TP
337.BI SZ_ we
338The number of octets needed to represent a value of the corresponding
339type; i.e., this is
340.IR w /8.
341.TP
342.BI MASK_ we
343The largest integer representable in the corresponding type; i.e., this
344is
345.RI 2\*(ss w \*(se\~\-\~1.
346.PP
347(Note that the endianness suffix is irrelevant in the above
348definitions.)
349.PP
350For each size suffix
351.IR w ,
352the macro invocation
353.BI U w ( x )
354coerces an integer
355.I x
356to the appropriate type; specifically, it returns the smallest
357nonnegative integer congruent to
358.I x
359(modulo
360.RI 2\*(ss w \*(se).
361.
362.SS "Shift and rotate"
363For each size suffix
364.IR w ,
365the macro invocations
366.BI LSL w ( x ", " n )
367and
368.BI LSR w ( x ", " n )
369shift a
370.IR w -bit
371quantity
372.I x
373left or right, respectively, by
374.I n
375places; if
376.IR n \~\(>=\~ w
377then
378.I n
379is reduced modulo
380.IR w .
381(This behaviour is unfortunate, but (a) it's what a number of CPUs
382provide natively, and (b) it's a cheap way to prevent undefined
383behaviour.) Similarly,
384.BI ROL w ( x ", " n )
385and
386.BI ROR w ( x ", " n )
387rotate a
388.IR w -bit
389quantity
390.I x
391left or right, respectively, by
392.I n
393places.
394.
395.SS "Byte order conversions"
396For each size suffix
397.IR w ,
398the macro invocation
399.BI ENDSWAP w ( x )
400returns the
401.IR w -bit
402value
403.IR x
404with its bytes reversed. The
405.B ENDSWAP8
406macro does nothing (except truncate its operand to 8 bits), but is
407provided for the sake of completeness.
408.PP
409A
410.I big-endian
411representation stores the most significant octet of an integer at the
412lowest address, with the following octets in decreasing order of
413significance. A
414.I little-endian
415representation instead stores the
416.I least
417significant octet at the lowest address, with the following octets in
418increasing order of significance. An environment has a preferred order
419for arranging the constituent octets of an integer of some given size in
420memory; this might be either the big- or little-endian representation
421just described, or something else strange.
422.PP
423It might be possible to rearrange the bits in an integer so that, when
424that integer is stored to memory in the environment's preferred manner,
425you end up with the big- or little-endian representation of the original
426integer; and, similarly, it might be possible to load a big- or
427little-endian representation of an integer into a variable using the
428environment's preferred ordering and then rearrange the bits so as to
429recover the integer value originally represented. If the environment is
430sufficiently strange, these things might not be possible, but this is
431actually quite rare.
432.PP
433Say that an integer has been converted to
434.I big-
435or
436.I "little-endian form"
437if, when it is stored in memory in the environment's preferred manner,
438one ends up with a big- or little-endian representation of the original
439integer. Equivalently, if one starts with a big- or little-endian
440representation of some integer, and loads it into a variable using the
441environment's preferred manner, one ends up with the big- or
442little-endian form of the original integer.
443.PP
444If these things are possible, then the following macros are defined.
445.TP
446.BI HTOL w ( x )
447Convert a
448.IR w -bit
449integer
450.I x
451to little-endian form.
452.TP
453.BI HTOB w ( x )
454Convert a
455.IR w -bit
456integer
457.I x
458to big-endian form.
459.TP
460.BI LTOH w ( x )
461Convert a
462.IR w -bit
463integer
464.I x
465from little-endian form.
466.TP
467.BI BTOH w ( x )
468Convert a
469.IR w -bit
470integer
471.I x
472from big-endian form.
473.
474.SS "Load and store"
475The macro invocation
476.BI GETBYTE( p ", " o )
477returns the
478.IR o th
479octet following the address
480.IR p .
481Conversely,
482.BI PUTBYTE( p ", " o ", " v)
483stores
484.I
485v in the
486.IR o th
487byte following the address
488.IR p .
489These macros always operate on byte offsets regardless of the type of
490the pointer
491.IR p .
492.PP
493For each size suffix
494.IR w ,
495there may be a macro such that the invocation
496.BI RAW w ( p )
497is an lvalue designating the
498.IR w /8
499octets starting at address
500.IR p ,
501interpreted according to the environment's preferred representation,
502except that
503.I p
504need not be aligned in any particular fashion. There are many reasons
505why this might not be possible; programmers are not normally expected to
506use these macros directly, and they are documented in case they are
507useful for special effects.
508.PP
509For each size-and-endian suffix
510.IR we ,
511the macro invocation
512.BI LOAD we ( p )
513loads and returns a value in the corresponding format at address
514.IR p ;
515similarly,
516.BI STORE we ( p ", " x )
517stores the value
518.I x
519at address
520.I p
521in the corresponding format.
522.
523.SS "64-bit support"
524For portability to environments without native 64-bit integers, the
525structure
526.B kludge64
527is defined. If the target platform is known to have an unsigned 64-bit
528integer type, then this structure merely encapsulates a native integer,
529and a decent optimizing compiler can be expected to handle this exactly
530as if it were the native type. Otherwise, it contains two 32-bit halves
531which are processed the hard way.
532.PP
533For each of the above macros with a suffix
534.BR 64 ,
535.BR 64_L ,
536or
537.BR 64_B ,
538an additional `kludge' macro is defined, whose name has an additional
539final underscore; e.g., the kludge macro corresponding to
540.B ROR64
541is
542.BR ROR64_ ;
543and that corresponding to
544.B LOAD64_L
545is
546.BR LOAD64_L_ .
547If the original macro would have
548.I returned
549a value of type
550.BR uint64 ,
551then the kludge macro has an additional first argument, denoted
552.IR d ,
553which should be an lvalue of type
554.BR kludge64 ,
555and the kludge macro will store its result in
556.IR d .
557The kludge macro's remaining arguments are the same as the original
558macro, except that where the original macro accepts an argument of type
559.BR uint64 ,
560the kludge macro accepts an argument of type
561.B kludge64
562instead.
563.PP
564Finally, a number of additional macros are provided, to make working
565with
566.B kludge64
567somewhat less awful.
568.TP
569.BI SET64( d ", " h ", " l )
570Set the high 32 bits of
571.I d
572to be
573.IR h ,
574and the low 32 bits to be
575.IR l .
576Both
577.I h
578and
579.I l
580may be arbitrary integers.
581.TP
582.BI X64( hexh ", " hexl )
583Expands to an initializer for an object of type
584.B kludge64
585where
586.I hexh
587and
588.I hexl
589encode the high and low 32-bit halves in hexadecimal, without any
590.B 0x
591prefix.
592.TP
593.BI ASSIGN( d ", " x )
594Make
595.I d
596be a copy of the
597.B kludge64
598.IR x .
599.TP
600.BI HI64( x )
601Return the high 32 bits of
602.IR x .
603.TP
604.BI LO64( x )
605Return the low 32 bits of
606.IR x .
607.TP
608.BI GET64( t ", " x )
609Return the value of
610.I x
611as a value of type
612.IR t .
613If
614.I t
615is an unsigned integer type, then the value will be truncated to fit as
616necessary; if
617.I t
618is a signed integer type, then the behaviour is undefined if the value
619of
620.I x
621is too large.
622.TP
623.BI AND64( d ", " x ", " y )
624Set
625.I d
626to be the bitwise-and of the two
627.B kludge64
628arguments
629.I x
630and
631.IR y .
632.TP
633.BI OR64( d ", " x ", " y )
634Set
635.I d
636to be the bitwise-or of the two
637.B kludge64
638arguments
639.I x
640and
641.IR y .
642.TP
643.BI XOR64( d ", " x ", " y )
644Set
645.I d
646to be the bitwise-exclusive-or of the two
647.B kludge64
648arguments
649.I x
650and
651.IR y .
652.TP
653.BI CPL64( d ", " x )
654Set
655.I d
656to be the bitwise complement of the
657.B kludge64
658argument
659.IR x .
660.TP
661.BI ADD64( d ", " x ", " y )
662Set
663.I d
664to be the sum of the two
665.B kludge64
666arguments
667.I x
668and
669.IR y .
670.TP
671.BI SUB64( d ", " x ", " y )
672Set
673.I d
674to be the difference of the two
675.B kludge64
676arguments
677.I x
678and
679.IR y .
680.TP
681.BI CMP64( x ", " op ", " y )
682Here,
683.I x
684and
685.I y
686should be arguments of type
687.B kludge64
688and
689.I op
690should be one of the relational operators
691.BR == ,
692.BR < ,
693.BR <= ,
694.BR > ,
695or
696.B >=
697\(en
698.I not
699.BR !=.
700Evaluates nonzero if
701.IR x \~ op \~ y .
702.TP
703.BI ZERO64( x )
704Evaluates nonzero if the
705.B kludge64
706argument
707.I x
708is exactly zero.
709.SH "SEE ALSO"
710.BR mLib (3).
711.SH AUTHOR
712Mark Wooding, <mdw@distorted.org.uk>
713