Christian Holm Christensen wrote:
> Hi again,
> 
> On Tue, 2007-11-06 at 21:10 +0000, Thiemo Seufer wrote:
> > Christian Holm Christensen wrote:
> > > Hi Thiemo,
> > > 
> > > On Tue, 2007-11-06 at 18:56 +0000, Thiemo Seufer wrote:
> > > > Christian Holm Christensen wrote:
> > > > > Hi Thiemo,
> > > > > 
> > > > > On Mon, 2007-11-05 at 00:48 +0000, Debian Bug Tracking System wrote:
> ...
> > > > I notice that the regex in configure excludes now mipsel. 
> > > 
> > > I did that because I wasn't sure if it would work on mipsel straight out
> > > of the box, since the endianess is important for I/O among other
> > > things. 
> > 
> > The places where endianness is visible would need some care, true.
> > The compiler provides built-in macros for that purpose:
> > 
> > __MIPSEL__ for little endian
> > __MIPSEB__ for big endian
> 
> > I presume you already use a macro to select endianness, selecting it
> > via the compiler builtins should be straightforward.
> 
> Currently, there's the following code in ROOT to deal with Linux on
> mips: 
> 
>         #if defined(linux) && defined(__mips)

Better would be to check for __linux__ and __mips__. linux might be a
variable in the code somewhere... The __mips__ version with two trailing
underscores is the more common one. So:

          #if defined(__linux__) && defined(__mips__)

>         #   define R__LINUX
>         #   define R__UNIX
>         #   define NEED_SIGJMP
>         #   if defined(__mips64) || defined(_ABI64)

This is broken, as __mips64 is also defined for N32, and _ABI64 is always
defined. Assuming the R__B64 controls both address space and register size,
it should be:

          #   if _MIPS_SIM==_ABI64

I don't know what the exact semantics of those defines are, and how well
suilted they are to support N32.

>         #      define R__B64      /* enable when 64 bit machine */
>         #   endif
>         #   if !defined(__MIPSEB__) /* Little endian */

For more clarity:

          #   if defined(__MIPSEL__) /* Little endian */

>         #      define R__BYTESWAP
>         #   endif 
>         #endif
>         
> > > > The only
> > > > difference between both is the endianness. For complete MIPS support
> > > > it would need the following:
> > > > 
> > > > mips        O32 ABI, ILP32, "long long" in a "aligned" even-odd register
> > > > mipsel      pair, 4 argument registers
> > > > 
> > > > mipsn32el   N32 ABI, ILP32, but with 64 bit wide registers, and
> > > > mipsn32     "long long" in a single register, 8 argument registers
> > > > 
> > > > mips64el    N64 ABI, LP64, 8 argument registers
> > > > mips64     
> > > 
> > > I'm not sure how to understand your table.   Could you, along the lines
> > > outlined at 
> > >  
> > >         http://wiki.debian.org/DebianScienceROOT -> Porting Notes
> > >         
> > > tell me what changes would be needed?  Perhaps which already support
> > > registers the 6 cases above would be similar to? 
> 
> Just to make sure:  There are only two Debian MIPS architectures: mips
> and mipsel.   Does that mean, that
> 
>   Debian arch  | ABI (from your list above)
>   -------------+---------------------------
>   mips         | mips, mipsn32, mips64
>   mipsel       | mipsel, mipsn32el, mips64el

No, sorry again for leaving ot crucial information. Debian currently
supports only O32 ABI. Support for the other ABIs is planned in future
but so far hasn't progressed much beyond 64bit Kernels. The ABI names
quoted above are actually the propsed Debian architecture names, since
"Debian architecture" effectiely means "support for one specific ABI".

> > > I guess the O32/N32/N64 is the "word-size", but what is the "O" and
> > > "N"? 
> > > 
> > > I don't know what you mean by ILP32/LP63.  I also don't know how to deal
> > > with "long long" in 1 or 2 registers.  
> > 
> > Sorry, I realize that was too terse. O32/N32/N64 are the names of the
> > ABIs (Application Binary Interfaces) supported on Linux/MIPS.
> 
> Ah, I see. 
> 
> > I attempted to add a short outline of its properties to each mention.
> > 
> > ILP32 is a common abbreviation for an ABI with "32bit integer,
> > 32bit long, 32bit pointer size", describing the most important
> > C types. This is like classic Linux i386. The comparable MIPS
> > ABI is O32.
> > 
> > LP64 is a shorthand for "64bit long, 64bit pointer size". This
> > is what most 64bit Unices use, one example is Linux AMD64. The
> > comparable MIPS ABI is N64.
> > 
> > The N32 ABI is a bit odd, it combines a 32bit address space with
> > 64bit wide registers, but it still retains the classic (ILP32)
> > data type lengths. I mentioned "long long" since that is the only
> > data type which is subtly different between both ILP32 variants.
> > Maybe this part isn't relevant for ROOT.
> 
> I guess whether the O32/N32 split is important, depends on where "64bit
> wide registers" registers are used and important. 
> 
> > > I guess the "argument registers" refers to variadic arguments, but
> > > exactly what that would imply in the ROOT source code I don't know.
> > 
> > On MIPS (and most other RISC-like architectures) the first few
> > arguments to a function are passed via registers. From the
> > powerpc code in cint I inferred this is an important property
> > which the code needs to know about.
> 
> The code in CINT related to MIPS is currently 
> 
>         #elif (defined(__mips)&&defined(linux))
>         /**********************************************
>         * MIPS, Linux
>         **********************************************/
>         # define G__VAARG_INC_COPY_N 4
>         # define G__VAARG_PASS_BY_REFERENCE 8
>         
> I guess these should really be 
> 
>                                    | mips   | mipsn32   | mips64
>                                    | mipsel | mipsn32el | mips64el
>     ---------------------------+--------+---------------------
>         G__VAARG_INC_COPY_N        |   4    |     8     |    8
>         G__VAARG_PASS_BY_REFERENCE |   4    |     8     |    8
>         
> if "G__VAARG_INC_COPY_N" is meant to be the size of the argument
> registers, and "G__VAARG_PASS_BY_REFERENCE" is the number of arguments
> passed by reference through registers.  Can someone on the CINT mailing
> list elaborate please? Thanks.

Sounds like it, yes.

> How would one find out whether the ABI was O32 or N32?  Is there some
> pre-processor macro that will tell you?  I guess the code quoted above
> will be enough to distinguish between mips/mipsn32 and mips64, but it's
> not clear how I would distinguish between mips and mipsn32.  

For O32:

#if _MIPS_SIM==_ABIO32
...
#endif


For N32:

#if _MIPS_SIM==_ABIN32
...
#endif


For N64:

#if _MIPS_SIM==_ABI64
...
#endif


> > > I've Cc'ed this mail to rootdev and cintdev for more input. 
> > > 
> > > > Note that the "el" is always the suffix.
> > > 
> > > OK.  That goes for the return from `uname'? 
> > 
> > Not quite. The uname is on a 32bit kernel "MIPS", and on a 64bit kernel
> > "MIPS64", regardless of endianness. You may have noticed by now that I
> > say "ABI" and try to avoid "Machine" or "CPU", since those are not
> > necessarily identical things. 'uname' would return the wrong result
> > if we want to build a 32bit program on a 64bit capable machine.
> 
> The ROOT configure script uses the triplet 
> 
>     arch=`uname -s | tr '[A-Z]' '[a-z]'`
>     chip=`uname -m | tr '[A-Z]' '[a-z]'`
>     rele=`uname -r`
> 
> to figure out the "platform" we're compiling fore - can I some how, from
> that triplet - figure out which ABI we're using? 

As I tried to explain, no. You can see the same problem already on a
AMD64 machine when trying to compile 32-bit code (via gcc -m32).
Using uname to figure out the ABI is inherently broken for multi-ABI
environments. It only allows to do better guesswork.

Current best practice in Debian is to feed dpkg-architecture values
to configure, this also makes cross-building via dpkg-cross possible.

> On the other hand, I don't think I need to do much based on the
> endianness since that's dealt with in the code directly.  OK, there may
> be a need to define a separate "mips64" "platform", since some compiler
> flags are specific to the word size. 

Endianness should work out mostly automatically. For compiler flags,
the MIPS gcc uses -mabi=32, -mabi=n32, -mabi=64 to select the right
thing. So it would be three different platforms in the end.

> I get the feeling that you have code compiled on O32, N32, and N64
> intermixed in the "mips" and "mipsel" distribution - which sort of
> implies that all chips can handle this.

It's a bit more complex. MIPS spans probably the largest performance
range of any CPU family, from a 32bit 20 MHz Microcontroller (made by
Microchip) up to a 64bit monster with over 5000 CPUs (made by SiCortex).
Obviously, only the 64bit CPUs can run 64bit code, but 32bit code runs
on all of them.

The use cases for the different ABIs are:
- O32: Most compatible, runs everywhere
- N32: Best performance on 64 bit if a large address space isn't needed.
       It is faster than O32 due to improved calling conventions, and it
       is faster than N64 due to reduced pointer size.
- N64: Huge address space.

> However, I'm not sure I
> understood this correctly.  Could you tell me a little bit about why
> there isn't separate mips, mipsel, mips64, and mips64el distributions?
> Thanks. 

They are supposed to be eventually separate, but co-installable in the
multiarch framework. For now, Debian has only mips/mipsel, and some
64bit capable kernels. The next step is to provide 64bit libraries
inside the existing mips/mipsel distribution.

I hope this gave some more insight.


Thiemo



-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to