On Sunday, 17 August 2014 at 11:35:33 UTC, Artur Skawina via D.gnu wrote:

It works for me:

import volat; // module w/ the last Volatile(T) implementation.

   struct uartreg {
       Volatile!int sr;
       Volatile!int dr;
       Volatile!int brr;
       Volatile!int cr1;
       Volatile!int cr2;
       Volatile!int cr3;
       Volatile!int gtpr;

       // send a byte to the uart
       void send(int t) {
         while ((sr&0x80)==0)
         {  }
         dr=t;
       }
   }

   enum uart = cast(uartreg*)0xDEADBEAF;

   void main() {
      uart.send(42);
   }

=>

0000000000403620 <_Dmain>:
  403620:       b8 af be ad de          mov    $0xdeadbeaf,%eax
  403625:       0f 1f 00                nopl   (%rax)
  403628:       b9 af be ad de          mov    $0xdeadbeaf,%ecx
  40362d:       8b 11                   mov    (%rcx),%edx
  40362f:       81 e2 80 00 00 00       and    $0x80,%edx
403635: 74 f1 je 403628 <_Dmain+0x8>
  403637:       bf b3 be ad de          mov    $0xdeadbeb3,%edi
  40363c:       31 c0                   xor    %eax,%eax
  40363e:       c7 07 2a 00 00 00       movl   $0x2a,(%rdi)
  403644:       c3                      retq

Except for some obviously missed optimizations (dead eax load,
unnecessary ecx reload), the code seems fine. What platform
are you using and what does the emitted code look like?

Also if I have:
cr1=cr2=0;
I get: expression this.cr2.opAssign(0) is void and has no value

That's because the opAssign returns void, which prevents this
kind of chaining. This was a deliberate choice, as I /wanted/ to
disallow that; it's already a bad idea for normal assignments;
for volatile ones, which can require a specific order, it's an
even worse one.
But it's trivial to "fix", just change

   void opAssign(A)(A a) { volatile_store(raw, a); }

to

   T opAssign(A)(A a) { volatile_store(raw, a); return a; }

artur

I am compiling for arm and I am sorry I misinterpreted the optimized code. Actually the code is correct but it still does not work. The problem is that the call to get the tls pointer for volatile_dummy seems to corrupt the register (r3) where the this pointer is. The call is inside the while loop. After removing tha call by hand in the assembly everything works. R3 is usually pushed into stack when it is used in a function. I have to check what is wrong in this case.

Reply via email to