Compilers
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
 
User Name:
Password:
Remember me
Go Back   Web Development Archives FAQs Compilers

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Display Modes
 
Unread Web Development Archives Sponsor:
  #1  
Old May 11th, 2008, 11:10 PM
cr88192
Guest
Dev Archives Newbie (0 - 499 posts)
 
Posts: n/a  
Time spent in forums:
Reputation Power:
x86-64 and calling conventions

Well, I have my own compiler, however, I don't as of yet target x86-64.

one of the main reasons:
the calling conventions used in Linux and friends are, scary


Short Description:
arguments are passed in registers, meanwhile, others may be left on the
stack, and there is no particular relation between the registers and the
stack layout.

Beyond Just Putting A Big Damper The Compiler Machinery, It Leaves Many
Ugly Questions:
how does one effectively deal with varargs? (of all things, the convention
still uses regs even for passing varargs).

it seems almost like one will have to dump all of the registers into a kind
of a context, and keep note of particular counts (GPR pos, XMM pos, stack
pos).

how does one do things like hidden argument injection? (useful for many
tasks, such as closures).



, in general, there are all sorts of ugly questions wrt the topic of
actually working with the args list in a first-class manner (beyond just the
task of having to get the compiler to work with all this to begin with).


I am left considering the idea of abandoning this convention for internal
usage, and instead using a different default calling convention. probably,
name mangling would be used to distinguish them, and interface stubs would
be generated to handle external calls.

sadly, this would lead to a big issue, which is that there would be a kind
of a "wall" between the two worlds. firstly, interface stubs would be
needed, and secondly, that function pointers could not be safely passed
across this wall (limiting the usage of callbacks, ).

more-so, these stubs could potentially be limited in terms of what they can
pass along (functions passing raw structs or similar stack-disordering
features may not be wrapable).

so, such a wall could be very problematic (especially in a mixed-compiler
codebase).


now, what kind of convention would I be imagining:
well, basically, it would be a hybrid of the existing conventions, and the
good old 32-bit x86 convention.

in particular, arguments would be passed on the stack (in good old linear
right-to-left ordering).


now, beyond this wall, there is also a possible risk of a performance impact
(both with calls, and in general).

it is also possible I could just "bear with it", and possibly use
stack-flattening/unflattening hacks mostly as a means of dealing with edge
cases.


alternatively, I could use a variant of the MS convention by default (even
on Linux), which is basically about the same (it being fairly simple to dump
arguments to the shadow space, or retrieve them from there).

the task of defeating the "wall" would then be a task for later


any suggestions?
[My suggestion is that if you want people to use the compiler, use the same
calling sequence as everyone else. The code to deal with varargs is ugly,
but I would be surprised if it were very long. -John]

Reply With Quote
  #2  
Old May 14th, 2008, 12:01 PM
glen herrmannsfeldt
Guest
Dev Archives Newbie (0 - 499 posts)
 
Posts: n/a  
Time spent in forums:
Reputation Power:
x86-64 and calling conventions

Dave Parker wrote:
(snip)

The calling convention is left-to-right (since I was making my own
calling convention, I figured I might as well fix the old right-to-
left holdover and use the stack the way the stack should be used
left-to-right). Left-to-right means the arguments are evaluated in
the order that users expect them to be. If the function is vararg,
then I push the argument count on the stack last.

That doesn't sound very convenient. I have known for a while now that
ANSI C requires varargs routines to be declared as such so that a
different calling convention could be used.

So far, I haven't known any that actually did that, though.

If you always push the length, one could use it to find the address of
the first argument, and then subsequent arguments.

As far as passing arguments in registers, there is at least one
convention (possibly SPARC, but I am not sure now) where some are
passed in registers, but stack space is still reserved for them. The
called routine can then store them into the stack. As some number of
words are kept in the registers, in some cases a double variable will
be half in a register and half on the stack. Storing to the stack is
a convenient way to get the two back together again.

-- glen

Reply With Quote
  #3  
Old May 24th, 2008, 05:10 PM
Boleslaw Ciesielski
Guest
Dev Archives Newbie (0 - 499 posts)
 
Posts: n/a  
Time spent in forums:
Reputation Power:
x86-64 and calling conventions

glen herrmannsfeldt wrote:
As far as passing arguments in registers, there is at least one
convention (possibly SPARC, but I am not sure now) where some are
passed in registers, but stack space is still reserved for them. The
called routine can then store them into the stack. As some number of
words are kept in the registers, in some cases a double variable will
be half in a register and half on the stack. Storing to the stack is
a convenient way to get the two back together again.

This is the case for 32-bit PowerPC.

Bolek


Reply With Quote
  #4  
Old May 29th, 2008, 11:40 PM
glen herrmannsfeldt
Guest
Dev Archives Newbie (0 - 499 posts)
 
Posts: n/a  
Time spent in forums:
Reputation Power:
x86-64 and calling conventions

Boleslaw Ciesielski wrote:
(I wrote)

>>As far as passing arguments in registers, there is at least one
>>convention (possibly SPARC, but I am not sure now) where some are
>>passed in registers, but stack space is still reserved for them. The
>>called routine can then store them into the stack. As some number of
>>words are kept in the registers, in some cases a double variable will
>>be half in a register and half on the stack. Storing to the stack is
>>a convenient way to get the two back together again.


This is the case for 32-bit PowerPC.

It seems the one I was remembering is SPARC. The LCC book, "A
Retargetable C compiler: Design and Implementation," describes code
generators for MIPS R3000, SPARC, and x86.

For SPARC, the first 24 bytes of arguments go in registers, even if a
double is split in half. Stack space is allocated for them, and also
16 words to store other registers if the register stack overflows.
Floating point values are passed in i registers, so have to be stored
anyway before they can be loaded into floating point registers. It
would have seemed more convenient to pass floating point values in
floating point registers, but that may not be compatible with C,
especially in the case of varargs.

-- glen


Reply With Quote
Reply

Viewing: Web Development Archives FAQs Compilers > x86-64 and calling conventions


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are Off
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest Threads | Shoutbox
Forum Jump


Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 





© 2003-2008 by Developer Shed. All rights reserved. DS Cluster 2 hosted by Hostway