From: Bernardo Innocenti 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 (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 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 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 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 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 - * - * 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 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 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 #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 - * - * 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 #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 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 #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 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 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 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 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 _