GCC in-line assembly and the removal of -mcx16
Andrew Haley
aph@redhat.com
Tue May 30 16:04:00 GMT 2017
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
More information about the Gcc-help
mailing list