Subject: Re: anybody tried NPTL?

From: Richard Sandiford <[email-masked]>
Date: Wed, 01 Sep 2004 10:17:44 +0100

Dominic Sweetman <[email-masked]> writes:
> In many ways it's easier to get away from the ingenious but
> troublesome stack-structure-based calling convention.  The "stack
> structure" trick was invented so that o32 could work without function
> prototypes - but function prototypes are now required, and something
> with fixed-size arguments is simpler.  Something like the old
> Cygnus/WRS EABI proposal, in fact...

Indeed, all of this:

> So we're proposing:
> [...]
> o Calling convention: register-, not slot-based. Each argument is
>   represented by a register value. Arguments 0-7 travel in registers
>   a0-7 (or fa0-7 as required for floating point types). If there are
>   more than eight arguments, further ones are formed as if put in a
>   register and then saved on the stack into a 64-bit slot (more than 8
>   arguments is rare enough that we can afford to standardise on the
>   big slots).
>   
> o Use floating point registers for double and float arguments, and
>   integer registers for all integer/pointer values which will
>   fit. Larger or structured data items are implicitly passed by
>   reference: to maintain pass-by-value semantics, the compiler uses a
>   copy-on-write trick if software writes a by-reference argument (or
>   takes its address).  I'm told gcc is happy enough to do that.
>
> o The return value comes back in two registers, with the second
>   return-register used only when the return value consists of two
>   scalars (ie a complex or double-precision number). [Folklore insists
>   this is essential for Fortran support of complex numbers, and I
>   don't want to fight folklore].
>
>   All other non-scalar return values are returned via a pointer
>   specified by the caller as an implicit first argument.
>
> o Reserved registers: all the traditional ones. But now:
>
>   - gp will be the GOT pointer in Linux, and should be defined as
>     saved (ie a function must preserve values in this registers, which
>     means it will need to save-and-restore the register if it is
>     written locally).

...are pretty much what we already do for EABI.  There's some fuzziness
in what EABI considers to be "double and float arguments": things like
"struct { float f; }" are passed in the same way as scalar floats, for
example.  Complex integers are also returned by invisible reference
rather than in two GPRs.  But these are very much corner cases.

Rather than define new, slightly different, conventions, have you thought
about defining this new ABI as an extension of EABI?  I.e. taking EABI,
adding n32/n64-style PIC, and the all-important:

>   - we'll define some other register as a per-thread data pointer.

Richard