Subject: mips64 cpu-probe.c compile failure

From: Atsushi Nemoto <[email-masked]>
Date: Thu, 18 Sep 2003 18:05:36 +0900 (JST)

>>>>> On Tue, 16 Sep 2003 16:12:57 +0100, [email-masked] said:
macro> Modified files:
macro> 	arch/mips64/kernel: Tag: linux_2_4 cpu-probe.c 

macro> Log message:
macro> 	Fix indeterminism in the multiply/shift erratum detection leading
macro> 	to false negatives.  Plus a few minor comment updates for clarity.

gcc 3.3.1 can not compile current (2.4) arch/mips64/kernel/cpu-probe.c.

cpu-probe.c:118: warning: asm operand 0 probably doesn't match constraints
cpu-probe.c:118: warning: asm operand 1 probably doesn't match constraints
...
cpu-probe.c: In function `check_mult_sh':
cpu-probe.c:118: error: impossible constraint in `asm'

The code is:

static inline void align_mod(int align, int mod)
{
	asm volatile(
		".set	push\n\t"
		".set	noreorder\n\t"
		".balign %0\n\t"
		".rept	%1\n\t"
		"nop\n\t"
		".endr\n\t"
		".set	pop"
		:
		: "i" (align), "i" (mod));
}

The align_mod() and mult_sh_align_mod() should be written as macro?

---
Atsushi Nemoto

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Thu, 18 Sep 2003 12:17:54 +0200 (MET DST)

> cpu-probe.c:118: error: impossible constraint in `asm'

 Hmm, perhaps 3.3.1 fails to inline the functions...  It works just fine
with 2.95.4.

> The align_mod() and mult_sh_align_mod() should be written as macro?

 I wanted to avoid that as the resulting code would be ugly.  I guess
there is no other choice, although I think that's a bug in gcc.

 Can you quote the exact command line used for building the file?

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

---

From: Atsushi Nemoto <[email-masked]>
Date: Thu, 18 Sep 2003 23:22:02 +0900 (JST)

>>>>> On Thu, 18 Sep 2003 12:17:54 +0200 (MET DST), "Maciej W. Rozycki" <[email-masked]> said:

macro>  I wanted to avoid that as the resulting code would be ugly.  I
macro> guess there is no other choice, although I think that's a bug
macro> in gcc.

I have no idea that is a gcc bug, but I think align_mod() inline
function is not so beautiful because it can not be compiled anyway if
non-constant value was passed.

macro>  Can you quote the exact command line used for building the
macro> file?

mips64el-linux-gcc -D__KERNEL__ -I/home/anemo/work/linux/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -fomit-frame-pointer -I /home/anemo/work/linux/include/asm/gcc -mabi=64 -G 0 -mno-abicalls -fno-pic -Wa,--trap -pipe  -march=r4600   -nostdinc -iwithprefix include -DKBUILD_BASENAME=cpu_probe  -c -o cpu-probe.o cpu-probe.c

I also tried with -finline-limit=100000 but no luck.

Does this help?

---
Atsushi Nemoto

---

From: "Maciej W. Rozycki" <[email-masked]>
Date: Fri, 19 Sep 2003 13:55:45 +0200 (MET DST)

> non-constant value was passed.

 Well, the asm statement requires immediates, so if macros are used
variables won't work anyway, but the the code will look more obscurely.

> I also tried with -finline-limit=100000 but no luck.

 It looks like gcc insists on forcing the constants into registers.  The
following patch should work for gcc 3.x.  A few warnings will still be
emitted, but the code will get build properly.

 I'm applying the change to the CVS as it's good anyway.

  Maciej

patch-mips-2.4.22-20030916-mips-bugs-gcc3-0
diff -up --recursive --new-file linux-mips-2.4.22-20030916.macro/arch/mips64/kernel/cpu-probe.c linux-mips-2.4.22-20030916/arch/mips64/kernel/cpu-probe.c
--- linux-mips-2.4.22-20030916.macro/arch/mips64/kernel/cpu-probe.c	2003-09-12 01:18:01.000000000 +0000
+++ linux-mips-2.4.22-20030916/arch/mips64/kernel/cpu-probe.c	2003-09-18 22:14:19.000000000 +0000
@@ -113,7 +113,7 @@ static inline void check_wait(void)
 	}
 }
 
-static inline void align_mod(int align, int mod)
+static inline void align_mod(const int align, const int mod)
 {
 	asm volatile(
 		".set	push\n\t"
@@ -124,11 +124,11 @@ static inline void align_mod(int align, 
 		".endr\n\t"
 		".set	pop"
 		:
-		: "i" (align), "i" (mod));
+		: "n" (align), "n" (mod));
 }
 
 static inline void mult_sh_align_mod(long *v1, long *v2, long *w,
-				     int align, int mod)
+				     const int align, const int mod)
 {
 	unsigned long flags;
 	int m1, m2;

---

From: Atsushi Nemoto <[email-masked]>
Date: Fri, 19 Sep 2003 23:21:23 +0900 (JST)

>>>>> On Fri, 19 Sep 2003 13:55:45 +0200 (MET DST), "Maciej W. Rozycki" <[email-masked]> said:
macro>  Well, the asm statement requires immediates, so if macros are
macro> used variables won't work anyway, but the the code will look
macro> more obscurely.

Yes, though variables won't work anyway, the inline function looks
like it can accept variables (for careless reader).  But that's just
my impression.

macro>  It looks like gcc insists on forcing the constants into
macro> registers.  The following patch should work for gcc 3.x.  A few
macro> warnings will still be emitted, but the code will get build
macro> properly.

Thanks.  It works fine with gcc 3.3.1.
---
Atsushi Nemoto