summaryrefslogtreecommitdiffstats
path: root/sys/alpha
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2003-02-23 06:34:21 +0000
committermarcel <marcel@FreeBSD.org>2003-02-23 06:34:21 +0000
commit7e9d753cf392748f8a8371d64524b2c31dccb361 (patch)
treead25d1c6e1e32c6413dbb8bb99d082f99c5eb159 /sys/alpha
parent5a23486f365f934af22d55ddbfde31de0a8e0a69 (diff)
downloadFreeBSD-src-7e9d753cf392748f8a8371d64524b2c31dccb361.zip
FreeBSD-src-7e9d753cf392748f8a8371d64524b2c31dccb361.tar.gz
Workaround for compiling LINT. Large kernels (like LINT) can have
branch targets that are too far apart for the BRADDR relocation. This is caused by the branch prediction optimizationi in the atomic inlines here, because they jump across sections. The workaround is to suppress jumping to a different section when compiling LINT. To generate correct code in that case, the section directives are replaced by a branch and a label to deal with the fall-through case. Reasonably good C compilers will optimize this away anyway, so the end result isn't really that bad.
Diffstat (limited to 'sys/alpha')
-rw-r--r--sys/alpha/include/atomic.h52
1 files changed, 32 insertions, 20 deletions
diff --git a/sys/alpha/include/atomic.h b/sys/alpha/include/atomic.h
index ba92cd6..1d1354a 100644
--- a/sys/alpha/include/atomic.h
+++ b/sys/alpha/include/atomic.h
@@ -32,6 +32,18 @@
#include <machine/alpha_cpu.h>
/*
+ * Quick and dirty workaround for compiling LINT. The kernel is too
+ * large to jump between sections without linker stubs/trampolines.
+ */
+#ifdef COMPILING_LINT
+#define __COLD_SECTION "br 3f\n"
+#define __HOT_SECTION "3:\n"
+#else
+#define __COLD_SECTION ".section .text3,\"ax\"\n"
+#define __HOT_SECTION ".previous\n"
+#endif
+
+/*
* Various simple arithmetic on memory which is atomic in the presence
* of interrupts and SMP safe.
*/
@@ -56,9 +68,9 @@ static __inline void atomic_set_32(volatile u_int32_t *p, u_int32_t v)
"bis %0, %3, %0\n\t" /* calculate new value */
"stl_c %0, %1\n\t" /* attempt to store */
"beq %0, 2f\n\t" /* spin if failed */
- ".section .text3,\"ax\"\n" /* improve branch prediction */
+ __COLD_SECTION /* improve branch prediction */
"2:\tbr 1b\n" /* try again */
- ".previous\n"
+ __HOT_SECTION
: "=&r" (temp), "=m" (*p)
: "m" (*p), "r" (v)
: "memory");
@@ -75,9 +87,9 @@ static __inline void atomic_clear_32(volatile u_int32_t *p, u_int32_t v)
"bic %0, %2, %0\n\t" /* calculate new value */
"stl_c %0, %1\n\t" /* attempt to store */
"beq %0, 2f\n\t" /* spin if failed */
- ".section .text3,\"ax\"\n" /* improve branch prediction */
+ __COLD_SECTION /* improve branch prediction */
"2:\tbr 1b\n" /* try again */
- ".previous\n"
+ __HOT_SECTION
: "=&r" (temp), "+m" (*p)
: "r" (v)
: "memory");
@@ -94,9 +106,9 @@ static __inline void atomic_add_32(volatile u_int32_t *p, u_int32_t v)
"addl %0, %2, %0\n\t" /* calculate new value */
"stl_c %0, %1\n\t" /* attempt to store */
"beq %0, 2f\n\t" /* spin if failed */
- ".section .text3,\"ax\"\n" /* improve branch prediction */
+ __COLD_SECTION /* improve branch prediction */
"2:\tbr 1b\n" /* try again */
- ".previous\n"
+ __HOT_SECTION
: "=&r" (temp), "+m" (*p)
: "r" (v)
: "memory");
@@ -113,9 +125,9 @@ static __inline void atomic_subtract_32(volatile u_int32_t *p, u_int32_t v)
"subl %0, %2, %0\n\t" /* calculate new value */
"stl_c %0, %1\n\t" /* attempt to store */
"beq %0, 2f\n\t" /* spin if failed */
- ".section .text3,\"ax\"\n" /* improve branch prediction */
+ __COLD_SECTION /* improve branch prediction */
"2:\tbr 1b\n" /* try again */
- ".previous\n"
+ __HOT_SECTION
: "=&r" (temp), "+m" (*p)
: "r" (v)
: "memory");
@@ -154,9 +166,9 @@ static __inline void atomic_set_64(volatile u_int64_t *p, u_int64_t v)
"bis %0, %2, %0\n\t" /* calculate new value */
"stq_c %0, %1\n\t" /* attempt to store */
"beq %0, 2f\n\t" /* spin if failed */
- ".section .text3,\"ax\"\n" /* improve branch prediction */
+ __COLD_SECTION /* improve branch prediction */
"2:\tbr 1b\n" /* try again */
- ".previous\n"
+ __HOT_SECTION
: "=&r" (temp), "+m" (*p)
: "r" (v)
: "memory");
@@ -173,9 +185,9 @@ static __inline void atomic_clear_64(volatile u_int64_t *p, u_int64_t v)
"bic %0, %2, %0\n\t" /* calculate new value */
"stq_c %0, %1\n\t" /* attempt to store */
"beq %0, 2f\n\t" /* spin if failed */
- ".section .text3,\"ax\"\n" /* improve branch prediction */
+ __COLD_SECTION /* improve branch prediction */
"2:\tbr 1b\n" /* try again */
- ".previous\n"
+ __HOT_SECTION
: "=&r" (temp), "+m" (*p)
: "r" (v)
: "memory");
@@ -192,9 +204,9 @@ static __inline void atomic_add_64(volatile u_int64_t *p, u_int64_t v)
"addq %0, %2, %0\n\t" /* calculate new value */
"stq_c %0, %1\n\t" /* attempt to store */
"beq %0, 2f\n\t" /* spin if failed */
- ".section .text3,\"ax\"\n" /* improve branch prediction */
+ __COLD_SECTION /* improve branch prediction */
"2:\tbr 1b\n" /* try again */
- ".previous\n"
+ __HOT_SECTION
: "=&r" (temp), "+m" (*p)
: "r" (v)
: "memory");
@@ -211,9 +223,9 @@ static __inline void atomic_subtract_64(volatile u_int64_t *p, u_int64_t v)
"subq %0, %2, %0\n\t" /* calculate new value */
"stq_c %0, %1\n\t" /* attempt to store */
"beq %0, 2f\n\t" /* spin if failed */
- ".section .text3,\"ax\"\n" /* improve branch prediction */
+ __COLD_SECTION /* improve branch prediction */
"2:\tbr 1b\n" /* try again */
- ".previous\n"
+ __HOT_SECTION
: "=&r" (temp), "+m" (*p)
: "r" (v)
: "memory");
@@ -375,9 +387,9 @@ atomic_cmpset_32(volatile u_int32_t* p, u_int32_t cmpval, u_int32_t newval)
"stl_c %0, %1\n\t" /* attempt to store */
"beq %0, 3f\n\t" /* if it failed, spin */
"2:\n" /* done */
- ".section .text3,\"ax\"\n" /* improve branch prediction */
+ __COLD_SECTION /* improve branch prediction */
"3:\tbr 1b\n" /* try again */
- ".previous\n"
+ __HOT_SECTION
: "=&r" (ret), "+m" (*p)
: "r" ((long)(int)cmpval), "r" (newval)
: "memory");
@@ -405,9 +417,9 @@ atomic_cmpset_64(volatile u_int64_t* p, u_int64_t cmpval, u_int64_t newval)
"stq_c %0, %1\n\t" /* attempt to store */
"beq %0, 3f\n\t" /* if it failed, spin */
"2:\n" /* done */
- ".section .text3,\"ax\"\n" /* improve branch prediction */
+ __COLD_SECTION /* improve branch prediction */
"3:\tbr 1b\n" /* try again */
- ".previous\n"
+ __HOT_SECTION
: "=&r" (ret), "+m" (*p)
: "r" (cmpval), "r" (newval)
: "memory");
OpenPOWER on IntegriCloud