On 2/1/2015 9:48 PM, Walter Bright wrote:
On 2/1/2015 9:21 PM, Daniel Murphy wrote:
   struct Ports {
     static ubyte B() { return volatileLoad(cast(ubyte *)0x0025); }
     static void B(ubyte value) { volatileStore(cast(ubyte *)0x0025, value); }
   }

A somewhat more refined version:

  import core.bitop;

  template Ports(T, uint address) {
    @property T B() { return volatileLoad(cast(T *)address); }
    @property void B(T value) { volatileStore(cast(T *)address, value); }
  }

  alias Ports!(uint, 0x1234) MyPort;

  uint test(uint x) {
   MyPort.B(x);
   MyPort.B(x);
   return MyPort.B();
  }

Compiling with:

  dmd -c foo -O -release -inline

gives:

  _D3foo4testFkZk:
            push    EAX
            mov     ECX,01234h
            mov     [ECX],EAX
            mov     [ECX],EAX   // the redundant store was not optimized away!
            mov     EAX,[ECX]   // nor was the common subexpression removed
            add     ESP,4
            ret

See the volatile semantics noted in the comments.

Reply via email to