From: Bernardo Innocenti <bernie@develer.com>

This patch does:

 - move the 64/32bit do_div() macro to the new asm-generic/div64.h
   header and kill multiple copies present in architecture specific
   subdirs. Most copies were either buggy or subtly different from
   each other;

 - ensure all surviving instances of do_div() have their parameters
   correctly parenthesized to avoid funny results;

Note that the arm26, cris, m68knommu, sh, sparc and v850 architectures are
silently clipping 64bit dividend to 32bit!  This patch doesn't try to fix
this because I can't test on all architectures.

Patch submitted by Bernardo Innocenti <bernie@develer.com> (who wasted
several hours trying to figure out why shrink_slab() was causing a division
by zero trap on m68knommu)




 include/asm-alpha/div64.h     |   15 +--------------
 include/asm-arm26/div64.h     |   15 +--------------
 include/asm-cris/div64.h      |   17 +----------------
 include/asm-generic/div64.h   |   13 +++++++++++++
 include/asm-h8300/div64.h     |   14 +-------------
 include/asm-ia64/div64.h      |   21 +--------------------
 include/asm-m68k/div64.h      |    9 ---------
 include/asm-m68knommu/div64.h |   14 +-------------
 include/asm-mips64/div64.h    |   19 +------------------
 include/asm-parisc/div64.h    |   36 ++++++++++--------------------------
 include/asm-ppc64/div64.h     |   19 +------------------
 include/asm-s390/div64.h      |    8 +-------
 include/asm-sh/div64.h        |   11 +----------
 include/asm-sparc/div64.h     |   12 +-----------
 include/asm-sparc64/div64.h   |   15 +--------------
 include/asm-v850/div64.h      |   12 +-----------
 include/asm-x86_64/div64.h    |   15 +--------------
 17 files changed, 37 insertions(+), 228 deletions(-)

diff -puN include/asm-alpha/div64.h~div64-cleanup include/asm-alpha/div64.h
--- 25/include/asm-alpha/div64.h~div64-cleanup	2003-06-26 18:42:18.000000000 -0700
+++ 25-akpm/include/asm-alpha/div64.h	2003-06-26 18:42:18.000000000 -0700
@@ -1,14 +1 @@
-#ifndef __ALPHA_DIV64
-#define __ALPHA_DIV64
-
-/*
- * Hey, we're already 64-bit, no
- * need to play games..
- */
-#define do_div(n,base) ({ \
-	int __res; \
-	__res = ((unsigned long) (n)) % (unsigned) (base); \
-	(n) = ((unsigned long) (n)) / (unsigned) (base); \
-	__res; })
-
-#endif
+#include <asm-generic/div64.h>
diff -puN include/asm-arm26/div64.h~div64-cleanup include/asm-arm26/div64.h
--- 25/include/asm-arm26/div64.h~div64-cleanup	2003-06-26 18:42:18.000000000 -0700
+++ 25-akpm/include/asm-arm26/div64.h	2003-06-26 18:42:18.000000000 -0700
@@ -1,14 +1 @@
-#ifndef __ASM_ARM_DIV64
-#define __ASM_ARM_DIV64
-
-/* We're not 64-bit, but... */
-#define do_div(n,base)						\
-({								\
-	int __res;						\
-	__res = ((unsigned long)n) % (unsigned int)base;	\
-	n = ((unsigned long)n) / (unsigned int)base;		\
-	__res;							\
-})
-
-#endif
-
+#include <asm-generic/div64.h>
diff -puN include/asm-cris/div64.h~div64-cleanup include/asm-cris/div64.h
--- 25/include/asm-cris/div64.h~div64-cleanup	2003-06-26 18:42:18.000000000 -0700
+++ 25-akpm/include/asm-cris/div64.h	2003-06-26 18:42:18.000000000 -0700
@@ -1,16 +1 @@
-#ifndef __ASM_CRIS_DIV64
-#define __ASM_CRIS_DIV64
-
-/* copy from asm-arm */
-
-/* We're not 64-bit, but... */
-#define do_div(n,base)						\
-({								\
-	int __res;						\
-	__res = ((unsigned long)n) % (unsigned int)base;	\
-	n = ((unsigned long)n) / (unsigned int)base;		\
-	__res;							\
-})
-
-#endif
-
+#include <asm-generic/div64.h>
diff -puN /dev/null include/asm-generic/div64.h
--- /dev/null	2002-08-30 16:31:37.000000000 -0700
+++ 25-akpm/include/asm-generic/div64.h	2003-06-26 18:42:18.000000000 -0700
@@ -0,0 +1,13 @@
+#ifndef _ASM_GENERIC_DIV64_H
+#define _ASM_GENERIC_DIV64_H
+
+/* n = n / base; return rem; */
+
+#define do_div(n,base) ({					\
+	int __res;						\
+	__res = ((unsigned long)(n)) % (unsigned)(base);	\
+	(n) = ((unsigned long)(n)) / (unsigned)(base);		\
+	__res;							\
+})
+
+#endif /* _ASM_GENERIC_DIV64_H */
diff -puN include/asm-h8300/div64.h~div64-cleanup include/asm-h8300/div64.h
--- 25/include/asm-h8300/div64.h~div64-cleanup	2003-06-26 18:42:18.000000000 -0700
+++ 25-akpm/include/asm-h8300/div64.h	2003-06-26 18:42:18.000000000 -0700
@@ -1,13 +1 @@
-#ifndef H8300_DIV64_H
-#define H8300_DIV64_H
-
-/* n = n / base; return rem; */
-
-#define do_div(n,base) ({					\
-	int __res;						\
-	__res = ((unsigned long) n) % (unsigned) base;		\
-	n = ((unsigned long) n) / (unsigned) base;		\
-	__res;							\
-})
-
-#endif /* _H8300_DIV64_H */
+#include <asm-generic/div64.h>
diff -puN include/asm-ia64/div64.h~div64-cleanup include/asm-ia64/div64.h
--- 25/include/asm-ia64/div64.h~div64-cleanup	2003-06-26 18:42:18.000000000 -0700
+++ 25-akpm/include/asm-ia64/div64.h	2003-06-26 18:42:18.000000000 -0700
@@ -1,20 +1 @@
-#ifndef _ASM_IA64_DIV64_H
-#define _ASM_IA64_DIV64_H
-
-/*
- * Copyright (C) 1999 Hewlett-Packard Co
- * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * vsprintf uses this to divide a 64-bit integer N by a small integer BASE.
- * This is incredibly hard on IA-64...
- */
-
-#define do_div(n,base)						\
-({								\
-	int _res;						\
-	_res = ((unsigned long) (n)) % (unsigned) (base);	\
-	(n) = ((unsigned long) (n)) / (unsigned) (base);	\
-	_res;							\
-})
-
-#endif /* _ASM_IA64_DIV64_H */
+#include <asm-generic/div64.h>
diff -puN include/asm-m68k/div64.h~div64-cleanup include/asm-m68k/div64.h
--- 25/include/asm-m68k/div64.h~div64-cleanup	2003-06-26 18:42:18.000000000 -0700
+++ 25-akpm/include/asm-m68k/div64.h	2003-06-26 18:42:18.000000000 -0700
@@ -3,7 +3,6 @@
 
 /* n = n / base; return rem; */
 
-#if 1
 #define do_div(n, base) ({					\
 	union {							\
 		unsigned long n32[2];				\
@@ -23,13 +22,5 @@
 	(n) = __n.n64;						\
 	__rem;							\
 })
-#else
-#define do_div(n,base) ({					\
-	int __res;						\
-	__res = ((unsigned long) n) % (unsigned) base;		\
-	n = ((unsigned long) n) / (unsigned) base;		\
-	__res;							\
-})
-#endif
 
 #endif /* _M68K_DIV64_H */
diff -puN include/asm-m68knommu/div64.h~div64-cleanup include/asm-m68knommu/div64.h
--- 25/include/asm-m68knommu/div64.h~div64-cleanup	2003-06-26 18:42:18.000000000 -0700
+++ 25-akpm/include/asm-m68knommu/div64.h	2003-06-26 18:42:18.000000000 -0700
@@ -1,13 +1 @@
-#ifndef _M68KNOMMU_DIV64_H
-#define _M68KNOMMU_DIV64_H
-
-/* n = n / base; return rem; */
-
-#define do_div(n,base) ({					\
-	int __res;						\
-	__res = ((unsigned long) n) % (unsigned) base;		\
-	n = ((unsigned long) n) / (unsigned) base;		\
-	__res;							\
-})
-
-#endif /* _M68K_DIV64_H */
+#include <asm-generic/div64.h>
diff -puN include/asm-mips64/div64.h~div64-cleanup include/asm-mips64/div64.h
--- 25/include/asm-mips64/div64.h~div64-cleanup	2003-06-26 18:42:18.000000000 -0700
+++ 25-akpm/include/asm-mips64/div64.h	2003-06-26 18:42:18.000000000 -0700
@@ -27,23 +27,6 @@
 	(res) = __quot; \
 	__mod; })
 
-/*
- * Hey, we're already 64-bit, no
- * need to play games..
- */
-#define do_div(n, base) ({ \
-	unsigned long __quot; \
-	unsigned int __mod; \
-	unsigned long __div; \
-	unsigned int __base; \
-	\
-	__div = (n); \
-	__base = (base); \
-	\
-	__mod = __div % __base; \
-	__quot = __div / __base; \
-	\
-	(n) = __quot; \
-	__mod; })
+#include <asm-generic/div64.h>
 
 #endif /* _ASM_DIV64_H */
diff -puN include/asm-parisc/div64.h~div64-cleanup include/asm-parisc/div64.h
--- 25/include/asm-parisc/div64.h~div64-cleanup	2003-06-26 18:42:18.000000000 -0700
+++ 25-akpm/include/asm-parisc/div64.h	2003-06-26 18:42:18.000000000 -0700
@@ -2,23 +2,7 @@
 #define __ASM_PARISC_DIV64
 
 #ifdef __LP64__
-
-/*
- * Copyright (C) 1999 Hewlett-Packard Co
- * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * vsprintf uses this to divide a 64-bit integer N by a small integer BASE.
- * This is incredibly hard on IA-64 and HPPA
- */
-
-#define do_div(n,base)						\
-({								\
-	int _res;						\
-	_res = ((unsigned long) (n)) % (unsigned) (base);	\
-	(n) = ((unsigned long) (n)) / (unsigned) (base);	\
-	_res;							\
-})
-
+#include <asm-generic/div64.h>
 #else
 /*
  * unsigned long long division.  Yuck Yuck!  What is Linux coming to?
@@ -30,21 +14,21 @@
 	__low  = (n) & 0xffffffff;					\
 	__high = (n) >> 32;						\
 	if (__high) {							\
-		__rem   = __high % (unsigned long)base;			\
-		__high  = __high / (unsigned long)base;			\
+		__rem   = __high % (unsigned long)(base);		\
+		__high  = __high / (unsigned long)(base);		\
 		__low2  = __low >> 16;					\
 		__low2 += __rem << 16;					\
-		__rem   = __low2 % (unsigned long)base;			\
-		__low2  = __low2 / (unsigned long)base;			\
+		__rem   = __low2 % (unsigned long)(base);		\
+		__low2  = __low2 / (unsigned long)(base);		\
 		__low   = __low & 0xffff;				\
 		__low  += __rem << 16;					\
-		__rem   = __low  % (unsigned long)base;			\
-		__low   = __low  / (unsigned long)base;			\
-		n = __low  + ((long long)__low2 << 16) +		\
+		__rem   = __low  % (unsigned long)(base);		\
+		__low   = __low  / (unsigned long)(base);		\
+		(n) = __low  + ((long long)__low2 << 16) +		\
 			((long long) __high << 32);			\
 	} else {							\
-		__rem = __low % (unsigned long)base;			\
-		n = (__low / (unsigned long)base);			\
+		__rem = __low % (unsigned long)(base);			\
+		(n) = (__low / (unsigned long)(base));			\
 	}								\
 	__rem;								\
 })
diff -puN include/asm-ppc64/div64.h~div64-cleanup include/asm-ppc64/div64.h
--- 25/include/asm-ppc64/div64.h~div64-cleanup	2003-06-26 18:42:18.000000000 -0700
+++ 25-akpm/include/asm-ppc64/div64.h	2003-06-26 18:42:18.000000000 -0700
@@ -1,18 +1 @@
-#ifndef __PPC_DIV64
-#define __PPC_DIV64
-
-/* Copyright 2001 PPC64 Team, IBM Corp
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#define do_div(n,base) ({ \
-	int __res; \
-	__res = ((unsigned long) (n)) % (unsigned) (base); \
-	(n) = ((unsigned long) (n)) / (unsigned) (base); \
-	__res; })
-
-#endif
+#include <asm-generic/div64.h>
diff -puN include/asm-s390/div64.h~div64-cleanup include/asm-s390/div64.h
--- 25/include/asm-s390/div64.h~div64-cleanup	2003-06-26 18:42:18.000000000 -0700
+++ 25-akpm/include/asm-s390/div64.h	2003-06-26 18:42:18.000000000 -0700
@@ -43,13 +43,7 @@
 })
 
 #else /* __s390x__ */
-
-#define do_div(n,base) ({ \
-int __res; \
-__res = ((unsigned long) n) % (unsigned) base; \
-n = ((unsigned long) n) / (unsigned) base; \
-__res; })
-
+#include <asm-generic/div64.h>
 #endif /* __s390x__ */
 
 #endif
diff -puN include/asm-sh/div64.h~div64-cleanup include/asm-sh/div64.h
--- 25/include/asm-sh/div64.h~div64-cleanup	2003-06-26 18:42:18.000000000 -0700
+++ 25-akpm/include/asm-sh/div64.h	2003-06-26 18:42:18.000000000 -0700
@@ -1,10 +1 @@
-#ifndef __ASM_SH_DIV64
-#define __ASM_SH_DIV64
-
-#define do_div(n,base) ({ \
-int __res; \
-__res = ((unsigned long) n) % (unsigned) base; \
-n = ((unsigned long) n) / (unsigned) base; \
-__res; })
-
-#endif /* __ASM_SH_DIV64 */
+#include <asm-generic/div64.h>
diff -puN include/asm-sparc64/div64.h~div64-cleanup include/asm-sparc64/div64.h
--- 25/include/asm-sparc64/div64.h~div64-cleanup	2003-06-26 18:42:18.000000000 -0700
+++ 25-akpm/include/asm-sparc64/div64.h	2003-06-26 18:42:18.000000000 -0700
@@ -1,14 +1 @@
-#ifndef __SPARC64_DIV64
-#define __SPARC64_DIV64
-
-/*
- * Hey, we're already 64-bit, no
- * need to play games..
- */
-#define do_div(n,base) ({ \
-	int __res; \
-	__res = ((unsigned long) n) % (unsigned) base; \
-	n = ((unsigned long) n) / (unsigned) base; \
-	__res; })
-
-#endif /* __SPARC64_DIV64 */
+#include <asm-generic/div64.h>
diff -puN include/asm-sparc/div64.h~div64-cleanup include/asm-sparc/div64.h
--- 25/include/asm-sparc/div64.h~div64-cleanup	2003-06-26 18:42:18.000000000 -0700
+++ 25-akpm/include/asm-sparc/div64.h	2003-06-26 18:42:18.000000000 -0700
@@ -1,11 +1 @@
-#ifndef __SPARC_DIV64
-#define __SPARC_DIV64
-
-/* We're not 64-bit, but... */
-#define do_div(n,base) ({ \
-	int __res; \
-	__res = ((unsigned long) n) % (unsigned) base; \
-	n = ((unsigned long) n) / (unsigned) base; \
-	__res; })
-
-#endif /* __SPARC_DIV64 */
+#include <asm-generic/div64.h>
diff -puN include/asm-v850/div64.h~div64-cleanup include/asm-v850/div64.h
--- 25/include/asm-v850/div64.h~div64-cleanup	2003-06-26 18:42:18.000000000 -0700
+++ 25-akpm/include/asm-v850/div64.h	2003-06-26 18:42:18.000000000 -0700
@@ -1,11 +1 @@
-#ifndef __V850_DIV64_H__
-#define __V850_DIV64_H__
-
-/* We're not 64-bit, but... */
-#define do_div(n,base) ({ \
-	int __res; \
-	__res = ((unsigned long) n) % (unsigned) base; \
-	n = ((unsigned long) n) / (unsigned) base; \
-	__res; })
-
-#endif /* __V850_DIV64_H__ */
+#include <asm-generic/div64.h>
diff -puN include/asm-x86_64/div64.h~div64-cleanup include/asm-x86_64/div64.h
--- 25/include/asm-x86_64/div64.h~div64-cleanup	2003-06-26 18:42:18.000000000 -0700
+++ 25-akpm/include/asm-x86_64/div64.h	2003-06-26 18:42:18.000000000 -0700
@@ -1,14 +1 @@
-#ifndef __X86_64_DIV64
-#define __X86_64_DIV64
-
-/*
- * Hey, we're already 64-bit, no
- * need to play games..
- */
-#define do_div(n,base) ({ \
-	int __res; \
-	__res = ((unsigned long) (n)) % (unsigned) (base); \
-	(n) = ((unsigned long) (n)) / (unsigned) (base); \
-	__res; })
-
-#endif
+#include <asm-generic/div64.h>

_