Commit 0697fbd3 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] const vs. __attribute__((const)) confusion

From: "H. Peter Anvin" <hpa@zytor.com>

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.
parent 477702e9
......@@ -2,20 +2,21 @@
#define _CRIS_ARCH_BYTEORDER_H
#include <asm/types.h>
#include <linux/compiler.h>
/* 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));
......
......@@ -2,6 +2,7 @@
#define _I386_BYTEORDER_H
#include <asm/types.h>
#include <linux/compiler.h>
#ifdef __GNUC__
......@@ -10,7 +11,7 @@
#include <linux/config.h>
#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 ___arch__swab32(__u32 x)
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(__u64 val)
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__
......
......@@ -8,8 +8,9 @@
#include <asm/types.h>
#include <asm/intrinsics.h>
#include <linux/compiler.h>
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;
......
......@@ -2,10 +2,11 @@
#define _M68K_BYTEORDER_H
#include <asm/types.h>
#include <linux/compiler.h>
#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;
......
......@@ -2,10 +2,11 @@
#define _PARISC_BYTEORDER_H
#include <asm/types.h>
#include <linux/compiler.h>
#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 ___arch__swab16(__u16 x)
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 ___arch__swab24(__u32 x)
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 ___arch__swab32(__u32 x)
** 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 ___arch__swab64(__u64 x) {
#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));
......
......@@ -2,6 +2,7 @@
#define _PPC_BYTEORDER_H
#include <asm/types.h>
#include <linux/compiler.h>
#ifdef __GNUC__
#ifdef __KERNEL__
......@@ -32,7 +33,7 @@ extern __inline__ void st_le32(volatile unsigned *addr, const unsigned val)
__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 ___arch__swab16(__u16 value)
return result;
}
static __inline__ __const__ __u32 ___arch__swab32(__u32 value)
static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value)
{
__u32 result;
......
......@@ -9,6 +9,7 @@
*/
#include <asm/types.h>
#include <linux/compiler.h>
#ifdef __GNUC__
#ifdef __KERNEL__
......@@ -40,7 +41,7 @@ static __inline__ void st_le32(volatile __u32 *addr, const __u32 val)
}
#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 ___arch__swab16(__u16 value)
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 ___arch__swab32(__u32 value)
return result;
}
static __inline__ __const__ __u64 ___arch__swab64(__u64 value)
static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 value)
{
__u64 result;
#error implement me
......
......@@ -6,8 +6,9 @@
*/
#include <asm/types.h>
#include <linux/compiler.h>
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 ___arch__swab32(__u32 x)
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)
......
......@@ -15,17 +15,18 @@
#define __V850_BYTEORDER_H__
#include <asm/types.h>
#include <linux/compiler.h>
#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));
......
......@@ -2,16 +2,17 @@
#define _X86_64_BYTEORDER_H
#include <asm/types.h>
#include <linux/compiler.h>
#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;
......
......@@ -15,6 +15,8 @@
*
*/
#include <linux/compiler.h>
/* 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 *addr)
__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 *addr)
}
#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;
......
......@@ -12,3 +12,4 @@
#define __deprecated __attribute__((deprecated))
#define __attribute_used__ __attribute__((__used__))
#define __attribute_pure__ __attribute__((pure))
#define __attribute_const__ __attribute__((__const__))
......@@ -20,4 +20,5 @@
*/
#if __GNUC_MINOR__ >= 96
# define __attribute_pure__ __attribute__((pure))
# define __attribute_const__ __attribute__((__const__))
#endif
......@@ -20,3 +20,4 @@
#endif
#define __attribute_pure__ __attribute__((pure))
#define __attribute_const__ __attribute__((__const__))
......@@ -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()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment