Jun Sun, > I am looking into porting NPTL to MIPS. Just curious if > anybody has tried this before. > > I notice there was a discussion about the ABI extension > for TLS (thread local storage) support. Before that support > becomes a reality it seems one can still use NPTL with > the help of additional system calls. Well, this is an area of substantial interest to MIPS Technologies. We are working on our multi-threading extension to the MIPS architecture, and one of our longer-term aims is to achieve really good NPTL performance. As you said, this motivates a revision of the ABI. Any incompatible change to the ABI is painful, since everything has to be recompiled; so our reasoning at the moment is that we might as well be radical... MIPS Technologies would write up the definition; make and circulate changes to the compiler, binutils and debugger; and make and circulate supporting changes to the kernel and glibc. We're aware this is only a part of the problem, so we do need to figure out what will attract community approval. A few years ago I was volubly arguing in favour of keeping o32 until we could move to n32/n64. But times change: SGI compatibility no longer seems important, and Linux on 32-bit MIPS CPUs needs long-term support. 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... So we're proposing: o The register name<->number mapping is that of n64. 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). - we'll define some other register as a per-thread data pointer. Some details are still to be worked out. But do you think this is on the right lines? And who would like to take an active part in specifying or reviewing? -- Dominic Sweetman MIPS Technologies