Define a bitvector type with accessors for its fields.
This macto defines a bitstruct type. A bitstruct can either be a base type, which is a single fixed-width integer, or a product type containing fields that are bits, Booleans, or other bitstructs. Such a product is represented as a single integer produced by concatenating all the fields together, where the first field is least significant.
A bitstruct can be made up of single bits and Booleans. (The difference is
only in the return type of the accessors and the input type of the updaters;
the representation is the same.) The fields are ordered LSB first, so
(defbitstruct foo ((a bitp) (b booleanp) (c bitp)))
A bitstruct can also contain fields that are other bitstructs. Here, the
first field is a
(defbitstruct bar ((myfoo foo-p) (b booleanp) (c bitp)) :signedp t)
A bitstruct can also be defined without any fields, giving only a width. These are mainly useful as fields of other bitstructs. This makes sense when the individual bits aren't meaningful, and their combined value is what's important. This defines a rounding-control as a 2-bit unsigned value.
(defbitstruct rounding-control 2)
Sometimes we may want to nest one bitstruct inside another, but also
directly access the fields of the internal struct. Providing the
(defbitstruct fp-flags ((ie bitp) (de bitp) (ze bitp) (oe bitp) (ue bitp) (pe bitp))) (defbitstruct mxcsr ((flags fp-flags :subfields (ie de ze oe ue pe)) (daz bitp) (masks fp-flags :subfields (im dm zm om um pm)) (rc rounding-control) (ftz bitp)))
(defbitstruct typename fields [ options ] )
(defbitstruct typename width [ options ] ).
The syntax of fields is described below.
A field has the following form:
(fieldname type [ docstring ] [ options ... ] )
The type can be either a predicate or type name, i.e.,
subfield_entry ::= name | ( name ( subfield_entry ... ) )
Each top-level entry corresponds to a subfield of the field type. If the entry uses the second syntax, which itself has a list of entries, those entries correspond to sub-subfields of the subfield type. For example:
(defbitstruct innermost ((aa bitp) (bb bitp))) (defbitstruct midlevel ((ii innermost :subfields (iaa ibb)) (qq bitp) (jj innermost :subfields (jaa jbb)))) (defbitstruct toplevel ((ss innermost :subfields (saa sbb)) (tt midlevel :subfields ((tii (tiaa tibb)) tqq tjj))))
(toplevel->saa x) == (innermost->aa (toplevel->ss x)) (toplevel->sbb x) == (innermost->bb (toplevel->ss x)) (toplevel->tii x) == (midlevel->ii (toplevel->ss x)) (toplevel->tiaa x) == (innermost->aa (midlevel->ii (toplevel->tt x))) (toplevel->tibb x) == (innermost->bb (midlevel->ii (toplevel->tt x))) (toplevel->tqq x) == (midlevel->qq (toplevel->tt x)) (toplevel->tjj x) == (midlevel->jj (toplevel->tt x))