diff options
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/unix/sysv/linux/sh/bits/atomic.h (renamed from sysdeps/sh/bits/atomic.h) | 109 |
1 files changed, 63 insertions, 46 deletions
diff --git a/sysdeps/sh/bits/atomic.h b/sysdeps/unix/sysv/linux/sh/bits/atomic.h index d3725fc66b..e692595960 100644 --- a/sysdeps/sh/bits/atomic.h +++ b/sysdeps/unix/sysv/linux/sh/bits/atomic.h @@ -1,4 +1,5 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. +/* Atomic operations used inside libc. Linux/SH version. + Copyright (C) 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -44,9 +45,28 @@ typedef uintptr_t uatomicptr_t; typedef intmax_t atomic_max_t; typedef uintmax_t uatomic_max_t; +/* SH kernel has implemented a gUSA ("g" User Space Atomicity) support + for the user space atomicity. The atomicity macros use this scheme. + + Reference: + Niibe Yutaka, "gUSA: Simple and Efficient User Space Atomicity + Emulation with Little Kernel Modification", Linux Conference 2002, + Japan. http://lc.linux.or.jp/lc2002/papers/niibe0919h.pdf (in + Japanese). + + B.N. Bershad, D. Redell, and J. Ellis, "Fast Mutual Exclusion for + Uniprocessors", Proceedings of the Fifth Architectural Support for + Programming Languages and Operating Systems (ASPLOS), pp. 223-233, + October 1992. http://www.cs.washington.edu/homes/bershad/Papers/Rcs.ps + + SuperH ABI: + r15: -(size of atomic instruction sequence) < 0 + r0: end point + r1: saved stack pointer +*/ #define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ - ({ __typeof (*mem) __result; \ + ({ __typeof (*(mem)) __result; \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -63,7 +83,7 @@ typedef uintmax_t uatomic_max_t; __result; }) #define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \ - ({ __typeof (*mem) __result; \ + ({ __typeof (*(mem)) __result; \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -80,7 +100,7 @@ typedef uintmax_t uatomic_max_t; __result; }) #define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ - ({ __typeof (*mem) __result; \ + ({ __typeof (*(mem)) __result; \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -105,9 +125,8 @@ typedef uintmax_t uatomic_max_t; (abort (), 0) #define atomic_exchange_and_add(mem, value) \ - ({ __typeof (*mem) __result; \ - __typeof (value) __value; \ - if (sizeof (*mem) == 1) \ + ({ __typeof (*(mem)) __result, __tmp, __value = (value); \ + if (sizeof (*(mem)) == 1) \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -117,9 +136,9 @@ typedef uintmax_t uatomic_max_t; add %0,%1\n\ mov.b %1,@%2\n\ 1: mov r1,r15"\ - : "=&r" (__result), "=&r" (__value) : "r" (mem), "1" (value) \ + : "=&r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \ : "r0", "r1", "memory"); \ - else if (sizeof (*mem) == 2) \ + else if (sizeof (*(mem)) == 2) \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -129,9 +148,9 @@ typedef uintmax_t uatomic_max_t; add %0,%1\n\ mov.w %1,@%2\n\ 1: mov r1,r15"\ - : "=&r" (__result), "=&r" (__value) : "r" (mem), "1" (value) \ + : "=&r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \ : "r0", "r1", "memory"); \ - else if (sizeof (*mem) == 4) \ + else if (sizeof (*(mem)) == 4) \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -141,23 +160,22 @@ typedef uintmax_t uatomic_max_t; add %0,%1\n\ mov.l %1,@%2\n\ 1: mov r1,r15"\ - : "=&r" (__result), "=&r" (__value) : "r" (mem), "1" (value) \ + : "=&r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \ : "r0", "r1", "memory"); \ else \ { \ - __typeof (value) addval = (value); \ __typeof (mem) memp = (mem); \ do \ __result = *memp; \ while (__arch_compare_and_exchange_val_64_acq \ - (memp, __result + addval, __result) == __result); \ - (void) addval; \ + (memp, __result + __value, __result) == __result); \ + (void) __value; \ } \ __result; }) #define atomic_add(mem, value) \ - (void) ({ __typeof (value) __value; \ - if (sizeof (*mem) == 1) \ + (void) ({ __typeof (*(mem)) __tmp, __value = (value); \ + if (sizeof (*(mem)) == 1) \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -167,9 +185,9 @@ typedef uintmax_t uatomic_max_t; add r2,%0\n\ mov.b %0,@%1\n\ 1: mov r1,r15"\ - : "=&r" (__value) : "r" (mem), "0" (value) \ + : "=&r" (__tmp) : "r" (mem), "0" (__value) \ : "r0", "r1", "r2", "memory"); \ - else if (sizeof (*mem) == 2) \ + else if (sizeof (*(mem)) == 2) \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -179,9 +197,9 @@ typedef uintmax_t uatomic_max_t; add r2,%0\n\ mov.w %0,@%1\n\ 1: mov r1,r15"\ - : "=&r" (__value) : "r" (mem), "0" (value) \ + : "=&r" (__tmp) : "r" (mem), "0" (__value) \ : "r0", "r1", "r2", "memory"); \ - else if (sizeof (*mem) == 4) \ + else if (sizeof (*(mem)) == 4) \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -191,25 +209,24 @@ typedef uintmax_t uatomic_max_t; add r2,%0\n\ mov.l %0,@%1\n\ 1: mov r1,r15"\ - : "=&r" (__value) : "r" (mem), "0" (value) \ + : "=&r" (__tmp) : "r" (mem), "0" (__value) \ : "r0", "r1", "r2", "memory"); \ else \ { \ - __typeof (value) addval = (value); \ - __typeof (*mem) oldval; \ + __typeof (*(mem)) oldval; \ __typeof (mem) memp = (mem); \ do \ oldval = *memp; \ while (__arch_compare_and_exchange_val_64_acq \ - (memp, oldval + addval, oldval) == oldval); \ - (void) addval; \ + (memp, oldval + __value, oldval) == oldval); \ + (void) __value; \ } \ }) #define atomic_add_negative(mem, value) \ ({ unsigned char __result; \ - __typeof (value) __value; \ - if (sizeof (*mem) == 1) \ + __typeof (*(mem)) __tmp, __value = (value); \ + if (sizeof (*(mem)) == 1) \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -221,9 +238,9 @@ typedef uintmax_t uatomic_max_t; 1: mov r1,r15\n\ shal %1\n\ movt %0"\ - : "=r" (__result), "=&r" (__value) : "r" (mem), "1" (value) \ + : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \ : "r0", "r1", "r2", "t", "memory"); \ - else if (sizeof (*mem) == 2) \ + else if (sizeof (*(mem)) == 2) \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -235,9 +252,9 @@ typedef uintmax_t uatomic_max_t; 1: mov r1,r15\n\ shal %1\n\ movt %0"\ - : "=r" (__result), "=&r" (__value) : "r" (mem), "1" (value) \ + : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \ : "r0", "r1", "r2", "t", "memory"); \ - else if (sizeof (*mem) == 4) \ + else if (sizeof (*(mem)) == 4) \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -249,7 +266,7 @@ typedef uintmax_t uatomic_max_t; 1: mov r1,r15\n\ shal %1\n\ movt %0"\ - : "=r" (__result), "=&r" (__value) : "r" (mem), "1" (value) \ + : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \ : "r0", "r1", "r2", "t", "memory"); \ else \ abort (); \ @@ -257,8 +274,8 @@ typedef uintmax_t uatomic_max_t; #define atomic_add_zero(mem, value) \ ({ unsigned char __result; \ - __typeof (value) __value; \ - if (sizeof (*mem) == 1) \ + __typeof (*(mem)) __tmp, __value = (value); \ + if (sizeof (*(mem)) == 1) \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -270,9 +287,9 @@ typedef uintmax_t uatomic_max_t; 1: mov r1,r15\n\ tst %1,%1\n\ movt %0"\ - : "=r" (__result), "=&r" (__value) : "r" (mem), "1" (value) \ + : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \ : "r0", "r1", "r2", "t", "memory"); \ - else if (sizeof (*mem) == 2) \ + else if (sizeof (*(mem)) == 2) \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -284,9 +301,9 @@ typedef uintmax_t uatomic_max_t; 1: mov r1,r15\n\ tst %1,%1\n\ movt %0"\ - : "=r" (__result), "=&r" (__value) : "r" (mem), "1" (value) \ + : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \ : "r0", "r1", "r2", "t", "memory"); \ - else if (sizeof (*mem) == 4) \ + else if (sizeof (*(mem)) == 4) \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -298,7 +315,7 @@ typedef uintmax_t uatomic_max_t; 1: mov r1,r15\n\ tst %1,%1\n\ movt %0"\ - : "=r" (__result), "=&r" (__value) : "r" (mem), "1" (value) \ + : "=r" (__result), "=&r" (__tmp) : "r" (mem), "1" (__value) \ : "r0", "r1", "r2", "t", "memory"); \ else \ abort (); \ @@ -309,7 +326,7 @@ typedef uintmax_t uatomic_max_t; #define atomic_bit_set(mem, bit) \ (void) ({ unsigned int __mask = 1 << (bit); \ - if (sizeof (*mem) == 1) \ + if (sizeof (*(mem)) == 1) \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -321,7 +338,7 @@ typedef uintmax_t uatomic_max_t; 1: mov r1,r15"\ : : "r" (mem), "r" (__mask) \ : "r0", "r1", "r2", "memory"); \ - else if (sizeof (*mem) == 2) \ + else if (sizeof (*(mem)) == 2) \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -333,7 +350,7 @@ typedef uintmax_t uatomic_max_t; 1: mov r1,r15"\ : : "r" (mem), "r" (__mask) \ : "r0", "r1", "r2", "memory"); \ - else if (sizeof (*mem) == 4) \ + else if (sizeof (*(mem)) == 4) \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -352,7 +369,7 @@ typedef uintmax_t uatomic_max_t; #define atomic_bit_test_set(mem, bit) \ ({ unsigned int __mask = 1 << (bit); \ unsigned int __result = __mask; \ - if (sizeof (*mem) == 1) \ + if (sizeof (*(mem)) == 1) \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -367,7 +384,7 @@ typedef uintmax_t uatomic_max_t; : "=&r" (__result), "=&r" (__mask) \ : "r" (mem), "0" (__result), "1" (__mask) \ : "r0", "r1", "r2", "memory"); \ - else if (sizeof (*mem) == 2) \ + else if (sizeof (*(mem)) == 2) \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ @@ -382,7 +399,7 @@ typedef uintmax_t uatomic_max_t; : "=&r" (__result), "=&r" (__mask) \ : "r" (mem), "0" (__result), "1" (__mask) \ : "r0", "r1", "r2", "memory"); \ - else if (sizeof (*mem) == 4) \ + else if (sizeof (*(mem)) == 4) \ __asm __volatile ("\ .align 2\n\ mova 1f,r0\n\ |