Re: x86-64 and calling conventions

"cr88192" <>
Mon, 12 May 2008 20:10:59 +1000

          From comp.compilers

Related articles
x86-64 and calling conventions (cr88192) (2008-05-12)
Re: x86-64 and calling conventions (cr88192) (2008-05-12)
Re: x86-64 and calling conventions (James Harris) (2008-05-12)
Re: x86-64 and calling conventions (Vidar Hokstad) (2008-05-12)
Re: x86-64 and calling conventions (Dave Parker) (2008-05-12)
Re: x86-64 and calling conventions (cr88192) (2008-05-13)
Re: x86-64 and calling conventions (cr88192) (2008-05-13)
Re: x86-64 and calling conventions (glen herrmannsfeldt) (2008-05-13)
[9 later articles]
| List of all articles for this month |

From: "cr88192" <>
Newsgroups: comp.compilers
Date: Mon, 12 May 2008 20:10:59 +1000
Organization: Saipan Datacom
References: 08-05-031
Keywords: C, architecture
Posted-Date: 12 May 2008 20:59:49 EDT

"cr88192" <> wrote in message
> 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 On 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...).


> 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]

Yes, this is probably what I will have to do.
the convention is a little bit of a horror, but I guess it has to be lived

after all, it is probably my due punishment for writing yet another C
compiler. it will also be the cost for trying to add an x86-64

well, I do JIT and I focus on somewhat different goals than those of
LLVM and similar. probably a good enough justification.

all just the fiddling of some lowly hobbyist anyways...

general context:

the compiler exists as 2 major parts:
an upper compiler, which does parsing and a lot of the higher-level
the lower compiler, which takes the RPN-based output of the upper compiler,
and compiles it into assembly code.

the JIT is simply an integrated assembler and linker (I use an
NASM-like syntax, and it can also dynamically load COFF, ELF, GNU-AR
libs, ... and can export COFF).

Win32 is my primary target, with Linux (x86 and x86-64) as secondary
targets. Win64 may also be a target at some point.

the primary use at present is as a scripting VM. technically, pretty damn
overkill, but this is the price I pay to not have to endlessly deal with
stupid FFI issues. now I just deal with code-generation issues...

later on, I may also incorporate a Java frontend as well (currentlly, I only
have a C frontend).

it is my eventual hope to use it for implementing something much closer to
the high-level scripting languages I have usually implemented in the past,
yet while hopefully still being solidly attached to C-land...

a nearer term goal is to add both lexical closures and eval as C extensions
(note: I already have garbage collection, dynamic types, geometric vectors
and quaternions, ... as compiler extensions).

note, on x86 maintaining the integrity of the calling convention and proper
threading has been an invariant goal (it not being acceptable for features
either to break the calling convention or violate threading).

my previous lower compiler was based on a stack machine, which later ended
up using register allocation and similar more as a means of optimization;
basically the lower compiler is an elaborate mass of fixed logic trees.

later on, I had started a rewrite (highly delayed due to getting backlogged
with homework and similar...).
I started building from the bottom up, targetting both x86 and x86-64 at the
same time, and reusing some of the codegen machinery from the previous lower

what I have now is basically a bunch of register allocation machinery, code
for performing various operations on registers, and code for performing
low-level memory operations.

however, I started to get a little stalled as to which direction I would go.
I am thinking of adding an intermediate representation basically consisting
of a kind of value flow graph.

this would imply a new upper end of the lower compiler, basically converting
from RPN into the graph representation (and also handling most of the
typesystem machinery and similar), possibly doing some fiddling, and then
flattening it back out in the process of converting it into assembly code
(the big hassle here being that registers have to be allocated in effective
reverse order...).

all of this will be because I don't really think it is possible to target
x86-64 with a big mass of fixed-logic being driven by the RPN-based input
(this works for x86, but doesn't really look like it will work for x86-64, a
graph being necessary just to generate working code it seems...).

but, I don't know if there is much point in all this, or if I am headed in a
good direction.

general opinions?...

or such...

Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.