On 30/05/17 15:52, Alexander Monakov wrote: > On Tue, 30 May 2017, Jonathan Wakely wrote: >>> I just built GCC from trunk, and this gives me: >>> >>> mustang-b0:~ $ /scratch/gcc/trunk/install/bin/gcc zzz.c >>> /tmp/ccmc3Y73.o: In function `main': >>> zzz.c:(.text+0x20): undefined reference to `__sync_val_compare_and_swap_16' >>> collect2: error: ld returned 1 exit status >>> >>> I can't figure out where __sync_val_compare_and_swap_16 should be >>> defined. It's not in libatomic or libc or libgcc. > > libgcc implements __sync..._N calls in terms of __sync_val_compare_and_swap_N > built-in when it's available, but there's no way libgcc could conjure CAS "out > of thin air". But why is it not then in libgcc? It's not hard to write it in a way that will run on all AArch64 systems. int __sync_val_compare_and_swap_16(__int128 *ptr, __int128 oldval, __int128 newval) { typedef union { struct parts { long lo; long hi; } parts; __int128 all; } k; k old_bits, new_bits; long temp_lo, temp_hi; old_bits.all = oldval; new_bits.all = newval; int result = 0; asm("1:\n" "ldaxp %[temp_lo], %[temp_hi], [%[ptr]]\n" "cmp %[temp_lo], %[old_lo]\n" "b.ne 0f\n" "cmp %[temp_hi], %[old_hi]\n" "b.ne 0f\n" "stlxp %w[result], %[new_lo], %[new_hi], [%[ptr]]\n" "cbnz %w[result], 1b\n" "mov %[result], #1\n" "0:\n" : [result]"+r"(result), [temp_lo]"=&r"(temp_lo), [temp_hi]"=&r"(temp_hi) : [ptr]"r"(ptr), [old_lo]"r"(old_bits.parts.lo), [old_hi]"r"(old_bits.parts.hi), [new_lo]"r"(new_bits.parts.lo), [new_hi]"r"(new_bits.parts.hi) : "memory"); return result; } -- Andrew Haley Java Platform Lead Engineer Red Hat UK Ltd. <https://www.redhat.com> EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671