Proposal: allow load/store widths for a pointer to be specified, like alignment #5591
Labels
proposal
This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone
In embedded development, sometimes certain areas of memory can only be correctly read from/written to using memory access instructions of specific widths. For example, the Game Boy Advance's VRAM must always be written in units of 2 bytes or greater. C programs often deal with these limitations using inline assembly, or by writing functions that use
volatile
like:This works, but it has some drawbacks. The use of
volatile
unnecessarily restricts the compiler from doing things like combining two stores of adjacent VRAM addresses into one halfword store. It's also challenging to safely use structs located in VRAM with this approach.Zig could solve this problem by adding a new set of attributes to pointers:
loadwidth
andstorewidth
. So a pointer to a byte in VRAM could have the type*loadwidth(1, 2, 4) storewidth(2, 4) u8
, and the compiler would guarantee that writing to the pointer would never result in a single-byte store instruction. In the simplest case, attempting to write a single byte to a singlestorewidth
-restricted pointer would generate a read/modify/write sequence similarly to a packed struct member pointer. But the compiler would be free to remove, reorder, or combine writes so long as it never generated a single-byte write. (Any reads/writes throughloadwidth
/storewidth
-restricted pointers would also need to be aligned to the minimum permitted load/store width.)Like packed struct member pointers, you wouldn't be able to pass a
loadwidth
/storewidth
-restricted pointer to a function expecting a regular pointer. Instead, the following type-conversion rules would apply:loadwidth
orstorewidth
isn't specified, any load or store width is permitted.const
pointers, no store width is ever permitted.*const loadwidth(2) u8
, you can pass a*u8
, but you can't pass a*loadwidth(1) u8
.@ptrCast
, you can add or remove permitted load/store widths arbitrarily.A related proposal is #5049, which suggests creating a kind of struct that guarantees the size of its loads/stores with the same kind of read/modify/write behavior I suggest. But it always restricts the loads/stores to a single width -- the size of the struct -- which isn't always what you want. (
setVramByte
is a little bit shorter on ARM when you use a single-byte load, but the store always has to be two bytes.)The text was updated successfully, but these errors were encountered: