I am currently porting LDC to PowerPC and, hopefully, eventually the POWER and
CELL platforms as well. The first bit requires me to port the inline assembler,
allowing me to review the problems that the D language presents LLVM.
LLVM is not a toy virtual machine. It is, perhaps, the most flexible and
powerful compiler toolset ever, spanning massive numbers of computing
platforms. It even supports (in a limited manner) the PIC16 platform, require
insane constraints: there are no registers, memory can only be accessed in one
byte amounts, and some processors only have 35 instructions.
LLVM, however, is not able to do everything. For some reason, its current API
does not allow the restriction of prologue and epilogue generation; to allow so
would not make sense: the language itself depends on the maintenance of the
stack. The only way to establish a 'naked' function in *c* is to 'omit' the
frame pointer—technically not allowed in most OS's ABIs—and then explicitly
avoid using all variables (and hence the stack), OR to use top level assembly
to write the assembly yourself.
Now, neither of those options are really what D should use, but I have some
other recommendations based on this. 'naked' functions should not be allowed to
have any D, except to reference arguments passed to it. In other words, it
should not touch the stack. in fact, there's really no reason at all to have
the 'naked' statement in the inline assembly. It's not a property of the
assembly, it's a property of the *function*. And because D code should not be
used (except perhaps for macros?), 'naked' functions should intrinsically be
assembly functions. So, I recommend the following:
+ Remove the naked keyword as an assembly 'instruction'.
+ Instate it as a function property, similarly to 'extern (C)'. So you might
see the following declaration:
extern naked void flushIDT() {
mov EAX, [ESP+4]
lidt [EAX]
ret
}
Though, if the assembly is implicit, it might be better to rename the keyword
'asm' or something like that to make it clearer. Anyway, these changes will, in
my humble opinion, make the language cleaner and my life easier because I can
simply declare this function by myself.
Cheers!
-Duane

+ Remove the naked keyword as an assembly 'instruction'.
+ Instate it as a function property, similarly to 'extern (C)'. So you might
see the following declaration:
extern naked void flushIDT() {
mov EAX, [ESP+4]
lidt [EAX]
ret
}

I agree. putting "naked" as function attribute seems more correct.
As they say: "Wisdom begins by calling things by their right names."
Putting back the asm{} is a compromise syntax, useful to remove a special case
from one of the stages of the compiler:
naked void flushIDT() {
asm {
mov EAX, [ESP+4]
lidt [EAX]
ret
}
}

except to reference arguments passed to it. In other words, it should not touch
the stack.<
And because D code should not be used (except perhaps for macros?),<

I don't fully understand what you say.
From my very limited experiments with naked functions I think I may enjoy to
add some I/O into naked functions: to be able to define new variables before
the asm and to copy registers into some variable before the final return. What
I am asking here may make useless the "naked" attribute, in such case please
ignore what I have said here.
Bye,
bearophile

From my very limited experiments with naked functions I think I may enjoy to
add some I/O into naked functions: to be able to define new variables before
the asm and to copy registers into some variable before the final return. What
I am asking here may make useless the "naked" attribute, in such case please
ignore what I have said here.

The problem is, the 'naked' keyword remove the prologue and epilogue, which set
up the stack frame, i.e. allocates space for variables. So any D code used in a
naked function must A) either not use any stack space, a tricky proposition, or
B) wait until a bit of assembly does the prologue itself.
Cheers!
-Duane

I am currently porting LDC to PowerPC and, hopefully, eventually the POWER
and CELL platforms as well. The first bit requires me to port the inline
assembler, allowing me to

review the problems that the D language presents LLVM.
Cool!!!!

LLVM is not a toy virtual machine. It is, perhaps, the most flexible and
powerful compiler toolset ever, spanning massive numbers of computing
platforms. It even supports (in a limited manner) the PIC16 platform, require
insane constraints: there are no registers, memory can only be accessed in one
byte amounts, and some processors only have 35 instructions.

That's pretty impressive. I'm currently using a PIC, but it's so
memory-limited it's hard to believe D ever being workable on it.

LLVM, however, is not able to do everything. For some reason, its current API
does not allow the restriction of prologue and epilogue generation; to allow so
would not make sense: the language itself depends on the maintenance of the
stack. The only way to establish a 'naked' function in *c* is to 'omit' the
frame pointer—technically not allowed in most OS's ABIs—and then explicitly
avoid using all variables (and hence the stack), OR to use top level assembly
to write the assembly yourself.
Now, neither of those options are really what D should use, but I have some
other recommendations based on this. 'naked' functions should not be allowed to
have any D, except to reference arguments passed to it. In other words, it
should not touch the stack. in fact, there's really no reason at all to have
the 'naked' statement in the inline assembly. It's not a property of the
assembly, it's a property of the *function*. And because D code should not be
used (except perhaps for macros?), 'naked' functions should intrinsically be
assembly functions.

+ Remove the naked keyword as an assembly 'instruction'.
+ Instate it as a function property, similarly to 'extern (C)'. So you might
see the following declaration:
extern naked void flushIDT() {
mov EAX, [ESP+4]
lidt [EAX]
ret
}

It doesn't need to part of the function signature, though, does it?

Though, if the assembly is implicit, it might be better to rename the keyword
'asm' or something like that to make it clearer. Anyway, these changes will, in
my humble opinion, make the language cleaner and my life easier because I can
simply declare this function by myself.

Because of what I wrote above, I think this removes too much
functionality. I think it would be quite reasonable, though, to make
non-asm code generation illegal inside a naked function. BTW this
probably includes contracts (at present, contracts don't work for naked
functions even in DMD).
Would that restriction be enough?

Because of what I wrote above, I think this removes too much
functionality. I think it would be quite reasonable, though, to make
non-asm code generation illegal inside a naked function. BTW this
probably includes contracts (at present, contracts don't work for naked
functions even in DMD).
Would that restriction be enough?

On Fri, Jan 2, 2009 at 9:21 AM, Don <nospam nospam.com
<mailto:nospam nospam.com>> wrote:
Duane Bailey wrote:
I am currently porting LDC to PowerPC and, hopefully,
eventually the POWER and CELL platforms as well. The first bit
requires me to port the inline assembler, allowing me to
review the problems that the D language presents LLVM.
Cool!!!!
LLVM is not a toy virtual machine. It is, perhaps, the most
flexible and powerful compiler toolset ever, spanning massive
numbers of computing platforms. It even supports (in a limited
manner) the PIC16 platform, require insane constraints: there
are no registers, memory can only be accessed in one byte
amounts, and some processors only have 35 instructions.
That's pretty impressive. I'm currently using a PIC, but it's so
memory-limited it's hard to believe D ever being workable on it.
LLVM, however, is not able to do everything. For some reason,
its current API does not allow the restriction of prologue and
epilogue generation; to allow so would not make sense: the
language itself depends on the maintenance of the stack. The
only way to establish a 'naked' function in *c* is to 'omit' the
frame pointerâ€”technically not allowed in most OS's ABIsâ€”and then
explicitly avoid using all variables (and hence the stack), OR
to use top level assembly to write the assembly yourself.
Now, neither of those options are really what D should use, but
I have some other recommendations based on this. 'naked'
functions should not be allowed to have any D, except to
reference arguments passed to it. In other words, it should not
touch the stack. in fact, there's really no reason at all to
have the 'naked' statement in the inline assembly. It's not a
property of the assembly, it's a property of the *function*. And
because D code should not be used (except perhaps for macros?),
'naked' functions should intrinsically be assembly functions.
I agree with this. Mixing run-time D and naked asm doesn't make any
sense. But, something which I've done which is _very_ useful is to
mixin CTFE functions. You get something like:
void foo() {
asm {
naked;
}
mixin(someasm("EBX")); // becomes asm {mov EAX, EBX; }
asm { ret; }
}
char [] someasm(char [] c) {
return "asm { mov EAX," ~ c ~"; }";
}
I see this as crucial functionality since it gives you an
unbelievably powerful macro language in the assembler.
it should be no problem to merge asm blocks in a function, the only
problem is mixing normal dcode in there as well.
I've decided to make this an error in LDC since there is no sensible way
to implement D-style function parameters *and* make sure the function
really is naked. function parameters in llvm are ssa values, so you
manually have to alloca a stack slot and copy the argument into that to
make sure the parameter is an l-value

I don't understand those last two sentences. Does it mean that you'd
only allow 'naked' on extern(C) functions? Or only that mixing D and
naked asm would be illegal?
By the way, in DMD, mixing naked and D code only works if you put a
"push EBP; mov EBP, ESP;" before the first bit of D code, which isn't
documented anywhere as far as I know; and I don't know how to make inner
functions work. So it's pretty much unspecified behaviour right now.
, I could probably come up with

some more reasons, but I think this is sufficient reason to simply drop
that (ill-defined) feature.
*NOTE: naked is not yet 100% implemented in ldc
So, I recommend the following:
+ Remove the naked keyword as an assembly 'instruction'.
+ Instate it as a function property, similarly to 'extern (C)'.
So you might see the following declaration:
extern naked void flushIDT() {
mov EAX, [ESP+4]
lidt [EAX]
ret
}
It doesn't need to part of the function signature, though, does it?
Though, if the assembly is implicit, it might be better to
rename the keyword 'asm' or something like that to make it
clearer. Anyway, these changes will, in my humble opinion, make
the language cleaner and my life easier because I can simply
declare this function by myself.
Because of what I wrote above, I think this removes too much
functionality. I think it would be quite reasonable, though, to make
non-asm code generation illegal inside a naked function. BTW this
probably includes contracts (at present, contracts don't work for
naked functions even in DMD).
Would that restriction be enough?
Cheers!
-Duane

On Wed, Jan 7, 2009 at 12:41 PM, Don <nospam nospam.com
<mailto:nospam nospam.com>> wrote:
Tomas Lindquist Olsen wrote:
On Fri, Jan 2, 2009 at 9:21 AM, Don <nospam nospam.com
<mailto:nospam nospam.com> <mailto:nospam nospam.com
<mailto:nospam nospam.com>>> wrote:
Duane Bailey wrote:
I am currently porting LDC to PowerPC and, hopefully,
eventually the POWER and CELL platforms as well. The
first bit
requires me to port the inline assembler, allowing me to
review the problems that the D language presents LLVM.
Cool!!!!
LLVM is not a toy virtual machine. It is, perhaps, the most
flexible and powerful compiler toolset ever, spanning massive
numbers of computing platforms. It even supports (in a
limited
manner) the PIC16 platform, require insane constraints: there
are no registers, memory can only be accessed in one byte
amounts, and some processors only have 35 instructions.
That's pretty impressive. I'm currently using a PIC, but it's so
memory-limited it's hard to believe D ever being workable on it.
LLVM, however, is not able to do everything. For some reason,
its current API does not allow the restriction of
prologue and
epilogue generation; to allow so would not make sense: the
language itself depends on the maintenance of the stack. The
only way to establish a 'naked' function in *c* is to
'omit' the
frame pointerâ€”technically not allowed in most OS's
ABIsâ€”and then
explicitly avoid using all variables (and hence the
stack), OR
to use top level assembly to write the assembly yourself.
Now, neither of those options are really what D should
use, but
I have some other recommendations based on this. 'naked'
functions should not be allowed to have any D, except to
reference arguments passed to it. In other words, it
should not
touch the stack. in fact, there's really no reason at all to
have the 'naked' statement in the inline assembly. It's
not a
property of the assembly, it's a property of the
*function*. And
because D code should not be used (except perhaps for
macros?),
'naked' functions should intrinsically be assembly functions.
I agree with this. Mixing run-time D and naked asm doesn't
make any
sense. But, something which I've done which is _very_ useful
is to
mixin CTFE functions. You get something like:
void foo() {
asm {
naked;
}
mixin(someasm("EBX")); // becomes asm {mov EAX, EBX; }
asm { ret; }
}
char [] someasm(char [] c) {
return "asm { mov EAX," ~ c ~"; }";
}
I see this as crucial functionality since it gives you an
unbelievably powerful macro language in the assembler.
it should be no problem to merge asm blocks in a function, the
only problem is mixing normal dcode in there as well.
I've decided to make this an error in LDC since there is no
sensible way to implement D-style function parameters *and* make
sure the function really is naked. function parameters in llvm
are ssa values, so you manually have to alloca a stack slot and
copy the argument into that to make sure the parameter is an l-value
I don't understand those last two sentences. Does it mean that you'd
only allow 'naked' on extern(C) functions? Or only that mixing D and
naked asm would be illegal?
Sorry, I can see I was a bit unclear. All I meant was that I can't
sensibly implement naked and allow arbitrary D code in the mix as well,
it's either or... naked should eventually work fine for any calling
conventions, it'll just bail out with an error if you try and mix D in
between the asm blocks.
By the way, in DMD, mixing naked and D code only works if you put a
"push EBP; mov EBP, ESP;" before the first bit of D code, which
isn't documented anywhere as far as I know; and I don't know how to
make inner functions work. So it's pretty much unspecified behaviour
right now.
nested delegates inside naked functions pose some problems, since they
will modify the stack frame as well (like allowing full access to
function parameters, like taking the address of one, which was what I
was trying to talk about in my reply)
Consider taking the address of a parameter that is passed by value in
EAX, this will allocate a stack slot...
Hope I was a bit more clear this time :)

Yes. And that's awesome! It means my existing Bigint naked asm code in
Tango should work on LDC without modification.