Commit 0fb1c286 authored by Mikael Ronstrom's avatar Mikael Ronstrom

Fixed complex gcc assembler issues with 64-bit operations on 32-bit platforms...

Fixed complex gcc assembler issues with 64-bit operations on 32-bit platforms using PIC codes, commented x86-gcc.h a lot more
parent 6b0bb050
......@@ -59,39 +59,68 @@
asm volatile (LOCK_prefix "; cmpxchg %3, %0; setz %2;" \
: "+m" (*a), "+a" (*cmp), "=q" (ret): "r" (set))
#define make_atomic_cas_bodyptr make_atomic_cas_body32
#ifndef __x86_64__
#ifdef __x86_64__
#define make_atomic_add_body64 make_atomic_add_body32
#define make_atomic_cas_body64 make_atomic_cas_body32
#define make_atomic_fas_body(S) \
asm volatile ("xchg %0, %1;" : "+r" (v) , "+m" (*a))
/*
Actually 32-bit reads/writes are always atomic on x86
But we add LOCK_prefix here anyway to force memory barriers
*/
#define make_atomic_load_body(S) \
ret=0; \
asm volatile (LOCK_prefix "; cmpxchg %2, %0" \
: "+m" (*a), "+a" (ret): "r" (ret))
#define make_atomic_store_body(S) \
asm volatile ("; xchg %0, %1;" : "+m" (*a), "+r" (v))
#else
/*
Use default implementations of 64-bit operations since we solved
the 64-bit problem on 32-bit platforms for CAS, no need to solve it
once more for ADD, LOAD, STORE and FAS as well.
Since we already added add32 support, we need to define add64
here, but we haven't defined fas, load and store at all, so
we can fallback on default implementations.
*/
#define make_atomic_add_body64 \
int64 tmp=*a; \
while (!my_atomic_cas64(a, &tmp, tmp+v)); \
v=tmp;
/*
On some platforms (e.g. Mac OS X and Solaris) the ebx register
is held as a pointer to the global offset table. Thus we're not
allowed to use the b-register on those platforms when compiling
PIC code, to avoid this we push ebx and pop ebx and add a movl
instruction to avoid having ebx in the interface of the assembler
instruction.
cmpxchg8b works on both 32-bit platforms and 64-bit platforms but
the code here is only used on 32-bit platforms, on 64-bit
platforms the much simpler make_atomic_cas_body32 will work
fine.
*/
#define make_atomic_cas_body64 \
int32 ebx=(set & 0xFFFFFFFF), ecx=(set >> 32); \
asm volatile (LOCK_prefix "; cmpxchg8b %0; setz %2;" \
asm volatile ("push %%ebx; movl %3, %%ebx;" \
LOCK_prefix "; cmpxchg8b %0; setz %2; pop %%ebx"\
: "+m" (*a), "+A" (*cmp), "=q" (ret) \
:"b" (ebx), "c" (ecx))
:"m" (ebx), "c" (ecx))
#endif
#define make_atomic_fas_body(S) \
asm volatile ("xchg %0, %1;" : "+r" (v) , "+m" (*a))
/*
The implementation of make_atomic_cas_body32 is adaptable to
the OS word size, so on 64-bit platforms it will automatically
adapt to 64-bits and so it will work also on 64-bit platforms
*/
#define make_atomic_cas_bodyptr make_atomic_cas_body32
#ifdef MY_ATOMIC_MODE_DUMMY
#define make_atomic_load_body(S) ret=*a
#define make_atomic_store_body(S) *a=v
#else
/*
Actually 32-bit reads/writes are always atomic on x86
But we add LOCK_prefix here anyway to force memory barriers
*/
#define make_atomic_load_body(S) \
ret=0; \
asm volatile (LOCK_prefix "; cmpxchg %2, %0" \
: "+m" (*a), "+a" (ret): "r" (ret))
#define make_atomic_store_body(S) \
asm volatile ("; xchg %0, %1;" : "+m" (*a), "+r" (v))
#endif
#endif /* ATOMIC_X86_GCC_INCLUDED */
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