Skip to content
Snippets Groups Projects
Commit 6abd6673 authored by Nathan Hjelm's avatar Nathan Hjelm
Browse files

opal: remove 32-bit platforms from atomics


These platforms are losing support with each passing day and it
is time to let them go. They will continue to work with a C11
compiler but Open MPI will no longer maintain ASM for these
platforms.

Signed-off-by: default avatarNathan Hjelm <hjelmn@google.com>
parent 8f19f0f0
No related branches found
No related tags found
No related merge requests found
Showing
with 92 additions and 791 deletions
......@@ -201,9 +201,13 @@ base as of this writing (April 2020):
* Open MPI requires a C99-capable compiler to build.
* On platforms other than x86-64, ARM, and PPC, Open MPI requires a
compiler that either supports C11 atomics or the GCC `__atomic`
atomics (e.g., GCC >= v4.7.2).
* On platforms other than x86-64, AArch64 (64-bit ARM), and PPC64,
Open MPI requires a compiler that either supports C11 atomics or
the GCC `__atomic` atomics (e.g., GCC >= v4.7.2).
* 32-bit platforms are only supported with a recent compiler that
supports C11 atomics. This includes gcc 4.9.x+ (gcc 6.x or newer
recommened), icc 16, clang 3.1+, etc.
* Mixing compilers from different vendors when building Open MPI
(e.g., using the C/C++ compiler from one vendor and the Fortran
......
......@@ -880,53 +880,6 @@ AC_DEFUN([OPAL_CHECK_POWERPC_REG],[
[Whether r notation is used for ppc registers])
])dnl
dnl #################################################################
dnl
dnl OPAL_CHECK_POWERPC_64BIT
dnl
dnl On some powerpc chips (the PPC970 or G5), the OS usually runs in
dnl 32 bit mode, even though the hardware can do 64bit things. If
dnl the compiler will let us, emit code for 64bit test and set type
dnl operations (on a long long).
dnl
dnl #################################################################
AC_DEFUN([OPAL_CHECK_POWERPC_64BIT],[
if test "$ac_cv_sizeof_long" != "4" ; then
# this function should only be called in the 32 bit case
AC_MSG_ERROR([CHECK_POWERPC_64BIT called on 64 bit platform. Internal error.])
fi
AC_MSG_CHECKING([for 64-bit PowerPC assembly support])
case $host in
*-darwin*)
ppc64_result=0
if test "$opal_cv_asm_powerpc_r_reg" = "1" ; then
ldarx_asm=" ldarx r1,r1,r1";
else
ldarx_asm=" ldarx 1,1,1";
fi
OPAL_TRY_ASSEMBLE([$opal_cv_asm_text
$ldarx_asm],
[ppc64_result=1],
[ppc64_result=0])
;;
*)
ppc64_result=0
;;
esac
if test "$ppc64_result" = "1" ; then
AC_MSG_RESULT([yes])
ifelse([$1],,:,[$1])
else
AC_MSG_RESULT([no])
ifelse([$2],,:,[$2])
fi
unset ppc64_result ldarx_asm
])dnl
dnl #################################################################
dnl
dnl OPAL_CHECK_CMPXCHG16B
......@@ -1129,63 +1082,43 @@ AC_DEFUN([OPAL_CONFIG_ASM],[
# find our architecture for purposes of assembly stuff
opal_cv_asm_arch="UNSUPPORTED"
OPAL_GCC_INLINE_ASSIGN=""
if test "$opal_cv_have___atomic_64" ; then
OPAL_ASM_SUPPORT_64BIT=1
else
OPAL_ASM_SUPPORT_64BIT=0
fi
case "${host}" in
x86_64-*x32)
opal_cv_asm_arch="X86_64"
OPAL_ASM_SUPPORT_64BIT=1
OPAL_GCC_INLINE_ASSIGN='"xaddl %1,%0" : "=m"(ret), "+r"(negone) : "m"(ret)'
;;
i?86-*|x86_64*|amd64*)
x86_64-*x32|i?86-*|x86_64*|amd64*)
if test "$ac_cv_sizeof_long" = "4" ; then
if test $opal_cv_asm_builtin = BUILTIN_NO ; then
AC_MSG_ERROR([IA32 atomics are no longer supported. Use a C11 compiler])
fi
opal_cv_asm_arch="IA32"
else
opal_cv_asm_arch="X86_64"
OPAL_CHECK_CMPXCHG16B
fi
OPAL_ASM_SUPPORT_64BIT=1
OPAL_GCC_INLINE_ASSIGN='"xaddl %1,%0" : "=m"(ret), "+r"(negone) : "m"(ret)'
OPAL_CHECK_CMPXCHG16B
;;
aarch64*)
opal_cv_asm_arch="ARM64"
OPAL_ASM_SUPPORT_64BIT=1
OPAL_ASM_ARM_VERSION=8
OPAL_GCC_INLINE_ASSIGN='"mov %0, #0" : "=&r"(ret)'
;;
armv7*|arm-*-linux-gnueabihf)
opal_cv_asm_arch="ARM"
OPAL_ASM_SUPPORT_64BIT=1
OPAL_ASM_ARM_VERSION=7
OPAL_GCC_INLINE_ASSIGN='"mov %0, #0" : "=&r"(ret)'
;;
armv7*|arm-*-linux-gnueabihf|armv6*)
if test $opal_cv_asm_builtin = BUILTIN_NO ; then
AC_MSG_ERROR([32-bit ARM atomics are no longer supported. Use a C11 compiler])
fi
armv6*)
opal_cv_asm_arch="ARM"
OPAL_ASM_SUPPORT_64BIT=0
OPAL_ASM_ARM_VERSION=6
CCASFLAGS="$CCASFLAGS -march=armv7-a"
OPAL_GCC_INLINE_ASSIGN='"mov %0, #0" : "=&r"(ret)'
;;
powerpc-*|powerpc64-*|powerpcle-*|powerpc64le-*|rs6000-*|ppc-*)
OPAL_CHECK_POWERPC_REG
if test "$ac_cv_sizeof_long" = "4" ; then
if test $opal_cv_asm_builtin = BUILTIN_NO ; then
AC_MSG_ERROR([PowerPC 32-bit atomics are no longer supported. Use a C11 compiler])
fi
opal_cv_asm_arch="POWERPC32"
# Note that on some platforms (Apple G5), even if we are
# compiling in 32 bit mode (and therefore should assume
# sizeof(long) == 4), we can use the 64 bit test and set
# operations.
OPAL_CHECK_POWERPC_64BIT(OPAL_ASM_SUPPORT_64BIT=1)
elif test "$ac_cv_sizeof_long" = "8" ; then
OPAL_ASM_SUPPORT_64BIT=1
opal_cv_asm_arch="POWERPC64"
else
AC_MSG_ERROR([Could not determine PowerPC word size: $ac_cv_sizeof_long])
......@@ -1213,20 +1146,10 @@ AC_DEFUN([OPAL_CONFIG_ASM],[
;;
esac
if ! test -z "$OPAL_ASM_ARM_VERSION" ; then
AC_DEFINE_UNQUOTED([OPAL_ASM_ARM_VERSION], [$OPAL_ASM_ARM_VERSION],
[What ARM assembly version to use])
fi
if test "$opal_cv_asm_builtin" = "BUILTIN_GCC" ; then
AC_DEFINE([OPAL_C_GCC_INLINE_ASSEMBLY], [1],
[Whether C compiler supports GCC style inline assembly])
else
AC_DEFINE_UNQUOTED([OPAL_ASM_SUPPORT_64BIT],
[$OPAL_ASM_SUPPORT_64BIT],
[Whether we can do 64bit assembly operations or not. Should not be used outside of the assembly header files])
AC_SUBST([OPAL_ASM_SUPPORT_64BIT])
opal_cv_asm_inline_supported="no"
# now that we know our architecture, try to inline assemble
OPAL_CHECK_INLINE_C_GCC([$OPAL_GCC_INLINE_ASSIGN])
......@@ -1239,12 +1162,12 @@ AC_DEFUN([OPAL_CONFIG_ASM],[
asm_format="${asm_format}-${opal_cv_asm_lsym}"
asm_format="${asm_format}-${opal_cv_asm_type}-${opal_asm_size}"
asm_format="${asm_format}-${opal_asm_align_log_result}"
if test "$opal_cv_asm_arch" = "POWERPC32" || test "$opal_cv_asm_arch" = "POWERPC64" ; then
if test "$opal_cv_asm_arch" = "POWERPC64" ; then
asm_format="${asm_format}-${opal_cv_asm_powerpc_r_reg}"
else
asm_format="${asm_format}-1"
fi
asm_format="${asm_format}-${OPAL_ASM_SUPPORT_64BIT}"
asm_format="${asm_format}-1"
opal_cv_asm_format="${asm_format}-${opal_cv_asm_gnu_stack}"
# For the Makefile, need to escape the $ as $$. Don't display
# this version, but make sure the Makefile gives the right thing
......
......@@ -15,7 +15,7 @@
# reserved.
# Copyright (c) 2017 Research Organization for Information Science
# and Technology (RIST). All rights reserved.
# Copyright (c) 2020 Google, LLC. All rights reserved.
# Copyright (c) 2020-2021 Google, LLC. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
......@@ -34,8 +34,6 @@ headers += \
opal/sys/cma.h
include opal/sys/x86_64/Makefile.am
include opal/sys/arm/Makefile.am
include opal/sys/arm64/Makefile.am
include opal/sys/ia32/Makefile.am
include opal/sys/powerpc/Makefile.am
include opal/sys/gcc_builtin/Makefile.am
#
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
# University Research and Technology
# Corporation. All rights reserved.
# Copyright (c) 2004-2008 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights
# reserved.
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
# This makefile.am does not stand on its own - it is included from opal/include/Makefile.am
headers += \
opal/sys/arm/atomic.h \
opal/sys/arm/timer.h
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2005 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2010 IBM Corporation. All rights reserved.
* Copyright (c) 2010 ARM ltd. All rights reserved.
* Copyright (c) 2017-2018 Los Alamos National Security, LLC. All rights
* reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
/*
* ARMv5 and earlier lack robust atomic operations and therefore this file uses
* Linux kernel support where needed. The kernel also provides memory barriers
* and this file uses them for ARMv5 and earlier processors, which lack the
* memory barrier instruction. These kernel functions are available on kernel
* versions 2.6.15 and greater; using them will result in undefined behavior on
* older kernels.
* See Documentation/arm/kernel_user_helpers.txt in the kernel tree for details
*/
#ifndef OPAL_SYS_ARCH_ATOMIC_H
#define OPAL_SYS_ARCH_ATOMIC_H 1
#if (OPAL_ASM_ARM_VERSION >= 7)
# define OPAL_HAVE_ATOMIC_MEM_BARRIER 1
/* use the DMB instruction if available... */
# define MB() __asm__ __volatile__("dmb" : : : "memory")
# define RMB() __asm__ __volatile__("dmb" : : : "memory")
# define WMB() __asm__ __volatile__("dmb" : : : "memory")
#elif (OPAL_ASM_ARM_VERSION == 6)
# define OPAL_HAVE_ATOMIC_MEM_BARRIER 1
/* ...or the v6-specific equivalent... */
# define MB() __asm__ __volatile__("mcr p15, 0, r0, c7, c10, 5" : : : "memory")
# define RMB() MB()
# define WMB() MB()
#else
# define OPAL_HAVE_ATOMIC_MEM_BARRIER 1
/* ...otherwise use the Linux kernel-provided barrier */
# define MB() (*((void (*)(void))(0xffff0fa0)))()
# define RMB() MB()
# define WMB() MB()
#endif
/**********************************************************************
*
* Memory Barriers
*
*********************************************************************/
#if (OPAL_HAVE_ATOMIC_MEM_BARRIER == 1)
static inline void opal_atomic_mb(void)
{
MB();
}
static inline void opal_atomic_rmb(void)
{
RMB();
}
static inline void opal_atomic_wmb(void)
{
WMB();
}
static inline void opal_atomic_isync(void)
{
}
#endif
/**********************************************************************
*
* Atomic math operations
*
*********************************************************************/
#if (OPAL_GCC_INLINE_ASSEMBLY && (OPAL_ASM_ARM_VERSION >= 6))
# define OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_32 1
# define OPAL_HAVE_ATOMIC_MATH_32 1
static inline bool opal_atomic_compare_exchange_strong_32(opal_atomic_int32_t *addr,
int32_t *oldval, int32_t newval)
{
int32_t prev, tmp;
bool ret;
__asm__ __volatile__("1: ldrex %0, [%2] \n"
" cmp %0, %3 \n"
" bne 2f \n"
" strex %1, %4, [%2] \n"
" cmp %1, #0 \n"
" bne 1b \n"
"2: \n"
: "=&r"(prev), "=&r"(tmp)
: "r"(addr), "r"(*oldval), "r"(newval)
: "cc", "memory");
ret = (prev == *oldval);
*oldval = prev;
return ret;
}
/* these two functions aren't inlined in the non-gcc case because then
there would be two function calls (since neither cmpset_32 nor
atomic_?mb can be inlined). Instead, we "inline" them by hand in
the assembly, meaning there is one function call overhead instead
of two */
static inline bool opal_atomic_compare_exchange_strong_acq_32(opal_atomic_int32_t *addr,
int32_t *oldval, int32_t newval)
{
bool rc;
rc = opal_atomic_compare_exchange_strong_32(addr, oldval, newval);
opal_atomic_rmb();
return rc;
}
static inline bool opal_atomic_compare_exchange_strong_rel_32(opal_atomic_int32_t *addr,
int32_t *oldval, int32_t newval)
{
opal_atomic_wmb();
return opal_atomic_compare_exchange_strong_32(addr, oldval, newval);
}
# if (OPAL_ASM_SUPPORT_64BIT == 1)
# define OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_64 1
static inline bool opal_atomic_compare_exchange_strong_64(opal_atomic_int64_t *addr,
int64_t *oldval, int64_t newval)
{
int64_t prev;
int tmp;
bool ret;
__asm__ __volatile__("1: ldrexd %0, %H0, [%2] \n"
" cmp %0, %3 \n"
" it eq \n"
" cmpeq %H0, %H3 \n"
" bne 2f \n"
" strexd %1, %4, %H4, [%2] \n"
" cmp %1, #0 \n"
" bne 1b \n"
"2: \n"
: "=&r"(prev), "=&r"(tmp)
: "r"(addr), "r"(*oldval), "r"(newval)
: "cc", "memory");
ret = (prev == *oldval);
*oldval = prev;
return ret;
}
/* these two functions aren't inlined in the non-gcc case because then
there would be two function calls (since neither cmpset_64 nor
atomic_?mb can be inlined). Instead, we "inline" them by hand in
the assembly, meaning there is one function call overhead instead
of two */
static inline bool opal_atomic_compare_exchange_strong_acq_64(opal_atomic_int64_t *addr,
int64_t *oldval, int64_t newval)
{
bool rc;
rc = opal_atomic_compare_exchange_strong_64(addr, oldval, newval);
opal_atomic_rmb();
return rc;
}
static inline bool opal_atomic_compare_exchange_strong_rel_64(opal_atomic_int64_t *addr,
int64_t *oldval, int64_t newval)
{
opal_atomic_wmb();
return opal_atomic_compare_exchange_strong_64(addr, oldval, newval);
}
# endif
# define OPAL_HAVE_ATOMIC_ADD_32 1
static inline int32_t opal_atomic_fetch_add_32(opal_atomic_int32_t *v, int inc)
{
int32_t t, old;
int tmp;
__asm__ __volatile__("1: ldrex %1, [%3] \n"
" add %0, %1, %4 \n"
" strex %2, %0, [%3] \n"
" cmp %2, #0 \n"
" bne 1b \n"
: "=&r"(t), "=&r"(old), "=&r"(tmp)
: "r"(v), "r"(inc)
: "cc", "memory");
return old;
}
# define OPAL_HAVE_ATOMIC_SUB_32 1
static inline int32_t opal_atomic_fetch_sub_32(opal_atomic_int32_t *v, int dec)
{
int32_t t, old;
int tmp;
__asm__ __volatile__("1: ldrex %1, [%3] \n"
" sub %0, %1, %4 \n"
" strex %2, %0, [%3] \n"
" cmp %2, #0 \n"
" bne 1b \n"
: "=&r"(t), "=&r"(old), "=&r"(tmp)
: "r"(v), "r"(dec)
: "cc", "memory");
return t;
}
#endif
#endif /* ! OPAL_SYS_ARCH_ATOMIC_H */
/*
* Copyright (c) 2008 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#ifndef OPAL_SYS_ARCH_TIMER_H
#define OPAL_SYS_ARCH_TIMER_H 1
#include <sys/times.h>
typedef uint64_t opal_timer_t;
static inline opal_timer_t opal_sys_timer_get_cycles(void)
{
opal_timer_t ret;
struct tms accurate_clock;
times(&accurate_clock);
ret = accurate_clock.tms_utime + accurate_clock.tms_stime;
return ret;
}
#define OPAL_HAVE_SYS_TIMER_GET_CYCLES 1
#endif /* ! OPAL_SYS_ARCH_TIMER_H */
#!/bin/sh
#
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
# University Research and Technology
# Corporation. All rights reserved.
# Copyright (c) 2004-2005 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights
# reserved.
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
CFILE=/tmp/opal_atomic_$$.c
trap "/bin/rm -f $CFILE; exit 0" 0 1 2 15
echo Updating atomic.s from atomic.h using gcc
cat > $CFILE<<EOF
#include <stdlib.h>
#include <inttypes.h>
#define static
#define inline
#define OPAL_GCC_INLINE_ASSEMBLY 1
#include "../architecture.h"
#include "atomic.h"
EOF
gcc -O1 -I. -S $CFILE -o atomic.s
......@@ -6,6 +6,7 @@
* Copyright (c) 2016 Broadcom Limited. All rights reserved.
* Copyright (c) 2016 Los Alamos National Security, LLC. All rights
* reserved.
* Copyright (c) 2021 Google, LLC. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
......@@ -16,14 +17,22 @@
#ifndef OPAL_SYS_ARCH_TIMER_H
#define OPAL_SYS_ARCH_TIMER_H 1
#if OPAL_ASSEMBLY_ARCH == OPAL_ARM64
typedef uint64_t opal_timer_t;
#else
typedef uint32_t opal_timer_t;
#endif
static inline opal_timer_t opal_sys_timer_get_cycles(void)
{
opal_timer_t ret;
__asm__ __volatile__("isb" ::: "memory");
#if OPAL_ASSEMBLY_ARCH == OPAL_ARM64
__asm__ __volatile__("mrs %0, CNTVCT_EL0" : "=r"(ret));
#else
__asm__ __volatile__("mrs %0, CNTVCT" : "=r"(ret));
#endif
return ret;
}
......@@ -31,7 +40,11 @@ static inline opal_timer_t opal_sys_timer_get_cycles(void)
static inline opal_timer_t opal_sys_timer_get_freq(void)
{
opal_timer_t freq;
#if OPAL_ASSEMBLY_ARCH == OPAL_ARM64
__asm__ __volatile__("mrs %0, CNTFRQ_EL0" : "=r"(freq));
#else
__asm__ __volatile__("mrs %0, CNTFRQ" : "=r"(freq));
#endif
return (opal_timer_t)(freq);
}
......
#
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
# University Research and Technology
# Corporation. All rights reserved.
# Copyright (c) 2004-2005 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights
# reserved.
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
# This makefile.am does not stand on its own - it is included from opal/include/Makefile.am
headers += \
opal/sys/ia32/atomic.h \
opal/sys/ia32/timer.h
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/*
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2010 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2007-2010 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* Copyright (c) 2015-2018 Los Alamos National Security, LLC. All rights
* reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#ifndef OPAL_SYS_ARCH_ATOMIC_H
#define OPAL_SYS_ARCH_ATOMIC_H 1
/*
* On ia32, we use cmpxchg.
*/
#define SMPLOCK "lock; "
#define MB() __asm__ __volatile__("" : : : "memory")
/**********************************************************************
*
* Define constants for IA32
*
*********************************************************************/
#define OPAL_HAVE_ATOMIC_MEM_BARRIER 1
#define OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_32 1
#define OPAL_HAVE_ATOMIC_MATH_32 1
#define OPAL_HAVE_ATOMIC_ADD_32 1
#define OPAL_HAVE_ATOMIC_SUB_32 1
/**********************************************************************
*
* Memory Barriers
*
*********************************************************************/
#if OPAL_GCC_INLINE_ASSEMBLY
static inline void opal_atomic_mb(void)
{
MB();
}
static inline void opal_atomic_rmb(void)
{
MB();
}
static inline void opal_atomic_wmb(void)
{
MB();
}
static inline void opal_atomic_isync(void)
{
}
#endif /* OPAL_GCC_INLINE_ASSEMBLY */
/**********************************************************************
*
* Atomic math operations
*
*********************************************************************/
#if OPAL_GCC_INLINE_ASSEMBLY
static inline bool opal_atomic_compare_exchange_strong_32(opal_atomic_int32_t *addr,
int32_t *oldval, int32_t newval)
{
unsigned char ret;
__asm__ __volatile__(SMPLOCK "cmpxchgl %3,%2 \n\t"
"sete %0 \n\t"
: "=qm"(ret), "+a"(*oldval), "+m"(*addr)
: "q"(newval)
: "memory", "cc");
return (bool) ret;
}
#endif /* OPAL_GCC_INLINE_ASSEMBLY */
#define opal_atomic_compare_exchange_strong_acq_32 opal_atomic_compare_exchange_strong_32
#define opal_atomic_compare_exchange_strong_rel_32 opal_atomic_compare_exchange_strong_32
#if OPAL_GCC_INLINE_ASSEMBLY
# define OPAL_HAVE_ATOMIC_SWAP_32 1
static inline int32_t opal_atomic_swap_32(opal_atomic_int32_t *addr, int32_t newval)
{
int32_t oldval;
__asm__ __volatile__("xchg %1, %0"
: "=r"(oldval), "=m"(*addr)
: "0"(newval), "m"(*addr)
: "memory");
return oldval;
}
#endif /* OPAL_GCC_INLINE_ASSEMBLY */
#if OPAL_GCC_INLINE_ASSEMBLY
/**
* atomic_add - add integer to atomic variable
* @i: integer value to add
* @v: pointer of type int
*
* Atomically adds @i to @v.
*/
static inline int32_t opal_atomic_fetch_add_32(opal_atomic_int32_t *v, int i)
{
int ret = i;
__asm__ __volatile__(SMPLOCK "xaddl %1,%0" : "+m"(*v), "+r"(ret) : : "memory", "cc");
return ret;
}
/**
* atomic_sub - subtract the atomic variable
* @i: integer value to subtract
* @v: pointer of type int
*
* Atomically subtracts @i from @v.
*/
static inline int32_t opal_atomic_fetch_sub_32(opal_atomic_int32_t *v, int i)
{
int ret = -i;
__asm__ __volatile__(SMPLOCK "xaddl %1,%0" : "+m"(*v), "+r"(ret) : : "memory", "cc");
return ret;
}
#endif /* OPAL_GCC_INLINE_ASSEMBLY */
#endif /* ! OPAL_SYS_ARCH_ATOMIC_H */
/*
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2014 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#ifndef OPAL_SYS_ARCH_TIMER_H
#define OPAL_SYS_ARCH_TIMER_H 1
typedef uint64_t opal_timer_t;
/* Using RDTSC(P) results in non-monotonic timers across cores */
#undef OPAL_TIMER_MONOTONIC
#define OPAL_TIMER_MONOTONIC 0
#if OPAL_GCC_INLINE_ASSEMBLY
static inline opal_timer_t opal_sys_timer_get_cycles(void)
{
opal_timer_t ret;
int tmp;
__asm__ __volatile__("xchgl %%ebx, %1\n"
"cpuid\n"
"xchgl %%ebx, %1\n"
"rdtsc\n"
: "=A"(ret), "=r"(tmp)::"ecx");
return ret;
}
# define OPAL_HAVE_SYS_TIMER_GET_CYCLES 1
#else
# define OPAL_HAVE_SYS_TIMER_GET_CYCLES 0
#endif /* OPAL_GCC_INLINE_ASSEMBLY */
#endif /* ! OPAL_SYS_ARCH_TIMER_H */
#!/bin/sh
#
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
# University Research and Technology
# Corporation. All rights reserved.
# Copyright (c) 2004-2005 The University of Tennessee and The University
# of Tennessee Research Foundation. All rights
# reserved.
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved.
# Copyright (c) 2004-2005 The Regents of the University of California.
# All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
CFILE=/tmp/opal_asm_$$.c
trap "/bin/rm -f $CFILE; exit 0" 0 1 2 15
echo Updating asm.s from atomic.h and timer.h using gcc
cat > $CFILE<<EOF
#include <stdlib.h>
#include <inttypes.h>
#define static
#define inline
#define OPAL_GCC_INLINE_ASSEMBLY 1
#include "atomic.h"
#include "timer.h"
EOF
gcc -O3 -I. -S $CFILE -o asm.s
......@@ -13,6 +13,7 @@
* Copyright (c) 2010-2021 IBM Corporation. All rights reserved.
* Copyright (c) 2015-2018 Los Alamos National Security, LLC. All rights
* reserved.
* Copyright (c) 2021 Google, LLC. All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
......@@ -34,7 +35,7 @@
/**********************************************************************
*
* Define constants for PowerPC 32
* Define constants for PowerPC 64
*
*********************************************************************/
#define OPAL_HAVE_ATOMIC_MEM_BARRIER 1
......@@ -49,8 +50,6 @@
#define OPAL_HAVE_ATOMIC_OR_32 1
#define OPAL_HAVE_ATOMIC_XOR_32 1
#define OPAL_HAVE_ATOMIC_SUB_32 1
#if (OPAL_ASSEMBLY_ARCH == OPAL_POWERPC64) || OPAL_ASM_SUPPORT_64BIT
#define OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_64 1
#define OPAL_HAVE_ATOMIC_SWAP_64 1
#define OPAL_HAVE_ATOMIC_LLSC_64 1
......@@ -60,7 +59,6 @@
#define OPAL_HAVE_ATOMIC_OR_64 1
#define OPAL_HAVE_ATOMIC_XOR_64 1
#define OPAL_HAVE_ATOMIC_SUB_64 1
#endif
/**********************************************************************
*
......@@ -203,13 +201,10 @@ static inline int32_t opal_atomic_swap_32(opal_atomic_int32_t *addr, int32_t new
#endif /* OPAL_GCC_INLINE_ASSEMBLY */
#if (OPAL_ASSEMBLY_ARCH == OPAL_POWERPC64)
#if OPAL_GCC_INLINE_ASSEMBLY
# define OPAL_ATOMIC_POWERPC_DEFINE_ATOMIC_64(type, instr) \
static inline int64_t opal_atomic_fetch_##type##_64(opal_atomic_int64_t *v, \
int64_t val) \
static inline int64_t opal_atomic_fetch_##type##_64(opal_atomic_int64_t *v, int64_t val) \
{ \
int64_t t, old; \
\
......@@ -293,54 +288,6 @@ static inline int64_t opal_atomic_swap_64(opal_atomic_int64_t *addr, int64_t new
# endif /* OPAL_GCC_INLINE_ASSEMBLY */
#elif (OPAL_ASSEMBLY_ARCH == OPAL_POWERPC32) && OPAL_ASM_SUPPORT_64BIT
# ifndef ll_low /* GLIBC provides these somewhere, so protect */
# define ll_low(x) *(((unsigned int *) &(x)) + 0)
# define ll_high(x) *(((unsigned int *) &(x)) + 1)
# endif
# if OPAL_GCC_INLINE_ASSEMBLY
static inline bool opal_atomic_compare_exchange_strong_64(opal_atomic_int64_t *addr,
int64_t *oldval, int64_t newval)
{
int64_t prev;
int ret;
/*
* We force oldval and newval into memory because PPC doesn't
* appear to have a way to do a move register with offset. Since
* this is 32-bit code, a 64 bit integer will be loaded into two
* registers (assuming no inlining, addr will be in r3, oldval
* will be in r4 and r5, and newval will be r6 and r7. We need
* to load the whole thing into one register. So we have the
* compiler push the values into memory and load the double word
* into registers. We use r4,r5 so that the main block of code
* is very similar to the pure 64 bit version.
*/
__asm__ __volatile__("ld r4,%3 \n\t"
"ld r5,%4 \n\t"
"1: ldarx %1, 0, %2 \n\t"
" cmpd 0, %1, r4 \n\t"
" bne- 2f \n\t"
" stdcx. r5, 0, %2 \n\t"
" bne- 1b \n\t"
"2: \n\t"
"xor r5,r4,%1 \n\t"
"subfic r9,r5,0 \n\t"
"adde %0,r9,r5 \n\t"
: "=&r"(ret), "+r"(prev)
: "r" OPAL_ASM_ADDR(addr), "m"(*oldval), "m"(newval)
: "r4", "r5", "r9", "cc", "memory");
*oldval = prev;
return (bool) ret;
}
# endif /* OPAL_GCC_INLINE_ASSEMBLY */
#endif /* OPAL_ASM_SUPPORT_64BIT */
#if OPAL_GCC_INLINE_ASSEMBLY
/* these two functions aren't inlined in the non-gcc case because then
......
......@@ -72,17 +72,11 @@ BEGIN_C_DECLS
#if defined(DOXYGEN)
/* don't include system-level gorp when generating doxygen files */
#elif OPAL_ASSEMBLY_ARCH == OPAL_X86_64
#elif OPAL_ASSEMBLY_ARCH == OPAL_X86_64 || OPAL_ASSEMBLY_ARCH == OPAL_IA32
# include "opal/sys/x86_64/timer.h"
#elif OPAL_ASSEMBLY_ARCH == OPAL_ARM
# include "opal/sys/arm/timer.h"
#elif OPAL_ASSEMBLY_ARCH == OPAL_ARM64
#elif OPAL_ASSEMBLY_ARCH == OPAL_ARM64 || OPAL_ASSEMBLY_ARCH == OPAL_ARM
# include "opal/sys/arm64/timer.h"
#elif OPAL_ASSEMBLY_ARCH == OPAL_IA32
# include "opal/sys/ia32/timer.h"
#elif OPAL_ASSEMBLY_ARCH == OPAL_POWERPC32
# include "opal/sys/powerpc/timer.h"
#elif OPAL_ASSEMBLY_ARCH == OPAL_POWERPC64
#elif OPAL_ASSEMBLY_ARCH == OPAL_POWERPC64 || OPAL_ASSEMBLY_ARCH == OPAL_POWERPC32
# include "opal/sys/powerpc/timer.h"
#endif
......
......@@ -30,6 +30,8 @@ typedef uint64_t opal_timer_t;
#if OPAL_GCC_INLINE_ASSEMBLY
# if OPAL_ASSEMBLY_ARCH == OPAL_X86_64
/* TODO: add AMD mfence version and dispatch at init */
static inline opal_timer_t opal_sys_timer_get_cycles(void)
{
......@@ -58,8 +60,26 @@ static inline bool opal_sys_timer_is_monotonic(void)
return !!(cpuid2 & (1 << 8));
}
# define OPAL_HAVE_SYS_TIMER_GET_CYCLES 1
# define OPAL_HAVE_SYS_TIMER_IS_MONOTONIC 1
# else
static inline opal_timer_t opal_sys_timer_get_cycles(void)
{
opal_timer_t ret;
int tmp;
__asm__ __volatile__("xchgl %%ebx, %1\n"
"cpuid\n"
"xchgl %%ebx, %1\n"
"rdtsc\n"
: "=A"(ret), "=r"(tmp)::"ecx");
return ret;
}
# endif
# define OPAL_HAVE_SYS_TIMER_GET_CYCLES 1
#else
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment