Am Sat, 25 Apr 2015 18:31:45 +0000 schrieb "Jens Bauer" <doc...@who.no>:
> On Saturday, 25 April 2015 at 17:58:59 UTC, Timo Sintonen wrote: > > On Saturday, 25 April 2015 at 17:04:18 UTC, Jens Bauer wrote: > > > >> I think volatileLoad and volatileStore are intended for this > >> (please correct me if my understanding is wrong). > >> > > Yes. Actually I am not sure whether they already exist in gdc > > or not. > > > > Try to write for example > > regs.cmdr |= 0x20 > > with these functions and guess how many users will move to > > another language. > > Ah, I get the point now. :) > > I don't want to start another volatile discussion, but to me it > seems an attribute would not be a bad idea. > -And for completeness... read-only, write-only, read/write and > perhaps even 'prohibited access'. I recall that something was > marked prohibited in some way in a library once; I forgot how > they did it, though. volatileLoad is not in gdc yet. I've written the code some months ago but I need to update it and then it needs to be reviewed. Always using volatileLoad/Store is annoying. The solution is to write a wrapper: Volatile!T: http://dpaste.dzfl.pl/dd7fa4c3d42b Volatile!size_t value; value += 1; assert(value == 1); Register wrapper: http://dpaste.dzfl.pl/3e6314714541 Register definition: enum Level : ubyte { low = 0, high = 1 } enum fields = [ Field("PIN0", 0, 0, true, "Level", Access.readWrite), Field("PIN1", 1, 1, true, "Level", Access.readWrite), Field("TEST", 2, 4, false, "ubyte", Access.readWrite)]; mixin(generateRegisterType!ubyte("PORT", fields)); pragma(address, 0x25) extern __gshared PORTRegister PORTB; Usage: auto b = PORTB.load(); PORTB.toggle!"PIN0"; PORTB.PIN0 = Level.low; writeln(PORTB.PIN0); PORTB.TEST = 0b000; The remaining problem is performance. (With optimization the generated code is as good as equivalent C code. However, we need to avoid size overhead: e.g. struct initializers and the opX functions shouldn't generate functions in the executable, though tha can be fixed with the linker)