RE: [Patch] asm workarounds in generic header files

From: Siddha, Suresh B
Date: Tue Sep 09 2003 - 23:51:46 EST


> How about something like this?
> (the patch has Works-for-Me status...)
>
> --david

Attached the patch with minor changes to David's patch.

include/linux/compiler.h defines the generic
definitions which are overwritten by per-compiler definitions.

include/linux/compiler-gcc.h contains the common definitions
for all gcc versions.

include/linux/compiler-gcc[2,3,+].h contains gcc version
specific definitions.

And intel.diff patch adds Intel compiler specific definitions.

thanks,
suresh

diff -Nru linux/include/linux/compiler-gcc+.h linux-/include/linux/compiler-gcc+.h
--- linux/include/linux/compiler-gcc+.h Wed Dec 31 16:00:00 1969
+++ linux-/include/linux/compiler-gcc+.h Tue Sep 9 21:26:03 2003
@@ -0,0 +1,14 @@
+/* Never include this file directly. Include <linux/compiler.h> instead. */
+
+/*
+ * These definitions are for Ueber-GCC: always newer than the latest
+ * version and hence sporting everything plus a kitchen-sink.
+ */
+#include <linux/compiler-gcc.h>
+
+#define inline __inline__ __attribute__((always_inline))
+#define __inline__ __inline__ __attribute__((always_inline))
+#define __inline __inline__ __attribute__((always_inline))
+#define __deprecated __attribute__((deprecated))
+#define __attribute_used__ __attribute__((__used__))
+#define __attribute_pure__ __attribute__((pure))
diff -Nru linux/include/linux/compiler-gcc.h linux-/include/linux/compiler-gcc.h
--- linux/include/linux/compiler-gcc.h Wed Dec 31 16:00:00 1969
+++ linux-/include/linux/compiler-gcc.h Tue Sep 9 21:26:03 2003
@@ -0,0 +1,17 @@
+/* Never include this file directly. Include <linux/compiler.h> instead. */
+
+/*
+ * Common definitions for all gcc versions go here.
+ */
+
+
+/* Optimization barrier */
+/* The "volatile" is due to gcc bugs */
+#define barrier() __asm__ __volatile__("": : :"memory")
+
+/* This macro obfuscates arithmetic on a variable address so that gcc
+ shouldn't recognize the original var, and make assumptions about it */
+#define RELOC_HIDE(ptr, off) \
+ ({ unsigned long __ptr; \
+ __asm__ ("" : "=g"(__ptr) : "0"(ptr)); \
+ (typeof(ptr)) (__ptr + (off)); })
diff -Nru linux/include/linux/compiler-gcc2.h linux-/include/linux/compiler-gcc2.h
--- linux/include/linux/compiler-gcc2.h Wed Dec 31 16:00:00 1969
+++ linux-/include/linux/compiler-gcc2.h Tue Sep 9 21:26:03 2003
@@ -0,0 +1,23 @@
+/* Never include this file directly. Include <linux/compiler.h> instead. */
+
+/* These definitions are for GCC v2.x. */
+
+/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented
+ a mechanism by which the user can annotate likely branch directions and
+ expect the blocks to be reordered appropriately. Define __builtin_expect
+ to nothing for earlier compilers. */
+#include <linux/compiler-gcc.h>
+
+#if __GNUC_MINOR__ < 96
+# define __builtin_expect(x, expected_value) (x)
+#endif
+
+#define __attribute_used__ __attribute__((__unused__))
+
+/*
+ * The attribute `pure' is not implemented in GCC versions earlier
+ * than 2.96.
+ */
+#if __GNUC_MINOR__ >= 96
+# define __attribute_pure__ __attribute__((pure))
+#endif
diff -Nru linux/include/linux/compiler-gcc3.h linux-/include/linux/compiler-gcc3.h
--- linux/include/linux/compiler-gcc3.h Wed Dec 31 16:00:00 1969
+++ linux-/include/linux/compiler-gcc3.h Tue Sep 9 21:26:03 2003
@@ -0,0 +1,22 @@
+/* Never include this file directly. Include <linux/compiler.h> instead. */
+
+/* These definitions are for GCC v3.x. */
+#include <linux/compiler-gcc.h>
+
+#if __GNUC_MINOR__ >= 1
+# define inline __inline__ __attribute__((always_inline))
+# define __inline__ __inline__ __attribute__((always_inline))
+# define __inline __inline__ __attribute__((always_inline))
+#endif
+
+#if __GNUC_MINOR__ > 0
+# define __deprecated __attribute__((deprecated))
+#endif
+
+#if __GNUC_MINOR__ >= 3
+# define __attribute_used__ __attribute__((__used__))
+#else
+# define __attribute_used__ __attribute__((__unused__))
+#endif
+
+#define __attribute_pure__ __attribute__((pure))
diff -Nru linux/include/linux/compiler.h linux-/include/linux/compiler.h
--- linux/include/linux/compiler.h Mon Sep 8 11:51:00 2003
+++ linux-/include/linux/compiler.h Tue Sep 9 21:32:44 2003
@@ -2,28 +2,28 @@
#define __LINUX_COMPILER_H

#ifdef __CHECKER__
- #define __user __attribute__((noderef, address_space(1)))
- #define __kernel /* default address space */
+# define __user __attribute__((noderef, address_space(1)))
+# define __kernel /* default address space */
#else
- #define __user
- #define __kernel
+# define __user
+# define __kernel
#endif

-#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
-#define inline __inline__ __attribute__((always_inline))
-#define __inline__ __inline__ __attribute__((always_inline))
-#define __inline __inline__ __attribute__((always_inline))
-#endif
-
-/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented
- a mechanism by which the user can annotate likely branch directions and
- expect the blocks to be reordered appropriately. Define __builtin_expect
- to nothing for earlier compilers. */
-
-#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
-#define __builtin_expect(x, expected_value) (x)
+#if __GNUC__ > 3
+# include <linux/compiler-gcc+.h> /* catch-all for GCC 4, 5, etc. */
+#elif __GNUC__ == 3
+# include <linux/compiler-gcc3.h>
+#elif __GNUC__ == 2
+# include <linux/compiler-gcc2.h>
+#else
+# error Sorry, your compiler is too old/not recognized.
#endif

+/*
+ * Below are the generic compiler related macros required for kernel
+ * build. Actual compiler/compiler version specific implementations
+ * come from the above header files
+ */
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)

@@ -33,10 +33,8 @@
* Usage is:
* int __deprecated foo(void)
*/
-#if ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 ) || __GNUC__ > 3
-#define __deprecated __attribute__((deprecated))
-#else
-#define __deprecated
+#ifndef __deprecated
+# define __deprecated /* unimplemented */
#endif

/*
@@ -50,10 +48,8 @@
* In prior versions of gcc, such functions and data would be emitted, but
* would be warned about except with attribute((unused)).
*/
-#if __GNUC__ == 3 && __GNUC_MINOR__ >= 3 || __GNUC__ > 3
-#define __attribute_used__ __attribute__((__used__))
-#else
-#define __attribute_used__ __attribute__((__unused__))
+#ifndef __attribute_used__
+# define __attribute_used__ /* unimplemented */
#endif

/*
@@ -65,19 +61,21 @@
* elimination and loop optimization just as an arithmetic operator
* would be.
* [...]
- * The attribute `pure' is not implemented in GCC versions earlier
- * than 2.96.
*/
-#if (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || __GNUC__ > 2
-#define __attribute_pure__ __attribute__((pure))
-#else
-#define __attribute_pure__ /* unimplemented */
+#ifndef __attribute_pure__
+# define __attribute_pure__ /* unimplemented */
+#endif
+
+/* Optimization barrier */
+#ifndef barrier
+# define barrier() __memory_barrier();
#endif

-/* This macro obfuscates arithmetic on a variable address so that gcc
- shouldn't recognize the original var, and make assumptions about it */
-#define RELOC_HIDE(ptr, off) \
+#ifndef RELOC_HIDE
+# define RELOC_HIDE(ptr, off) \
({ unsigned long __ptr; \
- __asm__ ("" : "=g"(__ptr) : "0"(ptr)); \
+ __ptr = (unsigned long) (ptr); \
(typeof(ptr)) (__ptr + (off)); })
+#endif
+
#endif /* __LINUX_COMPILER_H */
diff -Nru linux/include/linux/kernel.h linux-/include/linux/kernel.h
--- linux/include/linux/kernel.h Mon Sep 8 11:51:01 2003
+++ linux-/include/linux/kernel.h Tue Sep 9 21:26:03 2003
@@ -15,10 +15,6 @@
#include <asm/byteorder.h>
#include <asm/bug.h>

-/* Optimization barrier */
-/* The "volatile" is due to gcc bugs */
-#define barrier() __asm__ __volatile__("": : :"memory")
-
#define INT_MAX ((int)(~0U>>1))
#define INT_MIN (-INT_MAX - 1)
#define UINT_MAX (~0U)
diff -Nru linux/include/linux/compiler-intel.h linux-/include/linux/compiler-intel.h
--- linux/include/linux/compiler-intel.h Wed Dec 31 16:00:00 1969
+++ linux-/include/linux/compiler-intel.h Tue Sep 9 21:34:19 2003
@@ -0,0 +1,21 @@
+/* Never include this file directly. Include <linux/compiler.h> instead. */
+
+#ifdef __ECC
+
+/* Some compiler specific definitions are overwritten here
+ * for Intel ECC compiler
+ */
+
+#include <asm/intrinsics.h>
+
+#undef barrier
+#undef RELOC_HIDE
+
+#define barrier() __memory_barrier()
+
+#define RELOC_HIDE(ptr, off) \
+ ({ unsigned long __ptr; \
+ __ptr = (unsigned long) (ptr); \
+ (typeof(ptr)) (__ptr + (off)); })
+
+#endif
diff -Nru linux/include/linux/compiler.h linux-/include/linux/compiler.h
--- linux/include/linux/compiler.h Tue Sep 9 21:34:11 2003
+++ linux-/include/linux/compiler.h Tue Sep 9 21:35:08 2003
@@ -19,6 +19,13 @@
# error Sorry, your compiler is too old/not recognized.
#endif

+/* Intel compiler defines __GNUC__. So we will overwrite implementations
+ * coming from above header files here
+ */
+#ifdef __INTEL_COMPILER
+# include <linux/compiler-intel.h>
+#endif
+
/*
* Below are the generic compiler related macros required for kernel
* build. Actual compiler/compiler version specific implementations




Attachment: compiler.h.diff
Description: compiler.h.diff

Attachment: intel.diff
Description: intel.diff