On 08/17/14 11:24, Timo Sintonen via D.gnu wrote: > On Sunday, 17 August 2014 at 07:57:15 UTC, Timo Sintonen wrote: >> >> >> This seems to work. >> > > This does not work with member functions > > 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; > } > > } > > In this function the fetch of sr is omitted but compare is still > made against an invalid register value. Then address of dr is > omitted and store is made from wrong register to invalid address. > So the generated code is totally invalid. > > If I move this function out of the struct then it is ok. > I use -O2, not tested what it woud do without optimization.
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