narrowed down the problem area [naked asm]

Don nospam at nospam.com.au
Tue Oct 28 01:53:03 PDT 2008


bearophile wrote:
> K. Wilson:
>> Seems like the LLVM backend is doing well (though I have seen other timings where g++4.x beats llvm-g++4.x, so take from this what you will).<
> 
> Very nice. On Win in 100% of my programs and benchmarks llvm-gcc 2.3 turns out slower or quite slower than GCC 4.3.1, but the ratio is never bigger than about 2 times slower. So it's curious to see an example of the opposite.
> 
> 
>> I just thought I would let people know that ldc is coming along and performs quite well, at this point.<
> 
> I have read it compiles all Tango tests, this is a lot, because Tango is large and complex.
> 
> --------
> 
> The LDC docs say:
> 
>> One thing the D spec isn't clear about at all is how asm blocks mixed with normal D code (for example code between two asm blocks) interacts.<
>> Currently 'naked' in D is treated as a compile time error in LDC. Reason for this is that LLVM does not support directly controlling prologue/epilogue generation. Also the documentation from the D spec on this topic is extremely limited and doesn't mention anything about how normal D code in a naked function works. In particular local (stack) variables are unclear, also accessing named parameters etc.<

I can answer this.

'naked' in DMD is quite simple: almost nothing works.

Stack variables with 'naked' don't work. Parameters don't work, either. 
Nor do contracts. Here's why:

Regardless of whether 'naked' is specified or not, the compiler creates 
code exactly as if the function began with 'push EBP; mov EBP, ESP; ' 
and ended with 'pop EBP; '
If 'naked' is specified, it just doesn't put that prologue and epilogue in.
So the only way to use 'naked' is to manually keep track of where 
everything is on the stack, and index it off the stack pointer.

Why use 'naked' at all, then?
(1) so that you can use the EBP register;
(2) because non-naked asm doesn't work properly, either. If you pass an 
array into an asm function, you can't get the ".ptr" part of it, because 
the "ptr" conflicts with the asm "ptr" keyword. This is a big problem, 
since almost all asm functions that I write work on arrays.

I don't think that this is how naked asm _should_ work, though. It 
should allow you to reference parameters without adjusting the offsets 
assuming you're using EBP. So the following should work:

void nakedfunc(uint [] dest, uint [] src)
{
   asm {
     naked;
     mov ECX, dest.ptr[ESP];
   }
}

Since the spec says:
"If the [EBP] is omitted, it is assumed for local variables. If naked is 
used, this no longer holds."
True, it doesn't put in an [EBP], but it adjusts the offset assuming 
that a stack frame has been set up. And ".ptr" doesn't work.


Curious fact:
Whenever I'm naked, my body disappears!

void fkk()
{
    asm { naked; }
}

void main() { fkk(); }

--> generates a linker error. Fair enough, really. But kind of interesting.



More information about the Digitalmars-d mailing list