ARM bare-metal programming in D (cont) - volatile

Walter Bright newshound2 at digitalmars.com
Mon Oct 28 09:11:54 PDT 2013


On 10/28/2013 12:49 AM, Russel Winder wrote:
> On Sun, 2013-10-27 at 02:12 -0700, Walter Bright wrote:
> […]
>> Bitfield code generation for C compilers has generally been rather crappy. If
>> you wanted performant code, you always had to do the masking yourself.
>
> Endianism and packing have always been the bête noir of bitfields due to
> it not being part of the standard but left as compiler specific – sort
> of essentially in a way due to the vast difference in targets. Given a
> single compiler for a given target I never found the generated code
> poor. Using the UNIX compiler in early 1980s and the AVR compiler suites
> we used in the 2000s generated code always seemed fine. What's your
> evidence for hand crafted code being better than compiler generated
> code?

Generally the shifting is unnecessary, but the compiler doesn't know that as the 
spec says the values need to be right-justified. Also, I often set/reset/test 
many fields at once - doesn't work to well with bitfields.

Endianism should not be an issue if you're dealing with MMIO, since MMIO is 
going to be extremely target-specific and hence so is your code to deal with it.


>> I've written device drivers, and have designed, built, and programmed single
>> board computers. I've never found dealing with the oddities of memory mapped I/O
>> and bit flags to be of any difficulty.
>
> But don't you find:
>
> 	*x = (1 << 7) & (1 << 9)
>
> to lead directly to the use of macros:
>
> 	SET_SOMETHING_READY(x)
>
> to hide the lack of immediacy of comprehension of the purpose of the
> expression?

My bit code usually looks like:

       x |= FLAG_X | FLAG_Y;
       x &= ~(FLAG_Y | FLAG_Z);
       if (x & (FLAG_A | FLAG_B)) ...

You'll find stuff like that all through the dmd source code :-)


>> Do you really find & and | operations to be ugly? I don't find them any uglier
>> than + and *. Maybe that's because of my hardware background.
>
> It's not the operations that are the problem, it is the expressions
> using them that lead to code that is the antithesis of self-documenting.
> Almost all code using <<, >>, & and | invariable ends up being replaced
> with macros in C and C++ so as to avoid using functions.
>
> The core point here is that this sort of code fails as soon as a
> function call is involved, functions cannot be used as a tool of
> abstraction. At least with C and C++.

I thought that with modern inlining, this was no longer an issue.


> Clearly D has a USP over C and C++ here in that macros can be replaced
> by CTFE. But how to guarantee that a function is fully evaluated at
> compile time and not allowed to generate a function call. Only then can
> functions be used instead of macros to make such code self documenting.

     enum X = foo(args);

guarantees that foo(args) is evaluated at compile time. I.e. in any context that 
requires a value at compile time guarantees that it will get evaluated at 
compile time. If it is not required at compile time, it will not attempt CTFE on it.



More information about the Digitalmars-d mailing list