Open ManDeJan opened 6 years ago
Thank you for writing this up 👍
I think this behavior is exactly what ManDeJan asked for. The compiler has no idea that the reserved field should be written as zeros, and can't assume that. He asked for a single field to be modified and that is exactly what it did.
The behavior would be the same in C as well.
Here are some commented examples in godbolt. https://zig.godbolt.org/z/WqFNHB
I work in embedded, but mostly my projects have been using the MSP430. In that architecture, the supplied header files do not define memory mapped registers using structs, probably for this reason. Also, I highly disagree that the compiler should be able to reorder accesses to memory through volatile pointers. That is kind of the point of volatile. I do think that the ability to have read only or write only pointers is a good idea. The compilers for embedded architectures always have to include their own intrinsics to enforce that behavior.
I highly disagree that the compiler should be able to reorder accesses to memory through volatile pointers. That is kind of the point of volatile.
It's not able to do this now, and it won't be able to do it in the future, because as you say, that is the point.
Hello, we discussed this shortly on the live stream yesterday, but here is a more detailed issue so we can write everything down.
Right now if you have a struct that represents a special function register (SFR) on an embedded chip and you have a pointer with the type of that struct pointing to a location in memory. You need to make that pointer volatile in order to guarentee the SFR is written to. Often the SFR's are write only memory (or read only) and because the pointer is marked volatile, the SFR is accessed via the pointer, the generated assembly first reads the write only memory, than orrs that with the value the value you want to write before writing the value. This is inefficient and undefined behavior on many chips.
Here is an example of inefficient (arm thumb) assembly generated: code:
assembly:
this is what optimal assembly would look like:
We discussed some ways of solving this problem yesterday which where: Solving it as has been done by this C++ library. That uses template meta programming to merge and reorder writes to registers. I think this is very possible to do with the metaprogramming that zig supports
Another option would be to expand volatile semantics and add something along the lines of
volatiler
volatilew
that specify the read or write-onlyness of the memory. This would still not allow the compiler to reorder or merge accesses to a register, so if you would want that functionality you would need to write some compiletime library yourself anyway.There are some other questions that remain.
volatiler
?, Are there cases where there are write instructions generated if you mark a read only register as normalvolatile
?