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

Iain Buclaw ibuclaw at ubuntu.com
Thu Oct 24 06:22:40 PDT 2013


On 24 October 2013 12:50, Daniel Murphy <yebblies at nospamgmail.com> wrote:
> "Mike" <none at none.com> wrote in message
> news:bifrvifzrhgocrejepvc at forum.dlang.org...
>> I've read a few discussions on the D forums about the volatile keyword
>> debate, but noone seemed to reconcile the need for volatile in
>> memory-mapped IO.  Was this an oversight?
>>
>> What's D's answer to this?  If one were to use D to read from
>> memory-mapped IO, how would one ensure the compiler doesn't cache the
>> value?
>
> There are a few options:
>
> 1. Use shared in place of volatile.  I'm not sure this actually works, but
> otherwise this is pretty good.
>
> 2. Use the deprecated volatile statement.  D got it right that volatile
> access is a property of the load/store and not the variable, but missed the
> point that it's a huge pain to have to remember volatile at use.  Could be
> made better with a wrapper.  I think this still works.
>
> 3. Use inline assembly.  This sucks.
>
> 4. Defeat the optimizer with inline assembly.
>
> asm { nop; } // Haha, gotcha
> *my_hardware_register = 999;
> asm { nop; }
>
> This might be harder with gdc/ldc than it is with dmd, but I'm pretty sure
> there's a way to trick it into thinking an asm block could clobber/read
> arbitrary memory.
>

In gdc:
---
asm {"" ::: "memory";}

An asm instruction without any output operands will be treated
identically to a volatile asm instruction in gcc, which indicates that
the instruction has important side effects.  So it creates a point in
the code which may not be deleted (unless it is proved to be
unreachable).

The "memory" clobber will tell the backend to not keep memory values
cached in registers across the assembler instruction and not optimize
stores or loads to that memory.  (That does not prevent a CPU from
reordering loads and stores with respect to another CPU, though; you
need real memory barrier instructions for that.)


-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';


More information about the Digitalmars-d mailing list