# define GC_TEST_AND_SET_DEFINED
# endif
# if defined(POWERPC)
-# if CPP_WORDSZ == 64
- inline static int GC_test_and_set(volatile unsigned int *addr) {
- unsigned long oldval;
- unsigned long temp = 1; /* locked value */
-
- __asm__ __volatile__(
- "1:\tldarx %0,0,%3\n" /* load and reserve */
- "\tcmpdi %0, 0\n" /* if load is */
- "\tbne 2f\n" /* non-zero, return already set */
- "\tstdcx. %2,0,%1\n" /* else store conditional */
- "\tbne- 1b\n" /* retry if lost reservation */
- "\tsync\n" /* import barrier */
- "2:\t\n" /* oldval is zero if we set */
- : "=&r"(oldval), "=p"(addr)
- : "r"(temp), "1"(addr)
- : "cr0","memory");
- return (int)oldval;
- }
-# else
inline static int GC_test_and_set(volatile unsigned int *addr) {
int oldval;
int temp = 1; /* locked value */
__asm__ __volatile__(
- "1:\tlwarx %0,0,%3\n" /* load and reserve */
+ "1:\tlwarx %0,0,%1\n" /* load and reserve */
"\tcmpwi %0, 0\n" /* if load is */
"\tbne 2f\n" /* non-zero, return already set */
"\tstwcx. %2,0,%1\n" /* else store conditional */
"\tbne- 1b\n" /* retry if lost reservation */
"\tsync\n" /* import barrier */
"2:\t\n" /* oldval is zero if we set */
- : "=&r"(oldval), "=p"(addr)
- : "r"(temp), "1"(addr)
+ : "=&r"(oldval)
+ : "r"(addr), "r"(temp)
: "cr0","memory");
return oldval;
}
-# endif
# define GC_TEST_AND_SET_DEFINED
inline static void GC_clear(volatile unsigned int *addr) {
__asm__ __volatile__("lwsync" : : : "memory");
}
# endif /* I386 */
+# if defined(X86_64)
+# if !defined(GENERIC_COMPARE_AND_SWAP)
+ /* Returns TRUE if the comparison succeeded. */
+ inline static GC_bool GC_compare_and_exchange(volatile GC_word *addr,
+ GC_word old,
+ GC_word new_val)
+ {
+ char result;
+ __asm__ __volatile__("lock; cmpxchgq %2, %0; setz %1"
+ : "+m"(*(addr)), "=r"(result)
+ : "r" (new_val), "a"(old) : "memory");
+ return (GC_bool) result;
+ }
+# endif /* !GENERIC_COMPARE_AND_SWAP */
+ inline static void GC_memory_barrier()
+ {
+ /* We believe the processor ensures at least processor */
+ /* consistent ordering. Thus a compiler barrier */
+ /* should suffice. */
+ __asm__ __volatile__("" : : : "memory");
+ }
+# endif /* X86_64 */
+
# if defined(POWERPC)
# if !defined(GENERIC_COMPARE_AND_SWAP)
# if CPP_WORDSZ == 64