On Fri, Jul 01, 2016 at 10:04:36 -0700, Richard Henderson wrote:
> Force the use of cmpxchg16b on x86_64.
>
> Wikipedia suggests that only very old AMD64 (circa 2004) did not have
> this instruction. Further, it's required by Windows 8 so no new cpus
> will ever omit it.
>
> If we truely care about these, then we could check this at startup time
> and then avoid executing paths that use it.
>
> Signed-off-by: Richard Henderson <[email protected]>
> ---
> configure | 29 ++++++++++++-
> cputlb.c | 6 +++
> include/qemu/int128.h | 6 +++
> softmmu_template.h | 110
> +++++++++++++++++++++++++++++++++++++-------------
> tcg/tcg.h | 22 ++++++++++
> 5 files changed, 144 insertions(+), 29 deletions(-)
>
> diff --git a/configure b/configure
> index 59ea124..586abd6 100755
> --- a/configure
> +++ b/configure
> @@ -1201,7 +1201,10 @@ case "$cpu" in
> cc_i386='$(CC) -m32'
> ;;
> x86_64)
> - CPU_CFLAGS="-m64"
> + # ??? Only extremely old AMD cpus do not have cmpxchg16b.
> + # If we truly care, we should simply detect this case at
> + # runtime and generate the fallback to serial emulation.
> + CPU_CFLAGS="-m64 -mcx16"
> LDFLAGS="-m64 $LDFLAGS"
> cc_i386='$(CC) -m32'
> ;;
> @@ -4434,6 +4437,26 @@ if compile_prog "" "" ; then
> int128=yes
> fi
>
> +#########################################
> +# See if 128-bit atomic operations are supported.
> +
> +atomic128=no
> +if test "$int128" = "yes"; then
> + cat > $TMPC << EOF
> +int main(void)
> +{
> + unsigned __int128 x = 0, y = 0;
> + y = __atomic_load_16(&x, 0);
> + __atomic_store_16(&x, y, 0);
> + __atomic_compare_exchange_16(&x, &y, x, 0, 0, 0);
> + return 0;
> +}
> +EOF
> + if compile_prog "" "" ; then
> + atomic128=yes
> + fi
> +fi
Would it be correct to just trust that gcc is doing the right thing?
As in this delta over the patch:
--- a/configure
+++ b/configure
@@ -1201,10 +1201,7 @@ case "$cpu" in
cc_i386='$(CC) -m32'
;;
x86_64)
- # ??? Only extremely old AMD cpus do not have cmpxchg16b.
- # If we truly care, we should simply detect this case at
- # runtime and generate the fallback to serial emulation.
- CPU_CFLAGS="-m64 -mcx16"
+ CPU_CFLAGS="-m64"
LDFLAGS="-m64 $LDFLAGS"
cc_i386='$(CC) -m32'
;;
@@ -4454,6 +4451,10 @@ int main(void)
EOF
if compile_prog "" "" ; then
atomic128=yes
+ elif compile_prog "-mcx16" "" ; then
+ QEMU_CFLAGS="$QEMU_CFLAGS -mcx16"
+ EXTRA_CFLAGS="$EXTRA_CFLAGS -mcx16"
+ atomic128=yes
fi
fi
I might be missing other CFLAGS to be set, but the idea is that
if a program with __atomic[..]_16 links, then we should be OK.
This way we would handle correctly even those old AMD cpus,
and would also handle non-x86 architectures that implement
cmpxchg16.
Emilio