H1 2015 Priorities and Bare-Metal Programming
Johannes Pfau via Digitalmars-d
digitalmars-d at puremagic.com
Mon Feb 2 14:30:05 PST 2015
Am Mon, 02 Feb 2015 13:44:41 -0800
schrieb Walter Bright <newshound2 at digitalmars.com>:
> On 2/2/2015 9:06 AM, Johannes Pfau wrote:
> > _Dmain:
> > push rbp
> > mov rbp,rsp
> > sub rsp,0x10
> > mov rax,0x5 <==
> > mov QWORD PTR [rbp-0x8],rax
> > mov ecx,DWORD PTR [rax] <== a register based
> > load
> >
> > The instruction it should generate is
> > mov ecx, [0x5]
>
> In 64 bit mode, there is no direct addressing like that. The above
> would be relative to the instruction pointer, which is RIP, and is
> actually:
>
> mov ECX, 5[RIP]
>
> So, to load address location 5, you would have to load it into a
> register first.
>
> (You'd be right for 32 bit x86. But also, all 32 bit x86's have an
> MMU rather than direct addressing, and it would be strange to set up
> the x86 embedded system to use MMIO rather than the IO instructions,
> which are designed for that purpose.)
>
Well, as I said it's different on RISC. I'm mainly programming for ARM,
AVR MSP430 and similar systems, not X86.
>
> > Not sure if it's actually more efficient on X86 but it makes a huge
> > difference on real microcontroller architectures.
>
> What addressing mode is generated by the back end has nothing
> whatsoever to do with using volatileLoad() or pragma(address).
I does: if the backend can't know that a value is known at compile time
it cant use absolute addresses:
void test(ubyte* ptr)
{
volatileLoad(ptr); //Can't use literal addressing might be runtime
value
}
The context here is that pragma(address) allows avoiding one wrapper
function. See below.
ARM can code address literals into instructions. So you end up with one
instruction for a load from a compile time known address.
>
> To reiterate, volatileLoad() and volatileStore() are not reordered by
> the optimizer, and replacing them with pragma(address) is not going
> to make for better code generation.
>
> The only real issue is the forceinline one.
I think we're talking different languages. Nobody ever proposed
pragma(address) to replace volatileLoad. It's meant to be used together
with the volatile intrinsics like this:
-----------------------------------------------------------------
import core.bitop;
struct Volatile(T)
{
private:
T _store;
public:
@disable this(this);
/**
* Performs 1 load followed by 1 store
*/
@attribute("inlineonly") void opOpAssign(string op)(in T rhs)
nothrow @trusted {
T val = volatileLoad(&_store);
mixin("val" ~ op ~ "= rhs;");
volatileStore(&_store, val);
}
//In reality, much more complicated wrappers are possible
//http://pastebin.com/RGhKdm9i
}
pragma(address, 0x05) extern __gshared Volatile!ubyte PORTA;
//...
PORTA |= 0b0000_0001;
auto addr = &PORTA;
-----------------------------------------------------------------
The pragma(address, 0x05) makes sure that the compiler backend always
knows that PORTA is at 0x05. Thinks like &PORTA become trivial and the
compiler backend has exactly the same knowledge as if you'd use C
volatile => all optimizations apply.
And if you call opopAssign the backend knows that the this pointer is a
compile time literal value and generates exactly the same code as if
you wrote
T val = volatileLoad(0x05);
val ~ op ~ = rhs;
volatileStore(0x05, val);
but if you instead write
@property ref Volatile!ubyte PORTA()
{
return *(cast(Volatile!(ubyte)*)0x05)
}
PORTA |= now calls a function behind the scenes. The backend does not
immediately know that &PORTA is always 0x05. Also the this pointer in
opopAssign is no longer a compile time constant. And this is were the
constant/runtime value code gen difference discussed above matters.
-O mostly fixes performance problems, but adding an additional property
function is still much uglier than declaring an extern variable with an
address in many ways. (compiler bugs, user-facing code, debug info, ...)
Also it's a conceptually nice way for typed registers: You can read it
as: I've got a Register of type PORT which is an extern variable located
add a fixed address. PORT abstract away volatile access.
More information about the Digitalmars-d
mailing list