X-Git-Url: https://git.liburcu.org/?p=urcu.git;a=blobdiff_plain;f=include%2Furcu%2Fuatomic%2Fx86.h;h=f4e1887477684f779edd2d865ad3e7edb86eee37;hp=ec71e5151fa07b4115f5d4b62fce6d7a3e4c30cd;hb=13bf2f5734e6cab159fe7f9b8fcca175aa5f0e81;hpb=0b1e236d1711f4f9076f73a093ece05aca00eca4 diff --git a/include/urcu/uatomic/x86.h b/include/urcu/uatomic/x86.h index ec71e51..f4e1887 100644 --- a/include/urcu/uatomic/x86.h +++ b/include/urcu/uatomic/x86.h @@ -36,10 +36,21 @@ extern "C" { * Derived from AO_compare_and_swap() and AO_test_and_set_full(). */ -struct __uatomic_dummy { - unsigned long v[10]; -}; -#define __hp(x) ((struct __uatomic_dummy *)(x)) +/* + * The __hp() macro casts the void pointer @x to a pointer to a structure + * containing an array of char of the specified size. This allows passing the + * @addr arguments of the following inline functions as "m" and "+m" operands + * to the assembly. The @size parameter should be a constant to support + * compilers such as clang which do not support VLA. Create typedefs because + * C++ does not allow types be defined in casts. + */ + +typedef struct { char v[1]; } __hp_1; +typedef struct { char v[2]; } __hp_2; +typedef struct { char v[4]; } __hp_4; +typedef struct { char v[8]; } __hp_8; + +#define __hp(size, x) ((__hp_##size *)(x)) #define _uatomic_set(addr, v) ((void) CMM_STORE_SHARED(*(addr), (v))) @@ -56,7 +67,7 @@ unsigned long __uatomic_cmpxchg(void *addr, unsigned long old, __asm__ __volatile__( "lock; cmpxchgb %2, %1" - : "+a"(result), "+m"(*__hp(addr)) + : "+a"(result), "+m"(*__hp(1, addr)) : "q"((unsigned char)_new) : "memory"); return result; @@ -67,7 +78,7 @@ unsigned long __uatomic_cmpxchg(void *addr, unsigned long old, __asm__ __volatile__( "lock; cmpxchgw %2, %1" - : "+a"(result), "+m"(*__hp(addr)) + : "+a"(result), "+m"(*__hp(2, addr)) : "r"((unsigned short)_new) : "memory"); return result; @@ -78,7 +89,7 @@ unsigned long __uatomic_cmpxchg(void *addr, unsigned long old, __asm__ __volatile__( "lock; cmpxchgl %2, %1" - : "+a"(result), "+m"(*__hp(addr)) + : "+a"(result), "+m"(*__hp(4, addr)) : "r"((unsigned int)_new) : "memory"); return result; @@ -90,7 +101,7 @@ unsigned long __uatomic_cmpxchg(void *addr, unsigned long old, __asm__ __volatile__( "lock; cmpxchgq %2, %1" - : "+a"(result), "+m"(*__hp(addr)) + : "+a"(result), "+m"(*__hp(8, addr)) : "r"((unsigned long)_new) : "memory"); return result; @@ -123,7 +134,7 @@ unsigned long __uatomic_exchange(void *addr, unsigned long val, int len) unsigned char result; __asm__ __volatile__( "xchgb %0, %1" - : "=q"(result), "+m"(*__hp(addr)) + : "=q"(result), "+m"(*__hp(1, addr)) : "0" ((unsigned char)val) : "memory"); return result; @@ -133,7 +144,7 @@ unsigned long __uatomic_exchange(void *addr, unsigned long val, int len) unsigned short result; __asm__ __volatile__( "xchgw %0, %1" - : "=r"(result), "+m"(*__hp(addr)) + : "=r"(result), "+m"(*__hp(2, addr)) : "0" ((unsigned short)val) : "memory"); return result; @@ -143,7 +154,7 @@ unsigned long __uatomic_exchange(void *addr, unsigned long val, int len) unsigned int result; __asm__ __volatile__( "xchgl %0, %1" - : "=r"(result), "+m"(*__hp(addr)) + : "=r"(result), "+m"(*__hp(4, addr)) : "0" ((unsigned int)val) : "memory"); return result; @@ -154,7 +165,7 @@ unsigned long __uatomic_exchange(void *addr, unsigned long val, int len) unsigned long result; __asm__ __volatile__( "xchgq %0, %1" - : "=r"(result), "+m"(*__hp(addr)) + : "=r"(result), "+m"(*__hp(8, addr)) : "0" ((unsigned long)val) : "memory"); return result; @@ -187,7 +198,7 @@ unsigned long __uatomic_add_return(void *addr, unsigned long val, __asm__ __volatile__( "lock; xaddb %1, %0" - : "+m"(*__hp(addr)), "+q" (result) + : "+m"(*__hp(1, addr)), "+q" (result) : : "memory"); return result + (unsigned char)val; @@ -198,7 +209,7 @@ unsigned long __uatomic_add_return(void *addr, unsigned long val, __asm__ __volatile__( "lock; xaddw %1, %0" - : "+m"(*__hp(addr)), "+r" (result) + : "+m"(*__hp(2, addr)), "+r" (result) : : "memory"); return result + (unsigned short)val; @@ -209,7 +220,7 @@ unsigned long __uatomic_add_return(void *addr, unsigned long val, __asm__ __volatile__( "lock; xaddl %1, %0" - : "+m"(*__hp(addr)), "+r" (result) + : "+m"(*__hp(4, addr)), "+r" (result) : : "memory"); return result + (unsigned int)val; @@ -221,7 +232,7 @@ unsigned long __uatomic_add_return(void *addr, unsigned long val, __asm__ __volatile__( "lock; xaddq %1, %0" - : "+m"(*__hp(addr)), "+r" (result) + : "+m"(*__hp(8, addr)), "+r" (result) : : "memory"); return result + (unsigned long)val; @@ -251,7 +262,7 @@ void __uatomic_and(void *addr, unsigned long val, int len) { __asm__ __volatile__( "lock; andb %1, %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(1, addr)) : "iq" ((unsigned char)val) : "memory"); return; @@ -260,7 +271,7 @@ void __uatomic_and(void *addr, unsigned long val, int len) { __asm__ __volatile__( "lock; andw %1, %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(2, addr)) : "ir" ((unsigned short)val) : "memory"); return; @@ -269,7 +280,7 @@ void __uatomic_and(void *addr, unsigned long val, int len) { __asm__ __volatile__( "lock; andl %1, %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(4, addr)) : "ir" ((unsigned int)val) : "memory"); return; @@ -279,7 +290,7 @@ void __uatomic_and(void *addr, unsigned long val, int len) { __asm__ __volatile__( "lock; andq %1, %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(8, addr)) : "er" ((unsigned long)val) : "memory"); return; @@ -307,7 +318,7 @@ void __uatomic_or(void *addr, unsigned long val, int len) { __asm__ __volatile__( "lock; orb %1, %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(1, addr)) : "iq" ((unsigned char)val) : "memory"); return; @@ -316,7 +327,7 @@ void __uatomic_or(void *addr, unsigned long val, int len) { __asm__ __volatile__( "lock; orw %1, %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(2, addr)) : "ir" ((unsigned short)val) : "memory"); return; @@ -325,7 +336,7 @@ void __uatomic_or(void *addr, unsigned long val, int len) { __asm__ __volatile__( "lock; orl %1, %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(4, addr)) : "ir" ((unsigned int)val) : "memory"); return; @@ -335,7 +346,7 @@ void __uatomic_or(void *addr, unsigned long val, int len) { __asm__ __volatile__( "lock; orq %1, %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(8, addr)) : "er" ((unsigned long)val) : "memory"); return; @@ -363,7 +374,7 @@ void __uatomic_add(void *addr, unsigned long val, int len) { __asm__ __volatile__( "lock; addb %1, %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(1, addr)) : "iq" ((unsigned char)val) : "memory"); return; @@ -372,7 +383,7 @@ void __uatomic_add(void *addr, unsigned long val, int len) { __asm__ __volatile__( "lock; addw %1, %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(2, addr)) : "ir" ((unsigned short)val) : "memory"); return; @@ -381,7 +392,7 @@ void __uatomic_add(void *addr, unsigned long val, int len) { __asm__ __volatile__( "lock; addl %1, %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(4, addr)) : "ir" ((unsigned int)val) : "memory"); return; @@ -391,7 +402,7 @@ void __uatomic_add(void *addr, unsigned long val, int len) { __asm__ __volatile__( "lock; addq %1, %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(8, addr)) : "er" ((unsigned long)val) : "memory"); return; @@ -420,7 +431,7 @@ void __uatomic_inc(void *addr, int len) { __asm__ __volatile__( "lock; incb %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(1, addr)) : : "memory"); return; @@ -429,7 +440,7 @@ void __uatomic_inc(void *addr, int len) { __asm__ __volatile__( "lock; incw %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(2, addr)) : : "memory"); return; @@ -438,7 +449,7 @@ void __uatomic_inc(void *addr, int len) { __asm__ __volatile__( "lock; incl %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(4, addr)) : : "memory"); return; @@ -448,7 +459,7 @@ void __uatomic_inc(void *addr, int len) { __asm__ __volatile__( "lock; incq %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(8, addr)) : : "memory"); return; @@ -473,7 +484,7 @@ void __uatomic_dec(void *addr, int len) { __asm__ __volatile__( "lock; decb %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(1, addr)) : : "memory"); return; @@ -482,7 +493,7 @@ void __uatomic_dec(void *addr, int len) { __asm__ __volatile__( "lock; decw %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(2, addr)) : : "memory"); return; @@ -491,7 +502,7 @@ void __uatomic_dec(void *addr, int len) { __asm__ __volatile__( "lock; decl %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(4, addr)) : : "memory"); return; @@ -501,7 +512,7 @@ void __uatomic_dec(void *addr, int len) { __asm__ __volatile__( "lock; decq %0" - : "=m"(*__hp(addr)) + : "=m"(*__hp(8, addr)) : : "memory"); return;