Hello, Yes. Sparcv9 had something similar as well - at least on a few embedded systems (I did the VxWorks port for that ABI, and some of the gcc work - ages ago now).
The mips/n32 ABI is growing in popularity, both in the embedded space and at the higher end (As I understand it, the SiCortex systems are n32). It's higher performance, and it allows the compiler to take advantage of the 64-bit register file and ALU without having to port the code to a full 64-bit API (w/ 64 bit pointers and such). Even code that doesn't generally use 64-bit ints will run faster due to the changes in the calling convention[*]. Most (embedded) systems don't need the extended addressing of 64-bits, but if they're on a MIPS64 device they want access to the full 64-bit ALU and register set (yes, there are some embedded systems that would like pointers to be 64-bit, but they're few in number so far). So, n32 is a generally useful middle ground between the strict 32-bit ABI (o32) and the full 64-bit ABI (n64) - probably more so than SPE is for ppc. That last bit is speculation on my part, as ppc is one of the modern instruction sets I'm less than familiar with. This is despite the fact that a lot of the MIPS JIT for Mono was written by reverse engineering the PPC port ;). Andreas - the way I'm handling the code generation differences on MIPS is through a set of macros (basically pseudo-ops) that either produce the 32 or 64-bit versions of opcodes depending on which ABI we're compiling for. It's the same basic technique that's been in use on MIPS for writing ABI independent assembly code since the first 64-bit MIPS chips were introduced (back around '90 or so). It requires keeping a bit more context in your head when reading/writing the code, but it keeps from polluting the mini-mips.c file with a lot of extra #ifdef tests. The main thing I'm working through right now is finding and fixing a few of the macros in ir-emit.h to keep them 'doing the right thing' without warnings when inst_p0 and inst_p1 are MonoReg (an integral type) rather than a gpointer. Due to the way that OP_PCONST and a few other opcodes are handled, there's an assumption that inst_p* and inst_c* are type punned through the union. It's close to working, and I'm trying to keep the changes as small as possible. There's probably another day or two of spare-time work on it before I'm ready to post it for review. /Mark [*] the trade off is that on o64, n32 and n64 stack slots are 64-bits - which means that for any given call stack you tend to burn through your D-cache faster. On the plus side, n32 and n64 (1) provide for passing the first 8 arguments in registers (instead of the first four), and (2) doesn't require the caller allocating backing space in the stack frame for register arguments (which cuts down on the stack footprint and gets you back some of the performance loss due to the larger stack slots). The o32->o64 transition however tends to cost ~5-7% in performance for otherwise 32-bit code because you're still limited to 4 arguments in registers and backing stack slots allocated by the caller. I don't suggest we support o64 - it was never an official ABI, never was supported under Linux and is in the process of being phased out from the embedded systems that supported in (in favor of n32). On Dec 13, 2008, at 12:27 PM, Andreas Färber wrote: > Hi, > > On ppc there is a similar feature, SPE, which allows some 64-bit ops > on a 32-bit machine. > > There, the general-purpose registers appear to be all 64-bit but > regular instructions only access the lower 32 bits. Special > instructions are used to access full 64-bit registers, similar to > Altivec instructions using (separate) 128-bit registers on an > otherwise 32- or 64-bit system. > > From that point of view, technically the MonoReg distinction makes > sense, to allow sizeof(MonoReg) >= sizeof(gssize). > > But as pointed out below, changing the variable type is only a > start. Should anyone want to make Mono use SPE on ppc, probably all > places that save and restore registers would need to be reworked, > introducing a special code path for those systems that support it. > The only Mono feature benefitting would probably be System.Int64, so > I'm not sure if this is really needed. > > Andreas > > Am 13.12.2008 um 19:55 schrieb Mark Mason: > >> Hello, >> >> Not ... necessarily. The mips/n32 abi is one example. Code runs >> in a >> 32-bit address space (so pointers, and sizeof(void *) are 32-bits), >> but with 64-bit registers and 64-bit operations available. >> >> This is distinct from n64, which does have 64-bit pointers. >> >> /Mark >> >> On Dec 13, 2008, at 7:01 AM, Zoltan Varga wrote: >> >>> Hi, >>> >>> gssize is the size needed to hold a memory address, if the machine >>> has 64 bit registers, >>> this is 64 bits. On that mips machine, this is 32 bits ? >>> >>> Zoltan >>> >>> On Thu, Dec 11, 2008 at 8:40 PM, Mark Mason >>> <[email protected]> wrote: >>>> Hello all, >>>> >>>> Along the same lines as the SIZEOF_VOID_P change, I'd like to offer >>>> the >>>> following new type to replace to use of 'gssize' when referring >>>> to a >>>> machine register. 'gssize' comes from glib, and simply represents >>>> the >>>> size of an integer -- which is not necessarily always the same as >>>> the >>>> size of the underlying integer registers. >>>> >>>> There are some other uses of gssize in mini/ that will need to be >>>> updated as well, but this is a start. >>>> >>>> Comments most welcome. >>>> >>>> Thanks in advance, >>>> Mark >>>> >>>> Index: mini.h >>>> =================================================================== >>>> --- mini.h (revision 121269) >>>> +++ mini.h (working copy) >>>> @@ -400,6 +400,13 @@ >>>> int size, align; >>>> } MonoMemcpyArgs; >>>> >>>> +/* C type matching the size of a machine register. Not always the >>>> same >>>> as 'int' */ >>>> +#if SIZEOF_REGISTER == 4 >>>> +typedef gint32 MonoReg; >>>> +#elif SIZEOF_REGISTER == 8 >>>> +typedef gint64 MonoReg; >>>> +#endif >>>> + >>>> struct MonoInst { >>>> guint16 opcode; >>>> guint8 type; /* stack type */ >>>> @@ -415,7 +422,7 @@ >>>> union { >>>> MonoInst *src; >>>> MonoMethodVar *var; >>>> - gssize const_val; >>>> + MonoReg const_val; >>>> gpointer p; >>>> MonoMethod *method; >>>> MonoMethodSignature *signature; >>>> >>>> >>>> _______________________________________________ >>>> Mono-devel-list mailing list >>>> [email protected] >>>> http://lists.ximian.com/mailman/listinfo/mono-devel-list >>>> >> >> _______________________________________________ >> Mono-devel-list mailing list >> [email protected] >> http://lists.ximian.com/mailman/listinfo/mono-devel-list > _______________________________________________ Mono-devel-list mailing list [email protected] http://lists.ximian.com/mailman/listinfo/mono-devel-list
