summaryrefslogtreecommitdiffstats
path: root/txr.1
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-05-23 11:50:47 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-05-23 11:50:47 -0700
commit4666a2fa59648e02b057038aa68fa99958f34ecf (patch)
tree18da340538e98357a3fa4dbf4abde438f274e3c4 /txr.1
parent16eb3d22a29911981371b98e83008f8741903cc8 (diff)
downloadtxr-4666a2fa59648e02b057038aa68fa99958f34ecf.tar.gz
txr-4666a2fa59648e02b057038aa68fa99958f34ecf.tar.bz2
txr-4666a2fa59648e02b057038aa68fa99958f34ecf.zip
ffi: bitfield tests and fixes.
The bitfield allocation rules are wrong. Some of it is due to the recent changes which are based on incorrect analysis, but reverting things doesn't fix it. The idea that we compare the current member's alignment with the previous is wrong; it is not borne out by empirical tests with gcc. So we do a straight revert of that. In GNU C, an __attribute__((aligned (N))) attribute applied to a bitfield member will perform the requested alignment if, evidently, the bit field is already being placed into a new byte. (If the bit field is about to be packed into an existing byte, then there is a warning about the align attribute being ignored). Because we don't have alignment as a member attribute, but only as a type attribute, we must implement a flag which indicates that a type has had align applied to it (even if the alignment didn't change) so we can then honor this in the right place in the bitfield allocation code. * ffi.c (struct txr_ffi_type): New attribute flag, aligned. (make_ffi_type_struct): Remove the prev_align variable and all related logic. Consolidate all alignment into one place, which is done before we allocate the bitfield or regular member. We align if the new member isn't a bitfield, or even if it is a bitfield if it has the aligned attribute, or if the bitfield is changing endian compared to the previous member (our local rule, not from GNU C). (ffi_type_compile): The align and pack operators now set the aligned attribute, except in the (pack 1 ...) case which semantically denotes lack of alignment. * tests/017/bitfields.tl: New file. * txr.1: Documented.
Diffstat (limited to 'txr.1')
-rw-r--r--txr.129
1 files changed, 23 insertions, 6 deletions
diff --git a/txr.1 b/txr.1
index 70904936..2ef5678d 100644
--- a/txr.1
+++ b/txr.1
@@ -81293,12 +81293,29 @@ a structure can be read or written at the misaligned offsets depends on whether
the individual members support it. If they are integer or floating-point types,
or aggregates thereof, the usage is supported in a machine-independent manner.
-Alignment interacts with bitfields. If a bitfield's type has an alignment
-different from the previous member (whether that member is a bitfield or not),
-then the bitfield is placed into a new cell, which is aligned according to
-the alignment of its own type. The alignment of bitfields, other than
-zero width bitfields, contributes to the determination of the most
-strictly aligned member of the structure.
+Alignment interacts with the allocation of bitfields in special ways. If
+.meta width
+is greater than 1, or regardless of
+.meta width
+if the operator is
+.codn align ,
+the type is marked with a Boolean attribute indicating that it has
+altered alignment. Then, when a bitfield is based on a type which has altered
+alignment, then that bitfield isn't packed together with the previous
+field, even if the allocation rules otherwise call for it. Due to the
+alignment request, the byte offset is first adjusted according to the requested
+alignment and the bit offset is reset to zero. The bit field is then allocated
+at the new alignment. This requirement applies even if the requested alignment
+is 1, which is possible via a combination of both
+.code pack
+and
+.codn align ,
+both specified with a
+.meta width
+of 1. If the requested alignment for the type of a bitfield is 1, and
+the previous member is a bitfield which has left a byte partially filled,
+then the new bitfield starts on a fresh byte, even if it would otherwise
+be packed with the previous bitfield.
When
.meta type