sys/fdpass.c: Allocate extra cmsg space to hack around a Qemu bug.
[mLib] / utils / bits.3
CommitLineData
b6b9d458 1.\" -*-nroff-*-
fbf20b5b 2.TH bits 3 "20 June 1999" "Straylight/Edgeware" "mLib utilities library"
a9779382
MW
3.ie t \{\
4. ds ss \s8\u
5. ds se \d\s0
6.\}
7.el \{\
8. ds ss ^
9. ds se
10.\}
b6b9d458 11.SH NAME
12bits \- portable bit manipulation macros
a9779382
MW
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.\"
08da152e 65.\" @U8
66.\" @U16
a9779382 67.\" @U24
08da152e 68.\" @U32
a9779382
MW
69.\" @U64
70.\" @U64_
08da152e 71.\"
72.\" @LSL8
73.\" @LSR8
74.\" @LSL16
75.\" @LSR16
a9779382
MW
76.\" @LSL24
77.\" @LSR24
08da152e 78.\" @LSL32
79.\" @LSR32
a9779382
MW
80.\" @LSL64
81.\" @LSR64
82.\" @LSL64_
83.\" @LSR64_
08da152e 84.\"
85.\" @ROL8
86.\" @ROR8
87.\" @ROL16
88.\" @ROR16
a9779382
MW
89.\" @ROL24
90.\" @ROR24
91.\" @ROL32
08da152e 92.\" @ROL32
a9779382
MW
93.\" @ROL64
94.\" @ROR64
95.\" @ROL64_
96.\" @ROR64_
08da152e 97.\"
374bb459
MW
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.\"
a23bab96
MW
115.\" RAW8
116.\" RAW16
117.\" RAW32
118.\" RAW64
119.\"
08da152e 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.\"
a9779382
MW
133.\" @LOAD24_L
134.\" @LOAD24_B
135.\" @LOAD24
136.\" @STORE24_L
137.\" @STORE24_B
138.\" @STORE24
139.\"
08da152e 140.\" @LOAD32_L
141.\" @LOAD32_B
142.\" @LOAD32
143.\" @STORE32_L
144.\" @STORE32_B
145.\" @STORE32
146.\"
a9779382
MW
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
b6b9d458 175.SH SYNOPSIS
176.nf
177.B "#include <mLib/bits.h>"
178
a9779382
MW
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..."
b6b9d458 189
a9779382
MW
190.BI "#define DOUINTSZ(" f ") \fR..."
191.BI "#define DOUINTCONV(" f ") \fR..."
b6b9d458 192
a9779382 193.IB type " U" w ( v );
b6b9d458 194
a9779382
MW
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 );
b6b9d458 199
a9779382
MW
200.BI "octet GETBYTE(void *" p ", size_t " o );
201.BI "void PUTBYTE(void *" p ", size_t " o ", octet " v );
b6b9d458 202
a9779382
MW
203.IB type " LOAD" we "(void *" p );
204.BI "void STORE" we "(void *" p ", " type " " v );
b6b9d458 205
a9779382
MW
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 );
b6b9d458 220.fi
221.SH DESCRIPTION
222The header file
223.B <mLib/bits.h>
224contains a number of useful definitions for portably dealing with bit-
a9779382
MW
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.
b6b9d458 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
a9779382
MW
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
b6b9d458 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.
a9779382
MW
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.
b6b9d458 293.PP
a9779382
MW
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.
b6b9d458 303.PP
a9779382
MW
304The macro invocation
305.BI DOUINTCONV( f )
306invokes a given macro
307.I f
308repeatedly, as
309.IR f ( w ", " we ", " suff )
b6b9d458 310where
a9779382
MW
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,
b6b9d458 319or
a9779382
MW
320.IB w b\fR,
321suitable for a C function name.
b6b9d458 322.PP
a9779382
MW
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 )
b6b9d458 367and
a9779382
MW
368.BI LSR w ( x ", " n )
369shift a
370.IR w -bit
371quantity
372.I x
373left or right, respectively, by
b6b9d458 374.I n
a9779382
MW
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 )
b6b9d458 385and
a9779382
MW
386.BI ROR w ( x ", " n )
387rotate a
388.IR w -bit
389quantity
390.I x
391left or right, respectively, by
b6b9d458 392.I n
a9779382
MW
393places.
394.
374bb459
MW
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.
a9779382
MW
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
a23bab96
MW
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
a9779382
MW
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 ,
b6b9d458 536or
a9779382
MW
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
b6b9d458 630and
a9779382
MW
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.
08da152e 709.SH "SEE ALSO"
710.BR mLib (3).
b6b9d458 711.SH AUTHOR
9b5ac6ff 712Mark Wooding, <mdw@distorted.org.uk>
b6b9d458 713