Bit field differences

utzoo!decvax!harpo!floyd!vax135!ariel!houti!hogpc!houxm!npois!npoiv!alice!mhtsa!eagle!mit-vax!masscomp!tjt utzoo!decvax!harpo!floyd!vax135!ariel!houti!hogpc!houxm!npois!npoiv!alice!mhtsa!eagle!mit-vax!masscomp!tjt
Sat Apr 9 08:01:13 AEST 1983


I presume that the intent of assigning bit fields from left to right
on pdp-11's and right to left on other machines is to match the order
of bytes within larger integers.  This is certainly the
interpretation of PCC, in which #ifdef RTOLBYTES surrounds much of
the code dealing with bit fields.

This makes bit fields unportable for retro-fitting code whose
specifications are defined in terms of shifts and masks. An example
of this is <wait.h> in 4BSD which declares a structure using bit
fields as returned by the wait system call -- the fields have to be
declared in reverse order using PCC on a MC68000.  It should also be
emphasized that the portability problem here arises only because the
wait system call is described as returning information in the "low
order bits" and the "high order 8 bits" (from System III).  There
would be no problem if the bit field declarations were used
exclusively.  As an example of this, ld with vax-style symbols tables
(declared using bit fields) works fine on a 68000, at least for
object files generated on a 68000.  It's true that the bit field
order messes up the relocation information, but the byte order also
messes up the header and just about everything else in the object
file.

Unfortunately, having made this concession to portability (presumably
in the interest of efficiency), PCC doesn't go far enough.  The C
reference manual (p196 in Kernighan and Ritchie) states that:

	Field members are packed into machine integers; they do
	not straddle words.  A field which does not fit into the
	space remaining in a word is put into the next word.

and in the explanatory text (p137) "A field is a set of adjacent bits
within a single int." and later (p138) "A field may not overlap an
int boundary; if the width would cause this to happen, the field is
aligned at the next int boundary."

The code in PCC for dealing with bit fields in the absence of special
hardware does generate the obvious shifts and masks, operating on
values of data type int.  However, it does not pad out the next
non-field element of a structure to start at an int boundary, nor
does it align the first field element specially.  If it did, there
should have been little problem with defining bit fields to always go
from left to right or right to left (transforming positions of bit
fields to accomodate particular machine architectures can be done at
compile time since field widths are all constants).

As it is, PCC generates code which touches e.g. 32 bits in order to
change 1 bit. On 68000's (at least for the next year or two until the
68020 comes out), it is significantly more expensive to touch all
these bits than it is to touch say 16 or 8 bits.  There is an even
bigger problem if you attempt to use bit fields to access device
registers where reading and writing memory can have side effects even
if the "value" wasn't changed.  This was noticed at Stanford, where
the MIT PCC/68000 compiler was modified to access fields as a short
(16-bits) if possible (I don't know if the modifications were
incorporated into later versions of the compiler distributed by MIT).

The logical extension of this would be to access fields as char's
(8-bits) if possible as well, and in general, to treat a field
declared as char:8, short:16 and int:32 as much like structure
elements of type char, short and int respectively.  Obviously, these
field widths are machine dependent.  Also, these declarations can't
be equivalent since you can take the address of a structure element
of type char, but not of a bit field.  This is also the only place
where I can see the advantage of assigning bit fields in the same
order as bytes since assigning bits from right to left on a machine
where bytes are numbered from left to right would require knowing
where the right end of the whatever was. i.e. the next non-field
element of the structure.

Since the portability of bit fields is only a problem for binary
objects, and only where byte order is also a portability problem, I
think the only change that should be made is to get the compilers to
generate better code.



More information about the Comp.lang.c mailing list