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.