Subject: GCCFLAGS for gcc 3.3.x (-march and _MIPS_ISA)

From: Atsushi Nemoto <[email-masked]>
Date: Tue, 12 Aug 2003 15:26:54 +0900 (JST)

I'm trying to compile kernel with gcc 3.3.1 and binutils 2.14.  I
found this report on this ML:

>>>>> On Tue, 13 May 2003 13:33:16 +0200, Guido Guenther <[email-masked]> said:
Guido> Just for completeness: I had to use:
Guido>  GCCFLAGS += -mabi=32 -march=r4600 -mtune=r4600 -Wa,--trap
Guido> to make gcc-3.3 happy (note the 32 instead of o32). gcc-3.2
Guido> doesn't seem to handle these options correctly at all.

It can compile the kernel, but handle_adel_int (and handle_ades_int)
contain wrong codes.

8002630c <handle_adel_int> 40284000 	dmfc0	t0,$8
80026310 <handle_adel_int+0x4> 00000000 	nop
80026314 <handle_adel_int+0x8> ffa800a4 	sd	t0,164(sp)

The source code for this instructions are:

#define __BUILD_clear_ade(exception)                                    \
		.set	reorder;					\
		MFC0	t0,CP0_BADVADDR;                                \
		.set	noreorder;					\
		REG_S	t0,PT_BVADDR(sp);                               \
		KMODE

The macro MFC0 and REG_S are defined asm.h and depend on _MIPS_ISA.

#if (_MIPS_ISA == _MIPS_ISA_MIPS1) || (_MIPS_ISA == _MIPS_ISA_MIPS2) || \
    (_MIPS_ISA == _MIPS_ISA_MIPS32)
#define MFC0		mfc0
#define MTC0		mtc0
#endif
#if (_MIPS_ISA == _MIPS_ISA_MIPS3) || (_MIPS_ISA == _MIPS_ISA_MIPS4) || \
    (_MIPS_ISA == _MIPS_ISA_MIPS5) || (_MIPS_ISA == _MIPS_ISA_MIPS64)
#define MFC0		dmfc0
#define MTC0		dmtc0
#endif

The option -march=r4600 seems to make gcc 3.3.x choose MIPS_ISA_MIPS3.

So, the right options is:

	GCCFLAGS += -mabi=32 -march=mips2 -mtune=r4600 -Wa,--trap
(or	GCCFLAGS += $(call check_gcc, -mcpu=r4600 -mips2, -mabi=32 -march=mips2 -mtune=r4600) -Wa,--trap)

Isn't it?

---
Atsushi Nemoto

---

From: Kumba <[email-masked]>
Date: Tue, 12 Aug 2003 02:49:48 -0400

> (or	GCCFLAGS += $(call check_gcc, -mcpu=r4600 -mips2, -mabi=32 -march=mips2 -mtune=r4600) -Wa,--trap)

I don't claim to be an expert on all things mips yet, but If I recall 
correctly, the R4K processor line is a MIPS III capable processor.  So 
-mips3 -mabi=32 should be safe for it.  I've been building kernels off 
linux-mips.org CVS using "-mips3 -mabi=32 -Wa,--trap" in the 
arch/mips/Makefile, and it works great.

Several people I know using Indy's with R5000 processors use "-mips4 
-mabi=32 -Wa,--trap" (cause R5K is MIPS IV).  I know with gcc-3.3.x, 
-mipsX is just a synonym for the appropriate -march specifier, so it 
doesn't seem to make a different whether one uses -march or -mipsX.

I'm slowly working on building a Gentoo install using "-mips3 -mabi=32" 
code on my Indigo2 (Right now, it's a mix of -mips2 and -mips3 with a 
random -mips1 binary scattered around).  Quite a fun, albeit slow, 
experiment.

--Kumba

-- 
"Such is oft the course of deeds that move the wheels of the world: 
small hands do them because they must, while the eyes of the great are 
elsewhere."  --Elrond

---

From: Thiemo Seufer <[email-masked]>
Date: Tue, 12 Aug 2003 08:51:18 +0200

> The option -march=r4600 seems to make gcc 3.3.x choose MIPS_ISA_MIPS3.

Which is ok, because the available ISA has little to do with the actually
used register width.

If the intention is to use mfc0 for 32bit kernels and dmfc0 for 64bit,
the check should probably be

#ifdef __mips64
# define MFC0		dmfc0
# define MTC0		dmtc0
#else
# define MFC0		mfc0
# define MTC0		mtc0
#endif

> (or	GCCFLAGS += $(call check_gcc, -mcpu=r4600 -mips2, -mabi=32 -march=mips2 -mtune=r4600) -Wa,--trap)

-march=mips2 is an alias for -march=r6000, I don't think that's a
good choice.

Thiemo

---

From: Thiemo Seufer <[email-masked]>
Date: Tue, 12 Aug 2003 09:06:45 +0200

Kumba wrote:
[snip]
> random -mips1 binary scattered around).  Quite a fun, albeit slow, 

I recommend to prefer -march=mips3 over -mips3. It documents the
intention to use a generic arch better and avoids confusion with
e.g. -mips16, which has a totally different meaning.

It won't work with old toolchains, though.

Thiemo

---

From: Kumba <[email-masked]>
Date: Tue, 12 Aug 2003 03:56:34 -0400

> It won't work with old toolchains, though.

Good point.  Does the -march=mips3 work for gcc-3.2.x as well, or is 
that a gcc-3.3.x change?

--Kumba

---

From: Thiemo Seufer <[email-masked]>
Date: Tue, 12 Aug 2003 10:10:52 +0200

> Good point.  Does the -march=mips3 work for gcc-3.2.x as well, or is 

It's only in 3.3 and upwards.

Thiemo

---

From: Kumba <[email-masked]>
Date: Tue, 12 Aug 2003 04:26:58 -0400

> It's only in 3.3 and upwards.

Ahh.  This was why I was still using -mipsX, to maintain backwards 
compatibility until gcc-3.3.x becomes the mainstream compiler.

Something to keep in mind.

--Kumba

---

From: Atsushi Nemoto <[email-masked]>
Date: Tue, 12 Aug 2003 18:25:29 +0900 (JST)

>>>>> On Tue, 12 Aug 2003 02:49:48 -0400, Kumba <[email-masked]> said:
kumba> I don't claim to be an expert on all things mips yet, but If I
kumba> recall correctly, the R4K processor line is a MIPS III capable
kumba> processor.  So -mips3 -mabi=32 should be safe for it.  I've
kumba> been building kernels off linux-mips.org CVS using "-mips3
kumba> -mabi=32 -Wa,--trap" in the arch/mips/Makefile, and it works
kumba> great.

Only affected code I found is __BUILD_clear_ade.  So the 32-bit kernel
compiled with -mips3 will work fine normally, but once an address
error occur the kernel will crash.

As Thiemo said, it seems include/asm-mips/asm.h should be fixed
instead of Makefile.  Still investigating...

---
Atsushi Nemoto

---

From: Atsushi Nemoto <[email-masked]>
Date: Tue, 12 Aug 2003 19:06:36 +0900 (JST)

>>>>> On Tue, 12 Aug 2003 08:51:18 +0200, Thiemo Seufer <[email-masked]> said:

Thiemo> Which is ok, because the available ISA has little to do with
Thiemo> the actually used register width.

Thiemo> If the intention is to use mfc0 for 32bit kernels and dmfc0
Thiemo> for 64bit, the check should probably be

Thiemo> #ifdef __mips64
Thiemo> # define MFC0		dmfc0
Thiemo> # define MTC0		dmtc0
Thiemo> #else
Thiemo> # define MFC0		mfc0
Thiemo> # define MTC0		mtc0
Thiemo> #endif

Thanks for your explanations.  Perhaps the code should be fixed is
__BUILD_clear_ade in entry.S, but I'm not sure.  Does anybody know why
__BUILD_clear_ade uses MFC0 and REG_S though other parts using mfc0
and sw ?

---

From: Thiemo Seufer <[email-masked]>
Date: Tue, 12 Aug 2003 12:16:25 +0200

> __BUILD_clear_ade uses MFC0 and REG_S though other parts using mfc0

Probably because BADVADDR has to be 64bit for 64bit kernels. :-)

Thiemo

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Tue, 12 Aug 2003 15:56:27 +0200 (MET DST)

> the check should probably be

 I'd go for CONFIG_MIPS64 here.

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: [email-masked], PGP key available        +

---

From: Thiemo Seufer <[email-masked]>
Date: Tue, 12 Aug 2003 16:04:52 +0200

>  I'd go for CONFIG_MIPS64 here.

This would work as well, but I prefer compiler intrinsic defines
over custom configury.

Thiemo

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Tue, 12 Aug 2003 16:40:15 +0200 (MET DST)

> This would work as well, but I prefer compiler intrinsic defines

 Well, for Linux it seems appropriate to use a kernel's configuration to
select run-time behaviour -- in this case it's CONFIG_MIPS64 that was
selected by a user that matters (i.e. that we use 64-bit addressing) and
not a compiler's configuration.  Just the opposite to what's expected in
the userland.

---

From: Atsushi Nemoto <[email-masked]>
Date: Wed, 13 Aug 2003 00:26:44 +0900 (JST)

>>>>> On Tue, 12 Aug 2003 12:16:25 +0200, Thiemo Seufer <[email-masked]> said:

>> Does anybody know why __BUILD_clear_ade uses MFC0 and REG_S
>> though other parts using mfc0 and sw ?

Thiemo> Probably because BADVADDR has to be 64bit for 64bit
Thiemo> kernels. :-)

If so, MFC0 and REG_S should be controlled by __mips64 (or
CONFIG_MIPS64) as you and Maciej W. Rozycki said in other mails.  I
wonder why currently is not.  Historical reason ? :-)

Now I'm looking 2.6 codes and there is same problem.  But 2.6 codes
does not use REG_S at all so the stack corruption will never happen.
FYI.

--- Atsushi Nemoto

---

From: Thiemo Seufer <[email-masked]>
Date: Thu, 14 Aug 2003 05:03:59 +0200

> wonder why currently is not.  Historical reason ? :-)

Pre-3.0 gcc used -mips2 instead of -mabi=32 as hint to generate
32bit code. I guess the defines were affected by this also.

Thiemo

---

From: Thiemo Seufer <[email-masked]>
Date: Thu, 14 Aug 2003 05:08:41 +0200

> not a compiler's configuration.  Just the opposite to what's expected in

JFTR:
__mips64 denotes neither 64-bit addressing nor the compiler configuration.
It just means that the generated code uses 64 bit wide registers.

Thiemo

---

From: Ralf Baechle <[email-masked]>
Date: Tue, 19 Aug 2003 05:38:43 +0200

> This would work as well, but I prefer compiler intrinsic defines

I agree for this particular header file because it's been copied into
user applications.  So ideally it should be able to live entirely without
CONFIG_* symbols rsp. <linux/config.h>.

  Ralf

---

From: Ralf Baechle <[email-masked]>
Date: Tue, 19 Aug 2003 05:52:43 +0200

> instead of Makefile.  Still investigating...

No.  We may argue if the compiler is defining the wrong symbols for given
options or the Makefile passes the wrong options but the __mips64 symbol
is a define that exists since 64-bit MIPS compilers exist.  It simply
should not be defined at this point.

  Ralf

---

From: Ralf Baechle <[email-masked]>
Date: Tue, 19 Aug 2003 05:57:56 +0200

> -march=mips2 is an alias for -march=r6000, I don't think that's a

Why? MIPSII / MIPS32 are the highest ISAs supported for building 32-bit
kernels so that makes sense.

  Ralf

---

From: Thiemo Seufer <[email-masked]>
Date: Tue, 19 Aug 2003 08:41:18 +0200

> kernels so that makes sense.

Because you get only MIPS II instructions then. This doesn't matter
much for R4600, but the improvements of later ISAs won't be used.

-mabi=32 -march=r4600 works for 32bit kernels with newer toolchains,
there's no need to use -mtune separately.

Thiemo

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Tue, 19 Aug 2003 14:22:37 +0200 (MET DST)

> CONFIG_* symbols rsp. <linux/config.h>.

 OK, I now recall <asm/asm.h> and <asm/regdef.h> as traditionally being
often included in user assembly.  But then we should get rid of
configuration dependency entirely, i.e. remove "#include <linux/config.h>" 
and a CONFIG_CPU_HAS_PREFETCH dependency.  Perhaps <asm/pref.h> would be
desireable if we don't want wasting cycles.

 It's a pity a more reasonable choice wasn't made for the location of
these headers -- the asm and linux trees shouldn't really be used for
userland.  For example Alpha has <alpha/regdef.h> that comes from glibc.

---

From: Ralf Baechle <[email-masked]>
Date: Tue, 19 Aug 2003 14:34:53 +0200

> userland.  For example Alpha has <alpha/regdef.h> that comes from glibc. 

I completly agree on that.  Userspace should used <sys/regdef.h>,
<sys/fpregdef.h> and <sys/asm.h> for that which are the three de-facto
standard headers used throughout the MIPS world.

As for prefetching I like your suggestion of <asm/pref.h>.  The prefetching
stuff is a Linux extension of asm.h.  Moving it to it's own header file
along with the necessary bits for <linux/prefetch.h> would make a nice
cleanup.

  Ralf