Subject: r4600 flag

From: Pete Popov <[email-masked]>
Date: Mon, 30 Jul 2001 22:55:35 -0700

in arch/mips/Makefile, we use the -mcpu=r4600 flag for MIPS32. What's 
interesting is that the use of this flag can cause the toolchain to 
generate incorrect code. For example:

la k0, 1f
nop
1: nop

The la macro is split into a lui and a daddiu. The daddiu is not correct 
for a mips32 cpu.  Getting rid of the -mcpu=4600 fixes the problem and 
the daddiu is then changed addiu.

Is there a truly correct -mcpu option for a mips32 cpu?

Pete

---

From: Thiemo Seufer <[email-masked]>
Date: Tue, 31 Jul 2001 09:28:22 +0200

Pete Popov wrote:
> generate incorrect code.

Which toolchain versions, what patches applied to it?

> For example:

This is IIRC a known bug in at least current binutils CVS, a patch
to fix it really was already discussed.

> Is there a truly correct -mcpu option for a mips32 cpu?

In theory, no -mcpu option (which is to be deprecated in
favor of -march/-mtune) and -mips32 as ISA flag _should_ work.

In practice, the patch which adds this to gas was discussed on the
binutils list the last days and is likely to go in CVS
today or tomorrow.

Thiemo

---

From: "Kevin D. Kissell" <[email-masked]>
Date: Tue, 31 Jul 2001 10:06:35 +0200

> the daddiu is then changed addiu.

Using mips-linux-gcc from egcs-2.91.66, I don't see exactly this
behavior in the test case above.  I *do* see that *if* I have -mcpu=4600
set *and* I have not otherwise set the ISA level to be MIPS I or
MIPS II (-mips1, -mips2), 64-bit instructions will be emitted.
But that's to be expected.  To generate 32-bit code for an
R4600-like platform, you need to specify both the ISA level
(to deal with issues like the above) and the R4600 pipeline
(to get the MAD instruction).  One place where care must
be exercised is in MIPS32 exception handlers, where eret 
must be used.  Prior to MIPS32, eret implied MIPS III which 
implied a 64-bit CPU, and the Linux compilers still see
things that way.  If the whole module is built with -mips3,
one does risk seeing some cursed macro expansions.
Until we get proper support for MIPS32 integrated into
the standard Linux tool chain (see below), the most 
correct option would be to build with -mips2 and to use
explicit ".set mips3/.set mips0" directives.

> Is there a truly correct -mcpu option for a mips32 cpu?

It's "-mips32", which is sort of a -mips option and a -mcpu
option rolled into one.  It's supported by several gnu distributions,
notably those of Algorithmics and Cygnus/Red Hat.  I believe
that someone at MIPS or Algorithmics succeeded in building
a Linux kernel of some description using the Algorithmics
SDE, but I don't know the details.

            Regards,

            Kevin K.

---

From: Ralf Baechle <[email-masked]>
Date: Tue, 31 Jul 2001 11:25:31 +0200

> to fix it really was already discussed.

Is this macro expaned by the compiler or assembler?  Just -mcpu=r4600
should not make cc1 generate any instructions beyond MIPS I.

In the past we already had inline assembler fragments that left the assembler
in .misp3 mode thus resulting the rest of the file bein assembled in
mips3 mode.

> > Is there a truly correct -mcpu option for a mips32 cpu?

None is really good, none is really bad ...

> binutils list the last days and is likely to go in CVS

  Ralf

---

From: Ralf Baechle <[email-masked]>
Date: Tue, 31 Jul 2001 11:31:21 +0200

On Tue, Jul 31, 2001 at 10:06:35AM +0200, Kevin D. Kissell wrote:

> But that's to be expected.

No, it contradict the GCC documentation:

`-mcpu=CPU TYPE'
     Assume the defaults for the machine type CPU TYPE when scheduling
     instructions.  The choices for CPU TYPE are `r2000', `r3000',
     `r3900', `r4000', `r4100', `r4300', `r4400', `r4600', `r4650',
     `r5000', `r6000', `r8000', and `orion'.  Additionally, the
     `r2000', `r3000', `r4000', `r5000', and `r6000' can be abbreviated
     as `r2k' (or `r2K'), `r3k', etc.  While picking a specific CPU
     TYPE will schedule things appropriately for that particular chip,
     the compiler will not generate any code that does not meet level 1
     of the MIPS ISA (instruction set architecture) without a `-mipsX'
     or `-mabi' switch being used.

> To generate 32-bit code for an
> (to get the MAD instruction).

No MAD on R4600.  Again it would be in contradiction with above document-
ation.  Mad you get with:

`-mmad'
`-mno-mad'
     Permit use of the `mad', `madu' and `mul' instructions, as on the
     `r4650' chip.

  Ralf

---

From: "Kevin D. Kissell" <[email-masked]>
Date: Tue, 31 Jul 2001 13:40:47 +0200

>      or `-mabi' switch being used.

In that case, the tools that I've been using are technically
broken.  Surprise surprise.   Because -mcpu=4600 is
most assuredly setting the ISA level, even if it doesn't
override one explicitly set!

> No MAD on R4600.  Again it would be in contradiction with above document-

Right.  Sorry.  I got the 4600 and 4650 confused.  I no longer
understand why "4600" and not "4650" is the model for MIPS32.

            Kevin K.

---

From: Thiemo Seufer <[email-masked]>
Date: Tue, 31 Jul 2001 14:58:50 +0200

> should not make cc1 generate any instructions beyond MIPS I.

It's the assembler, -mcpu does not only affect scheduling in gas.
To clean this up -march and -tune were introduced recently to
obsolete -mcpu and -m<cpu> (in both binutils and gcc).

Thiemo

---

From: Thiemo Seufer <[email-masked]>
Date: Tue, 31 Jul 2001 15:08:29 +0200

Kevin D. Kissell wrote:
[snip]
> override one explicitly set!

gas and gcc have different meanings for this option, gas uses the
cpu's default ISA (if none specified) while gcc uses MIPS I.
In current binutils/gcc CVS, there was -march and -mtune introduced
as a replacement for -mcpu and -m<cpu>, which were kept for backward
compatibility only.

[snip]
> understand why "4600" and not "4650" is the model for MIPS32.

At least for the CVS binutils gas it is Generic-MIPS32, not 4600.

Thiemo

---

From: Carsten Langgaard <[email-masked]>
Date: Tue, 31 Jul 2001 15:38:46 +0200

> in .misp3 mode thus resulting the rest of the file bein assembled in

Yes, and I'm sure I fixed that so it worked on MIPS32 CPUs, only leaving the
"eret" instructions.

---

From: "John D. Davis" <[email-masked]>
Date: Tue, 31 Jul 2001 08:29:12 -0700 (PDT)

Looking at the system map from the generic build of 2.4.3, it looks like
the code is 64 bit.  The upper 32 bits are "f" instead of 0.  I built it
using the R4600 flag.  This differs from the system map for 2.4.0-test9
where the upper 32 bits are 0.  For the indy, do I specify mips2 to
generate 32 bit code?  objdump says it is ELF32, but it doesn't look like
that.  I would like to generate 32bit.

thanks,
john