From: "H. Peter Anvin" Declaring a function to return a const scalar value is pretty meaningless. These functions are really trying to say that they don't alter any external state. Fix that up by using __attribute__((const)), if the compiler supports that. include/asm-cris/arch-v10/byteorder.h | 5 +++-- include/asm-i386/byteorder.h | 20 ++++++-------------- include/asm-ia64/byteorder.h | 7 ++++--- include/asm-m68k/byteorder.h | 3 ++- include/asm-parisc/byteorder.h | 11 ++++++----- include/asm-ppc/byteorder.h | 5 +++-- include/asm-ppc64/byteorder.h | 7 ++++--- include/asm-s390/byteorder.h | 13 +++++++------ include/asm-sh/byteorder.h | 5 +++-- include/asm-v850/byteorder.h | 5 +++-- include/asm-x86_64/byteorder.h | 5 +++-- include/linux/byteorder/swab.h | 8 +++++--- include/linux/compiler-gcc+.h | 1 + include/linux/compiler-gcc2.h | 1 + include/linux/compiler-gcc3.h | 1 + include/linux/compiler.h | 18 ++++++++++++++++++ 16 files changed, 70 insertions(+), 45 deletions(-) diff -puN include/asm-cris/arch-v10/byteorder.h~const-fixes include/asm-cris/arch-v10/byteorder.h --- 25/include/asm-cris/arch-v10/byteorder.h~const-fixes 2003-12-21 23:45:22.000000000 -0800 +++ 25-akpm/include/asm-cris/arch-v10/byteorder.h 2003-12-21 23:45:22.000000000 -0800 @@ -2,20 +2,21 @@ #define _CRIS_ARCH_BYTEORDER_H #include +#include /* we just define these two (as we can do the swap in a single * asm instruction in CRIS) and the arch-independent files will put * them together into ntohl etc. */ -extern __inline__ __const__ __u32 ___arch__swab32(__u32 x) +extern __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) { __asm__ ("swapwb %0" : "=r" (x) : "0" (x)); return(x); } -extern __inline__ __const__ __u16 ___arch__swab16(__u16 x) +extern __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x) { __asm__ ("swapb %0" : "=r" (x) : "0" (x)); diff -puN include/asm-i386/byteorder.h~const-fixes include/asm-i386/byteorder.h --- 25/include/asm-i386/byteorder.h~const-fixes 2003-12-21 23:45:22.000000000 -0800 +++ 25-akpm/include/asm-i386/byteorder.h 2003-12-21 23:45:22.000000000 -0800 @@ -2,6 +2,7 @@ #define _I386_BYTEORDER_H #include +#include #ifdef __GNUC__ @@ -10,7 +11,7 @@ #include #endif -static __inline__ __const__ __u32 ___arch__swab32(__u32 x) +static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) { #ifdef CONFIG_X86_BSWAP __asm__("bswap %0" : "=r" (x) : "0" (x)); @@ -24,18 +25,7 @@ static __inline__ __const__ __u32 ___arc return x; } -/* gcc should generate this for open coded C now too. May be worth switching to - it because inline assembly cannot be scheduled. -AK */ -static __inline__ __const__ __u16 ___arch__swab16(__u16 x) -{ - __asm__("xchgb %b0,%h0" /* swap bytes */ - : "=q" (x) - : "0" (x)); - return x; -} - - -static inline __u64 ___arch__swab64(__u64 val) +static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 val) { union { struct { __u32 a,b; } s; @@ -54,9 +44,11 @@ static inline __u64 ___arch__swab64(__u6 return v.u; } +/* Do not define swab16. Gcc is smart enough to recognize "C" version and + convert it into rotation or exhange. */ + #define __arch__swab64(x) ___arch__swab64(x) #define __arch__swab32(x) ___arch__swab32(x) -#define __arch__swab16(x) ___arch__swab16(x) #define __BYTEORDER_HAS_U64__ diff -puN include/asm-ia64/byteorder.h~const-fixes include/asm-ia64/byteorder.h --- 25/include/asm-ia64/byteorder.h~const-fixes 2003-12-21 23:45:22.000000000 -0800 +++ 25-akpm/include/asm-ia64/byteorder.h 2003-12-21 23:45:22.000000000 -0800 @@ -8,8 +8,9 @@ #include #include +#include -static __inline__ __const__ __u64 +static __inline__ __attribute_const__ __u64 __ia64_swab64 (__u64 x) { __u64 result; @@ -18,13 +19,13 @@ __ia64_swab64 (__u64 x) return result; } -static __inline__ __const__ __u32 +static __inline__ __attribute_const__ __u32 __ia64_swab32 (__u32 x) { return __ia64_swab64(x) >> 32; } -static __inline__ __const__ __u16 +static __inline__ __attribute_const__ __u16 __ia64_swab16(__u16 x) { return __ia64_swab64(x) >> 48; diff -puN include/asm-m68k/byteorder.h~const-fixes include/asm-m68k/byteorder.h --- 25/include/asm-m68k/byteorder.h~const-fixes 2003-12-21 23:45:22.000000000 -0800 +++ 25-akpm/include/asm-m68k/byteorder.h 2003-12-21 23:45:22.000000000 -0800 @@ -2,10 +2,11 @@ #define _M68K_BYTEORDER_H #include +#include #ifdef __GNUC__ -static __inline__ __const__ __u32 ___arch__swab32(__u32 val) +static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 val) { __asm__("rolw #8,%0; swap %0; rolw #8,%0" : "=d" (val) : "0" (val)); return val; diff -puN include/asm-parisc/byteorder.h~const-fixes include/asm-parisc/byteorder.h --- 25/include/asm-parisc/byteorder.h~const-fixes 2003-12-21 23:45:22.000000000 -0800 +++ 25-akpm/include/asm-parisc/byteorder.h 2003-12-21 23:45:22.000000000 -0800 @@ -2,10 +2,11 @@ #define _PARISC_BYTEORDER_H #include +#include #ifdef __GNUC__ -static __inline__ __const__ __u16 ___arch__swab16(__u16 x) +static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x) { __asm__("dep %0, 15, 8, %0\n\t" /* deposit 00ab -> 0bab */ "shd %%r0, %0, 8, %0" /* shift 000000ab -> 00ba */ @@ -14,7 +15,7 @@ static __inline__ __const__ __u16 ___arc return x; } -static __inline__ __const__ __u32 ___arch__swab24(__u32 x) +static __inline__ __attribute_const__ __u32 ___arch__swab24(__u32 x) { __asm__("shd %0, %0, 8, %0\n\t" /* shift xabcxabc -> cxab */ "dep %0, 15, 8, %0\n\t" /* deposit cxab -> cbab */ @@ -24,7 +25,7 @@ static __inline__ __const__ __u32 ___arc return x; } -static __inline__ __const__ __u32 ___arch__swab32(__u32 x) +static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) { unsigned int temp; __asm__("shd %0, %0, 16, %1\n\t" /* shift abcdabcd -> cdab */ @@ -47,7 +48,7 @@ static __inline__ __const__ __u32 ___arc ** HSHR 67452301 -> *6*4*2*0 into %0 ** OR %0 | %1 -> 76543210 into %0 (all done!) */ -static __inline__ __const__ __u64 ___arch__swab64(__u64 x) { +static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x) { __u64 temp; __asm__("permh,3210 %0, %0\n\t" "hshl %0, 8, %1\n\t" @@ -60,7 +61,7 @@ static __inline__ __const__ __u64 ___arc #define __arch__swab64(x) ___arch__swab64(x) #define __BYTEORDER_HAS_U64__ #elif !defined(__STRICT_ANSI__) -static __inline__ __const__ __u64 ___arch__swab64(__u64 x) +static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x) { __u32 t1 = ___arch__swab32((__u32) x); __u32 t2 = ___arch__swab32((__u32) (x >> 32)); diff -puN include/asm-ppc64/byteorder.h~const-fixes include/asm-ppc64/byteorder.h --- 25/include/asm-ppc64/byteorder.h~const-fixes 2003-12-21 23:45:22.000000000 -0800 +++ 25-akpm/include/asm-ppc64/byteorder.h 2003-12-21 23:45:22.000000000 -0800 @@ -9,6 +9,7 @@ */ #include +#include #ifdef __GNUC__ #ifdef __KERNEL__ @@ -40,7 +41,7 @@ static __inline__ void st_le32(volatile } #if 0 -static __inline__ __const__ __u16 ___arch__swab16(__u16 value) +static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value) { __u16 result; @@ -50,7 +51,7 @@ static __inline__ __const__ __u16 ___arc return result; } -static __inline__ __const__ __u32 ___arch__swab32(__u32 value) +static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value) { __u32 result; @@ -62,7 +63,7 @@ static __inline__ __const__ __u32 ___arc return result; } -static __inline__ __const__ __u64 ___arch__swab64(__u64 value) +static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 value) { __u64 result; #error implement me diff -puN include/asm-ppc/byteorder.h~const-fixes include/asm-ppc/byteorder.h --- 25/include/asm-ppc/byteorder.h~const-fixes 2003-12-21 23:45:22.000000000 -0800 +++ 25-akpm/include/asm-ppc/byteorder.h 2003-12-21 23:45:22.000000000 -0800 @@ -2,6 +2,7 @@ #define _PPC_BYTEORDER_H #include +#include #ifdef __GNUC__ #ifdef __KERNEL__ @@ -32,7 +33,7 @@ extern __inline__ void st_le32(volatile __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); } -static __inline__ __const__ __u16 ___arch__swab16(__u16 value) +static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value) { __u16 result; @@ -40,7 +41,7 @@ static __inline__ __const__ __u16 ___arc return result; } -static __inline__ __const__ __u32 ___arch__swab32(__u32 value) +static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value) { __u32 result; diff -puN include/asm-s390/byteorder.h~const-fixes include/asm-s390/byteorder.h --- 25/include/asm-s390/byteorder.h~const-fixes 2003-12-21 23:45:22.000000000 -0800 +++ 25-akpm/include/asm-s390/byteorder.h 2003-12-21 23:45:22.000000000 -0800 @@ -10,11 +10,12 @@ */ #include +#include #ifdef __GNUC__ #ifdef __s390x__ -static __inline__ __const__ __u64 ___arch__swab64p(__u64 *x) +static __inline__ __attribute_const__ __u64 ___arch__swab64p(__u64 *x) { __u64 result; @@ -24,7 +25,7 @@ static __inline__ __const__ __u64 ___arc return result; } -static __inline__ __const__ __u64 ___arch__swab64(__u64 x) +static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x) { __u64 result; @@ -40,7 +41,7 @@ static __inline__ void ___arch__swab64s( } #endif /* __s390x__ */ -static __inline__ __const__ __u32 ___arch__swab32p(__u32 *x) +static __inline__ __attribute_const__ __u32 ___arch__swab32p(__u32 *x) { __u32 result; @@ -58,7 +59,7 @@ static __inline__ __const__ __u32 ___arc return result; } -static __inline__ __const__ __u32 ___arch__swab32(__u32 x) +static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) { #ifndef __s390x__ return ___arch__swab32p(&x); @@ -77,7 +78,7 @@ static __inline__ void ___arch__swab32s( *x = ___arch__swab32p(x); } -static __inline__ __const__ __u16 ___arch__swab16p(__u16 *x) +static __inline__ __attribute_const__ __u16 ___arch__swab16p(__u16 *x) { __u16 result; @@ -93,7 +94,7 @@ static __inline__ __const__ __u16 ___arc return result; } -static __inline__ __const__ __u16 ___arch__swab16(__u16 x) +static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x) { return ___arch__swab16p(&x); } diff -puN include/asm-sh/byteorder.h~const-fixes include/asm-sh/byteorder.h --- 25/include/asm-sh/byteorder.h~const-fixes 2003-12-21 23:45:22.000000000 -0800 +++ 25-akpm/include/asm-sh/byteorder.h 2003-12-21 23:45:22.000000000 -0800 @@ -6,8 +6,9 @@ */ #include +#include -static __inline__ __const__ __u32 ___arch__swab32(__u32 x) +static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) { __asm__("swap.b %0, %0\n\t" "swap.w %0, %0\n\t" @@ -17,7 +18,7 @@ static __inline__ __const__ __u32 ___arc return x; } -static __inline__ __const__ __u16 ___arch__swab16(__u16 x) +static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x) { __asm__("swap.b %0, %0" : "=r" (x) diff -puN include/asm-v850/byteorder.h~const-fixes include/asm-v850/byteorder.h --- 25/include/asm-v850/byteorder.h~const-fixes 2003-12-21 23:45:22.000000000 -0800 +++ 25-akpm/include/asm-v850/byteorder.h 2003-12-21 23:45:22.000000000 -0800 @@ -15,17 +15,18 @@ #define __V850_BYTEORDER_H__ #include +#include #ifdef __GNUC__ -static __inline__ __const__ __u32 ___arch__swab32 (__u32 word) +static __inline__ __attribute_const__ __u32 ___arch__swab32 (__u32 word) { __u32 res; __asm__ ("bsw %1, %0" : "=r" (res) : "r" (word)); return res; } -static __inline__ __const__ __u16 ___arch__swab16 (__u16 half_word) +static __inline__ __attribute_const__ __u16 ___arch__swab16 (__u16 half_word) { __u16 res; __asm__ ("bsh %1, %0" : "=r" (res) : "r" (half_word)); diff -puN include/asm-x86_64/byteorder.h~const-fixes include/asm-x86_64/byteorder.h --- 25/include/asm-x86_64/byteorder.h~const-fixes 2003-12-21 23:45:22.000000000 -0800 +++ 25-akpm/include/asm-x86_64/byteorder.h 2003-12-21 23:45:22.000000000 -0800 @@ -2,16 +2,17 @@ #define _X86_64_BYTEORDER_H #include +#include #ifdef __GNUC__ -static __inline__ __const__ __u64 ___arch__swab64(__u64 x) +static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 x) { __asm__("bswapq %0" : "=r" (x) : "0" (x)); return x; } -static __inline__ __const__ __u32 ___arch__swab32(__u32 x) +static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) { __asm__("bswapl %0" : "=r" (x) : "0" (x)); return x; diff -puN include/linux/byteorder/swab.h~const-fixes include/linux/byteorder/swab.h --- 25/include/linux/byteorder/swab.h~const-fixes 2003-12-21 23:45:22.000000000 -0800 +++ 25-akpm/include/linux/byteorder/swab.h 2003-12-21 23:45:22.000000000 -0800 @@ -15,6 +15,8 @@ * */ +#include + /* casts are necessary for constants, because we never know how for sure * how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way. */ @@ -128,7 +130,7 @@ #endif /* OPTIMIZE */ -static __inline__ __const__ __u16 __fswab16(__u16 x) +static __inline__ __attribute_const__ __u16 __fswab16(__u16 x) { return __arch__swab16(x); } @@ -141,7 +143,7 @@ static __inline__ void __swab16s(__u16 * __arch__swab16s(addr); } -static __inline__ __const__ __u32 __fswab32(__u32 x) +static __inline__ __attribute_const__ __u32 __fswab32(__u32 x) { return __arch__swab32(x); } @@ -155,7 +157,7 @@ static __inline__ void __swab32s(__u32 * } #ifdef __BYTEORDER_HAS_U64__ -static __inline__ __const__ __u64 __fswab64(__u64 x) +static __inline__ __attribute_const__ __u64 __fswab64(__u64 x) { # ifdef __SWAB_64_THRU_32__ __u32 h = x >> 32; diff -puN include/linux/compiler-gcc2.h~const-fixes include/linux/compiler-gcc2.h --- 25/include/linux/compiler-gcc2.h~const-fixes 2003-12-21 23:45:22.000000000 -0800 +++ 25-akpm/include/linux/compiler-gcc2.h 2003-12-21 23:45:22.000000000 -0800 @@ -20,4 +20,5 @@ */ #if __GNUC_MINOR__ >= 96 # define __attribute_pure__ __attribute__((pure)) +# define __attribute_const__ __attribute__((__const__)) #endif diff -puN include/linux/compiler-gcc3.h~const-fixes include/linux/compiler-gcc3.h --- 25/include/linux/compiler-gcc3.h~const-fixes 2003-12-21 23:45:22.000000000 -0800 +++ 25-akpm/include/linux/compiler-gcc3.h 2003-12-21 23:45:22.000000000 -0800 @@ -20,3 +20,4 @@ #endif #define __attribute_pure__ __attribute__((pure)) +#define __attribute_const__ __attribute__((__const__)) diff -puN include/linux/compiler-gcc+.h~const-fixes include/linux/compiler-gcc+.h --- 25/include/linux/compiler-gcc+.h~const-fixes 2003-12-21 23:45:22.000000000 -0800 +++ 25-akpm/include/linux/compiler-gcc+.h 2003-12-21 23:45:22.000000000 -0800 @@ -12,3 +12,4 @@ #define __deprecated __attribute__((deprecated)) #define __attribute_used__ __attribute__((__used__)) #define __attribute_pure__ __attribute__((pure)) +#define __attribute_const__ __attribute__((__const__)) diff -puN include/linux/compiler.h~const-fixes include/linux/compiler.h --- 25/include/linux/compiler.h~const-fixes 2003-12-21 23:45:22.000000000 -0800 +++ 25-akpm/include/linux/compiler.h 2003-12-21 23:45:22.000000000 -0800 @@ -76,6 +76,24 @@ # define __attribute_pure__ /* unimplemented */ #endif +/* + * From the GCC manual: + * + * Many functions do not examine any values except their arguments, + * and have no effects except the return value. Basically this is + * just slightly more strict class than the `pure' attribute above, + * since function is not allowed to read global memory. + * + * Note that a function that has pointer arguments and examines the + * data pointed to must _not_ be declared `const'. Likewise, a + * function that calls a non-`const' function usually must not be + * `const'. It does not make sense for a `const' function to return + * `void'. + */ +#ifndef __attribute_const__ +# define __attribute_const__ /* unimplemented */ +#endif + /* Optimization barrier */ #ifndef barrier # define barrier() __memory_barrier() _