1
1

* Update build system to support non-GCC inline assembly, including detection

of assembler format
* Fix minor bugs in AMD64, PPC, and IA32 assembly for atomic operations
* Clean up the #defines to look for when examining level of atomic operation
  support

This commit was SVN r4183.
This commit is contained in:
Brian Barrett 2005-01-27 01:39:55 +00:00
parent b240395d9a
commit 9c1a277804
39 changed files with 2875 additions and 840 deletions

View File

@ -892,7 +892,7 @@ INCLUDE_FILE_PATTERNS =
# or name=definition (no spaces). If the definition and the = are
# omitted =1 is assumed.
PREDEFINED =
PREDEFINED = DOXYGEN
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.

View File

@ -36,6 +36,9 @@ sinclude(config/f90_check_type.m4)
sinclude(config/f90_get_alignment.m4)
sinclude(config/f90_get_sizeof.m4)
sinclude(config/ompi_try_assemble.m4)
sinclude(config/ompi_config_asm.m4)
sinclude(config/ompi_case_sensitive_fs_setup.m4)
sinclude(config/ompi_check_optflags.m4)
sinclude(config/ompi_config_subdir.m4)

763
config/ompi_config_asm.m4 Normal file
View File

@ -0,0 +1,763 @@
dnl
dnl Copyright (c) 2004-2005 The Trustees of Indiana University.
dnl All rights reserved.
dnl Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
dnl All rights reserved.
dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
dnl University of Stuttgart. All rights reserved.
dnl $COPYRIGHT$
dnl
dnl Additional copyrights may follow
dnl
dnl $HEADER$
dnl
dnl #################################################################
dnl
dnl OMPI_CHECK_ASM_TEXT
dnl
dnl Determine how to set current mode as text.
dnl
dnl #################################################################
AC_DEFUN([OMPI_CHECK_ASM_TEXT],[
AC_MSG_CHECKING([directive for setting text section])
ompi_cv_asm_text=""
case $host in
*-aix*)
ompi_cv_asm_text=[".csect .text[PR]"]
;;
*)
ompi_cv_asm_text=".text"
;;
esac
AC_MSG_RESULT([$ompi_cv_asm_text])
AC_DEFINE_UNQUOTED([OMPI_ASM_TEXT], ["$ompi_cv_asm_text"],
[Assembly directive for setting text section])
OMPI_ASM_TEXT="$ompi_cv_asm_text"
AC_SUBST(OMPI_ASM_TEXT)
])dnl
dnl #################################################################
dnl
dnl OMPI_CHECK_ASM_GLOBAL
dnl
dnl Sets OMPI_ASM_GLOBAL to the value to prefix global values
dnl
dnl I'm sure if I don't have a test for this, there will be some
dnl dumb platform that uses something else
dnl
dnl #################################################################
AC_DEFUN([OMPI_CHECK_ASM_GLOBAL],[
AC_MSG_CHECKING([directive for exporting symbols])
ompi_cv_asm_global=""
case $host in
*)
ompi_cv_asm_global=".globl"
;;
esac
AC_MSG_RESULT([$ompi_cv_asm_global])
AC_DEFINE_UNQUOTED([OMPI_ASM_GLOBAL], ["$ompi_cv_asm_global"],
[Assembly directive for exporting symbols])
OMPI_ASM_GLOBAL="$ompi_cv_asm_global"
AC_SUBST(OMPI_AS_GLOBAL)
])dnl
dnl #################################################################
dnl
dnl OMPI_CHECK_ASM_LSYM
dnl
dnl Sets OMPI_ASM_LSYM to the prefix value on a symbol to make it
dnl an internal label (jump target and whatnot)
dnl
dnl We look for L .L $ L$ (in that order) for something that both
dnl assembles and does not leave a label in the output of nm. Fall
dnl back to L if nothing else seems to work :/
dnl
dnl #################################################################
AC_DEFUN([OMPI_CHECK_ASM_LSYM],[
AC_REQUIRE([OMPI_CHECK_ASM_LABEL_SUFFIX])
AC_REQUIRE([AC_PROG_NM])
AC_MSG_CHECKING([prefix for lsym labels])
ompi_cv_asm_lsym="L"
for sym in L .L $ L$ ; do
asm_result=0
echo "configure: trying $sym" >& AC_FD_CC
OMPI_TRY_ASSEMBLE([foobar$ompi_cv_asm_label_suffix
${sym}mytestlabel$ompi_cv_asm_label_suffix],
[# ok, we succeeded at assembling. see if we can nm,
# throwing the results in a file
if $NM conftest.$OBJEXT > conftest.out 2>&AC_FD_CC ; then
if test "`grep mytestlabel conftest.out`" = "" ; then
# there was no symbol... looks promising to me
ompi_cv_asm_lsym="$sym"
asm_result=1
elif test ["`grep ' [Nt] .*mytestlabel' conftest.out`"] = "" ; then
# see if we have a non-global-ish symbol
# but we should see if we can do better.
ompi_cv_asm_lsym="$sym"
fi
else
# not so much on the NM goodness :/
echo "$NM failed. Output from NM was:" >& AC_FD_CC
cat conftest.out > AC_FD_CC
AC_MSG_WARN([$NM could not read object file])
fi
])
if test "$asm_result" = "1" ; then
break
fi
done
rm -f conftest.out
AC_MSG_RESULT([$ompi_cv_asm_lsym])
AC_DEFINE_UNQUOTED([OMPI_ASM_LSYM], ["$ompi_cv_asm_lsym"],
[Assembly prefix for lsym labels])
OMPI_ASM_LSYM="$ompi_cv_asm_lsym"
AC_SUBST(OMPI_ASM_LSYM)
unset asm_result sym
])dnl
dnl #################################################################
dnl
dnl OMPI_CHECK_ASM_GSYM
dnl
dnl Sets OMPI_ASM_GSYM to the prefix value on a symbol to make it
dnl a global linkable from C. Basically, an _ or not.
dnl
dnl #################################################################
AC_DEFUN([OMPI_CHECK_ASM_GSYM],[
AC_REQUIRE([OMPI_CHECK_ASM_TEXT])
AC_REQUIRE([OMPI_CHECK_ASM_GLOBAL])
AC_REQUIRE([OMPI_CHECK_ASM_LABEL_SUFFIX])
AC_MSG_CHECKING([prefix for global symbol labels])
ompi_cv_asm_gsym="none"
for sym in "_" "" ; do
asm_result=0
echo "configure: trying $sym" >& AC_FD_CC
cat > conftest_c.c <<EOF
#ifdef __cplusplus
extern "C" {
#endif
void gsym_test_func(void);
#ifdef __cplusplus
}
#endif
int
main(int argc, char *argv[[]])
{
gsym_test_func();
return 0;
}
EOF
OMPI_TRY_ASSEMBLE([
$ompi_cv_asm_text
$ompi_cv_asm_global ${sym}gsym_test_func
${sym}gsym_test_func${ompi_cv_asm_label_suffix}],
[ompi_compile="$CC $CFLAGS -I. conftest_c.c -c > conftest.cmpl 2>&1"
if AC_TRY_EVAL(ompi_compile) ; then
# save the warnings
cat conftest.cmpl >&AC_FD_CC
ompi_link="$CC $CFLAGS conftest_c.$OBJEXT conftest.$OBJEXT -o conftest > conftest.link 2>&1"
if AC_TRY_EVAL(ompi_link) ; then
# save the warnings
cat conftest.link >&AC_FD_CC
asm_result=1
else
cat conftest.link >&AC_FD_CC
echo "configure: failed C program was: " >&AC_FD_CC
cat conftest_c.c >&AC_FD_CC
echo "configure: failed ASM program was: " >&AC_FD_CC
cat conftest.s >&AC_FD_CC
asm_result=0
fi
else
# save output and failed program
cat conftest.cmpl >&AC_FD_CC
echo "configure: failed C program was: " >&AC_FD_CC
cat conftest.c >&AC_FD_CC
asm_result=0
fi],
[asm_result=0])
if test "$asm_result" = "1" ; then
ompi_cv_asm_gsym="$sym"
break
fi
done
rm -f conftest.*
AC_MSG_RESULT([$ompi_cv_asm_gsym])
if test "$ompi_cv_asm_gsym" = "none" ; then
AC_MSG_ERROR([Could not determine global symbol label prefix])
fi
AC_DEFINE_UNQUOTED([OMPI_ASM_GSYM], ["$ompi_cv_asm_gsym"],
[Assembly prefix for lsym labels])
OMPI_ASM_GSYM="$ompi_cv_asm_gsym"
AC_SUBST(OMPI_ASM_GSYM)
])dnl
dnl #################################################################
dnl
dnl OMPI_CHECK_ASM_LABEL_SUFFIX
dnl
dnl Sets OMPI_ASM_LABEL_SUFFIX to the value to suffix for labels
dnl
dnl I'm sure if I don't have a test for this, there will be some
dnl dumb platform that uses something else
dnl
dnl #################################################################
AC_DEFUN([OMPI_CHECK_ASM_LABEL_SUFFIX],[
AC_MSG_CHECKING([suffix for labels])
ompi_cv_asm_label_suffix=""
case $host in
*)
ompi_cv_asm_label_suffix=":"
;;
esac
AC_MSG_RESULT([$ompi_cv_asm_label_suffix])
AC_DEFINE_UNQUOTED([OMPI_ASM_LABEL_SUFFIX], ["$ompi_cv_asm_label_suffix"],
[Assembly suffix for labels])
OMPI_ASM_LABEL_SUFFIX="$ompi_cv_asm_label_suffix"
AC_SUBST(OMPI_AS_LABEL_SUFFIX)
])dnl
dnl #################################################################
dnl
dnl OMPI_CHECK_ASM_ALIGN_LOG
dnl
dnl Sets OMPI_ASM_ALIGN_LOG to 1 if align is specified
dnl logarithmically, 0 otherwise
dnl
dnl #################################################################
AC_DEFUN([OMPI_CHECK_ASM_ALIGN_LOG],[
AC_REQUIRE([OMPI_CHECK_ASM_TEXT])
AC_REQUIRE([OMPI_CHECK_ASM_GLOBAL])
AC_REQUIRE([OMPI_CHECK_ASM_LABEL_SUFFIX])
AC_REQUIRE([AC_PROG_NM])
ompi_cv_asm_align_log=0
asm_result="no"
AC_MSG_CHECKING([if .align directive takes logarithmic value])
OMPI_TRY_ASSEMBLE([ $ompi_cv_asm_text
.align 4
$ompi_cv_asm_global foo
.byte 1
.align 4
foo$ompi_cv_asm_label_suffix
.byte 2],
[ompi_asm_addr=[`$NM conftest.$OBJEXT | sed -e 's/.*\([0-9a-fA-F][0-9a-fA-F]\).*foo.*/\1/'`]],
[ompi_asm_addr=""])
# test for both 16 and 10 (decimal and hex notations)
echo "configure: .align test address offset is $ompi_asm_addr" >& AC_FD_CC
if test "$ompi_asm_addr" = "16" -o "$ompi_asm_addr" = "10" ; then
ompi_cv_asm_align_log=1
asm_result="yes"
fi
AC_MSG_RESULT([$asm_result])
AC_DEFINE_UNQUOTED([OMPI_ASM_ALIGN_LOG],
[$ompi_cv_asm_align_log],
[Assembly align directive expects logarithmic value])
unset omp_asm_addr asm_result
])dnl
dnl #################################################################
dnl
dnl OMPI_CHECK_ASM_TYPE
dnl
dnl Sets OMPI_ASM_TYPE to the prefix for the function type to
dnl set a symbol's type as function (needed on ELF for shared
dnl libaries). If no .type directive is needed, sets OMPI_ASM_TYPE
dnl to an empty string
dnl
dnl We look for @ \# %
dnl
dnl #################################################################
AC_DEFUN([OMPI_CHECK_ASM_TYPE],[
AC_MSG_CHECKING([prefix for function in .type])
ompi_cv_asm_type=""
for type in @ \# % ; do
asm_result=0
echo "configure: trying $type" >& AC_FD_CC
OMPI_TRY_ASSEMBLE([ .type mysym, ${type}function],
[# ok, we succeeded at assembling. see if there was
# a warning in the output.
if test "`cat conftest.out`" = "" ; then
ompi_cv_asm_type="${type}"
asm_result=1
fi])
if test "$asm_result" = "1" ; then
break
fi
done
rm -f conftest.out
AC_MSG_RESULT([$ompi_cv_asm_type])
AC_DEFINE_UNQUOTED([OMPI_ASM_TYPE], ["$ompi_cv_asm_type"],
[How to set function type in .type directive])
OMPI_ASM_TYPE="$ompi_cv_asm_type"
AC_SUBST(OMPI_ASM_TYPE)
unset asm_result type
])dnl
dnl #################################################################
dnl
dnl OMPI_CHECK_ASM_SIZE
dnl
dnl Sets OMPI_ASM_SIZE to 1 if we should set .size directives for
dnl each function, 0 otherwise.
dnl
dnl #################################################################
AC_DEFUN([OMPI_CHECK_ASM_SIZE],[
AC_MSG_CHECKING([if .size is needed])
ompi_cv_asm_size=0
asm_result="no"
OMPI_TRY_ASSEMBLE([ .size mysym, 1],
[# ok, we succeeded at assembling. see if there was
# a warning in the output.
if test "`cat conftest.out`" = "" ; then
ompi_cv_asm_size=1
asm_result="yes"
fi])
rm -f conftest.out
AC_MSG_RESULT([$asm_result])
AC_DEFINE_UNQUOTED([OMPI_ASM_SIZE], ["$ompi_cv_asm_size"],
[Do we need to give a .size directive?])
OMPI_ASM_SIZE="$ompi_cv_asm_size"
AC_SUBST(OMPI_ASM_TYPE)
unset asm_result
])dnl
dnl #################################################################
dnl
dnl OMPI_CHECK_POWERPC_REG
dnl
dnl See if the notation for specifying registers is X (most everyone)
dnl or rX (OS X)
dnl
dnl #################################################################
AC_DEFUN([OMPI_CHECK_POWERPC_REG],[
AC_REQUIRE([OMPI_CHECK_ASM_TEXT])
AC_MSG_CHECKING([if PowerPC registers have r prefix])
OMPI_TRY_ASSEMBLE([$ompi_cv_asm_text
addi 1,1,0],
[ompi_cv_asm_powerpc_r_reg=0],
OMPI_TRY_ASSEMBLE([$ompi_cv_asm_text
addi r1,r1,0],
[ompi_cv_asm_powerpc_r_reg=1],
AC_MSG_ERROR([Can not determine how to use PPC registers])))
if test "$ompi_cv_asm_powerpc_r_reg" = "1" ; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
AC_DEFINE_UNQUOTED([OMPI_POWERPC_R_REGISTERS],
[$ompi_cv_asm_powerpc_r_reg],
[Whether r notation is used for ppc registers])
])dnl
dnl #################################################################
dnl
dnl OMPI_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([OMPI_CHECK_POWERPC_64BIT],[
AC_REQUIRE([OMPI_CHECK_ASM_TEXT])
AC_MSG_CHECKING([for 64-bit PowerPC assembly support])
ppc64_result=0
if test "$ompi_cv_asm_powerpc_r_reg" = "1" ; then
ldarx_asm=" ldarx r1,r1,r1";
else
ldarx_asm=" ldarx1,1,1";
fi
OMPI_TRY_ASSEMBLE([$ompi_cv_asm_text
$ldarx_asm],
[ppc64_result=1],
[ppc64_result=0])
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 OMPI_CHECK_INLINE_GCC
dnl
dnl Check if the compiler is capable of doing GCC-style inline
dnl assembly. Some compilers emit a warning and ignore the inline
dnl assembly (xlc on OS X) and compile without error. Therefore,
dnl the test attempts to run the emited code to check that the
dnl assembly is actually run. To run this test, one argument to
dnl the macro must be an assembly instruction in gcc format to move
dnl the value 0 into the register containing the variable ret.
dnl For PowerPC, this would be:
dnl
dnl "li %0,0" : "=&r"(ret)
dnl
dnl DEFINE OMPI_GCC_INLINE_ASSEMBLY to 0 or 1 depending on GCC
dnl support
dnl
dnl #################################################################
AC_DEFUN([OMPI_CHECK_INLINE_GCC],[
assembly="$1"
asm_result="unknown"
AC_MSG_CHECKING([if $CC supports GCC inline assembly])
if test ! "$assembly" = "" ; then
AC_RUN_IFELSE(AC_LANG_PROGRAM([[
AC_INCLUDES_DEFAULT]],
[[int ret = 1;
__asm__ __volatile__ ($assembly);
return ret;]]),
[asm_result="yes"], [asm_result="no"],
[asm_result="unknown"])
else
assembly="test skipped - assuming no"
fi
# if we're cross compiling, just try to compile and figure good enough
if test "$asm_result" = "unknown" ; then
AC_LINK_IFELSE(AC_LANG_PROGRAM([[
AC_INCLUDES_DEFAULT]],
[[int ret = 1;
__asm__ __volatile__ ($assembly);
return ret;]]),
[asm_result="yes"], [asm_result="no"])
fi
AC_MSG_RESULT([$asm_result])
if test "$asm_result" = "yes" ; then
OMPI_GCC_INLINE_ASSEMBLY=1
else
OMPI_GCC_INLINE_ASSEMBLY=0
fi
AC_DEFINE_UNQUOTED([OMPI_GCC_INLINE_ASSEMBLY],
[$OMPI_GCC_INLINE_ASSEMBLY],
[Whether compiler supports GCC style inline assembly])
unset OMPI_GCC_INLINE_ASSEMBLY assembly asm_result
])dnl
dnl #################################################################
dnl
dnl OMPI_CHECK_INLINE_DEC
dnl
dnl DEFINE OMPI_DEC to 0 or 1 depending on DEC
dnl support
dnl
dnl #################################################################
AC_DEFUN([OMPI_CHECK_INLINE_DEC],[
AC_MSG_CHECKING([if $CC supports DEC inline assembly])
AC_LINK_IFELSE(AC_LANG_PROGRAM([[
AC_INCLUDES_DEFAULT
#include <c_asm.h>]],
[[asm("");
return 0;]]),
[asm_result="yes"], [asm_result="no"])
AC_MSG_RESULT([$asm_result])
if test "$asm_result" = "yes" ; then
OMPI_DEC_INLINE_ASSEMBLY=1
else
OMPI_DEC_INLINE_ASSEMBLY=0
fi
AC_DEFINE_UNQUOTED([OMPI_DEC_INLINE_ASSEMBLY],
[$OMPI_DEC_INLINE_ASSEMBLY],
[Whether compiler supports DEC style inline assembly])
unset OMPI_DEC_INLINE_ASSEMBLY asm_result
])dnl
dnl #################################################################
dnl
dnl OMPI_CHECK_INLINE_XLC
dnl
dnl DEFINE OMPI_XLC to 0 or 1 depending on XLC
dnl support
dnl
dnl #################################################################
AC_DEFUN([OMPI_CHECK_INLINE_XLC],[
AC_MSG_CHECKING([if $CC supports XLC inline assembly])
OMPI_XLC_INLINE_ASSEMBLY=0
asm_result="no"
if test "$CC" = "xlc" ; then
if test "$CXX" = "xlC" -o "$CXX" = "xlc++" ; then
OMPI_XLC_INLINE_ASSEMBLY=1
asm_result="yes"
fi
fi
AC_MSG_RESULT([$asm_result])
AC_DEFINE_UNQUOTED([OMPI_XLC_INLINE_ASSEMBLY],
[$OMPI_XLC_INLINE_ASSEMBLY],
[Whether compiler supports XLC style inline assembly])
unset OMPI_XLC_INLINE_ASSEMBLY
])dnl
dnl #################################################################
dnl
dnl OMPI_CONFIG_ASM
dnl
dnl DEFINE OMPI_ASSEMBLY_ARCH to something in sys/architecture.h
dnl DEFINE OMPI_ASSEMBLY_FORMAT to string containing correct
dnl format for assembly (not user friendly)
dnl SUBST OMPI_ASSEMBLY_FORMAT to string containing correct
dnl format for assembly (not user friendly)
dnl
dnl #################################################################
AC_DEFUN([OMPI_CONFIG_ASM],[
AC_REQUIRE([OMPI_SETUP_CC])
AC_REQUIRE([OMPI_SETUP_CXX])
AC_REQUIRE([AM_PROG_AS])
AC_REQUIRE([OMPI_CHECK_ASM_TEXT])
AC_REQUIRE([OMPI_CHECK_ASM_GLOBAL])
AC_REQUIRE([OMPI_CHECK_ASM_GSYM])
AC_REQUIRE([OMPI_CHECK_ASM_LSYM])
AC_REQUIRE([OMPI_CHECK_ASM_TYPE])
AC_REQUIRE([OMPI_CHECK_ASM_SIZE])
AC_REQUIRE([OMPI_CHECK_ASM_LABEL_SUFFIX])
AC_REQUIRE([OMPI_CHECK_ASM_ALIGN_LOG])
AC_MSG_CHECKING([whether to enable smp locks])
AC_ARG_ENABLE(smp-locks,
AC_HELP_STRING([--enable-smp-locks],
[disable smp locks in atomic ops (default: enabled)]))
if test "$enable_smp_locks" != "no"; then
AC_MSG_RESULT([yes])
want_smp_locks=1
else
AC_MSG_RESULT([no])
want_smp_locks=1
fi
AC_DEFINE_UNQUOTED([OMPI_WANT_SMP_LOCKS], [$want_smp_locks],
[whether we want to have smp locks in atomic ops or not])
# find our architecture for purposes of assembly stuff
ompi_cv_asm_arch="UNSUPPORTED"
OMPI_GCC_INLINE_ASSIGN=""
OMPI_POWERPC_SUPPORT_64BIT=0
case "${host}" in
*-winnt*)
ompi_cv_asm_arch="WINDOWS"
;;
i?86-*)
ompi_cv_asm_arch="IA32"
OMPI_GCC_INLINE_ASSIGN='"movl [$]0, %0" : "=&r"(ret)'
;;
x86_64*)
ompi_cv_asm_arch="AMD64"
OMPI_GCC_INLINE_ASSIGN='"movl [$]0, %0" : "=&r"(ret)'
;;
ia64-*)
ompi_cv_asm_arch="IA64"
OMPI_GCC_INLINE_ASSIGN='"mov %0=r0\n;;\n" : "=&r"(ret)'
;;
alpha-*)
ompi_cv_asm_arch="ALPHA"
OMPI_GCC_INLINE_ASSIGN='"bis zero,zero,%0" : "=&r"(ret)'
;;
powerpc-*)
OMPI_CHECK_POWERPC_REG
if test "$ac_cv_sizeof_long" = "4" ; then
ompi_cv_asm_arch="POWERPC32"
# Note that on some platforms (Apple G5), even if we are
# compiling in 32 bit more (and therefore should assume
# sizeof(long) == 4), we can use the 64 bit test and set
# operations.
OMPI_CHECK_POWERPC_64BIT(OMPI_POWERPC_SUPPORT_64BIT=1)
elif test "$ac_cv_sizeof_long" = "8" ; then
OMPI_POWERPC_SUPPORT_64BIT=1
ompi_cv_asm_arch="POWERPC64"
else
AC_MSG_ERROR([Could not determine PowerPC word size: $ac_cv_sizeof_long])
fi
OMPI_GCC_INLINE_ASSIGN='"li %0,0" : "=&r"(ret)'
;;
sparc-*)
if test "$ac_cv_sizeof_long" = "4" ; then
ompi_cv_asm_arch="SPARC32"
elif test "$ac_cv_sizeof_long" = "8" ; then
ompi_cv_asm_arch="SPARC64"
else
AC_MSG_ERROR([Could not determine Sparc word size: $ac_cv_sizeof_long])
fi
OMPI_GCC_INLINE_ASSIGN='"mov 0,%0" : : "=&r"(ret)'
;;
*)
AC_MSG_ERROR([No atomic primitives available for $host])
;;
esac
AC_DEFINE_UNQUOTED([OMPI_POWERPC_SUPPORT_64BIT],
[$OMPI_POWERPC_SUPPORT_64BIT],
[Non-zero if safe to call PPC64 ops, even in PPC32 code])
AC_SUBST([OMPI_POWERPC_SUPPORT_64BIT])
# now that we know our architecture, try to inline assemble
OMPI_CHECK_INLINE_GCC([$OMPI_GCC_INLINE_ASSIGN])
OMPI_CHECK_INLINE_DEC
OMPI_CHECK_INLINE_XLC
# format:
# text-global-label_suffix-gsym-lsym-type-size-align_log-ppc_r_reg-64_bit
asm_format="${ompi_cv_asm_text}-${ompi_cv_asm_global}"
asm_format="${asm_format}-${ompi_cv_asm_label_suffix}-${ompi_cv_asm_gsym}"
asm_format="${asm_format}-${ompi_cv_asm_lsym}"
asm_format="${asm_format}-${ompi_cv_asm_type}-${ompi_cv_asm_size}"
asm_format="${asm_format}-${ompi_cv_asm_align_log}"
if test "$ompi_cv_asm_arch" = "POWERPC32" -o "$ompi_cv_asm_arch" = "POWERPC64" ; then
asm_format="${asm_format}-${ompi_cv_asm_powerpc_r_reg}"
else
asm_format="${asm_format}-1"
fi
ompi_cv_asm_format="${asm_format}-${OMPI_POWERPC_SUPPORT_64BIT}"
OMPI_ASSEMBLY_FORMAT="$ompi_cv_asm_format"
AC_MSG_CHECKING([for assembly format])
AC_MSG_RESULT([$OMPI_ASSEMBLY_FORMAT])
AC_DEFINE_UNQUOTED([OMPI_ASSEMBLY_FORMAT], ["$OMPI_ASSEMBLY_FORMAT"],
[Format of assembly file])
AC_SUBST([OMPI_ASSEMBLY_FORMAT])
result="OMPI_$ompi_cv_asm_arch"
OMPI_ASSEMBLY_ARCH="$ompi_cv_asm_arch"
AC_MSG_CHECKING([for asssembly architecture])
AC_MSG_RESULT([$ompi_cv_asm_arch])
AC_DEFINE_UNQUOTED([OMPI_ASSEMBLY_ARCH], [$result],
[Architecture type of assembly to use for atomic operations])
AC_SUBST([OMPI_ASSEMBLY_ARCH])
OMPI_ASM_FIND_FILE
unset result asm_format
])dnl
dnl #################################################################
dnl
dnl OMPI_ASM_FIND_FILE
dnl
dnl
dnl do all the evil mojo to provide a working assembly file
dnl
dnl #################################################################
AC_DEFUN([OMPI_ASM_FIND_FILE], [
AC_CHECK_PROG([PERL], [perl], [perl])
# see if we have a pre-built one already
AC_MSG_CHECKING([for pre-built assembly file])
ompi_cv_asm_file=""
if grep "$ompi_cv_asm_arch.*$ompi_cv_asm_format" "${top_ompi_srcdir}/src/asm/asm-data.txt" >conftest.out 2>&1 ; then
ompi_cv_asm_file="`cut -f3 conftest.out`"
if test ! "$ompi_cv_asm_file" = "" ; then
ompi_cv_asm_file="atomic-${ompi_cv_asm_file}.s"
if test -f "${top_ompi_srcdir}/src/asm/generated/${ompi_cv_asm_file}" ; then
AC_MSG_RESULT([yes ($ompi_cv_asm_file)])
else
AC_MSG_RESULT([no ($ompi_cv_asm_file not found)])
ompi_cv_asm_file=""
fi
fi
else
AC_MSG_RESULT([no (not in asm-data)])
fi
rm -f conftest.*
if test "$ompi_cv_asm_file" = "" ; then
if test ! "$PERL" = "" ; then
# we have perl... Can we generate a file?
AC_MSG_CHECKING([whether possible to generate assembly file])
ompi_cv_asm_file="atomic-local.s"
ompi_try="$PERL \"$top_ompi_srcdir/src/asm/generate-asm.pl\" \"$ompi_cv_asm_arch\" \"$ompi_cv_asm_format\" \"$top_ompi_srcdir/src/asm/base\" \"$top_ompi_builddir/src/asm/generated/$ompi_cv_asm_file\" >conftest.out 2>&1"
if AC_TRY_EVAL(ompi_try) ; then
# save the warnings
cat conftest.out >&AC_FD_CC
AC_MSG_RESULT([yes])
else
# save output
cat conftest.out >&AC_FD_CC
ompi_cv_asm_file=""
AC_MSG_RESULT([failed])
AC_MSG_WARN([Could not build atomic operations assembly file.])
AC_MSG_WARN([There will be no atomic operations for this build.])
fi
else
AC_MSG_WARN([Could not find prebuilt atomic operations file and could not])
AC_MSG_WARN([find perl to attempt to generate a custom assembly file.])
AC_MSG_WARN([There will be no atomic operations for this build.])
fi
fi
rm -f conftest.*
AC_MSG_CHECKING([for atomic assembly filename])
if test "$ompi_cv_asm_file" = "" ; then
AC_MSG_RESULT([none])
result=0
else
AC_MSG_RESULT([$ompi_cv_asm_file])
result=1
fi
AC_DEFINE_UNQUOTED([OMPI_HAVE_ASM_FILE], [$result],
[Whether there is an atomic assembly file available])
AM_CONDITIONAL([OMPI_HAVE_ASM_FILE], [test "$result" = "1"])
OMPI_ASM_FILE=$ompi_cv_asm_file
AC_SUBST(OMPI_ASM_FILE)
])dnl

View File

@ -0,0 +1,43 @@
dnl
dnl Copyright (c) 2004-2005 The Trustees of Indiana University.
dnl All rights reserved.
dnl Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
dnl All rights reserved.
dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
dnl University of Stuttgart. All rights reserved.
dnl $COPYRIGHT$
dnl
dnl Additional copyrights may follow
dnl
dnl $HEADER$
dnl
dnl OMPI_TRY_ASSEMBLE(asm-code, [action-if-success], [action-if-fail])
dnl
dnl Attempt to assemble asm-code. If success, run action-if-success.
dnl Otherwise, run action-if-fail. Neither action-if-success nor
dnl action-if-fail are required.
dnl
dnl No preprocessing is guaranteed to be done on asm-code. Some
dnl compilers do not run the preprocessor on assembly files.
dnl
dnl On failure, asm-test.s will be included in config.out
AC_DEFUN([OMPI_TRY_ASSEMBLE],
[cat >conftest.s <<EOF
[$1]
EOF
ompi_assemble="$CCAS $CFLAGS -c conftest.s >conftest.out 2>&1"
if AC_TRY_EVAL(ompi_assemble); then
# save the warnings
cat conftest.out >&AC_FD_CC
ifelse([$2],,:,[$2])
else
# save compiler output and failed program
cat conftest.out >&AC_FD_CC
echo "configure: failed program was:" >&AC_FD_CC
cat conftest.s >&AC_FD_CC
ifelse([$3],,:,[$3])
fi
rm -f conftest*
unset ompi_assemble
])dnl

View File

@ -315,6 +315,16 @@ AC_DEFINE_UNQUOTED(OMPI_WANT_CXX_BINDINGS, $WANT_MPI_CXX_SUPPORT,
[Whether we want MPI cxx support or not])
##################################
# Assembler Configuration
##################################
ompi_show_subtitle "Assembler"
AM_PROG_AS
OMPI_CONFIG_ASM
##################################
# Fortran
##################################
@ -1382,6 +1392,7 @@ AC_CONFIG_FILES([
src/event/compat/sys/Makefile
src/attribute/Makefile
src/asm/Makefile
src/communicator/Makefile
src/datatype/Makefile
src/errhandler/Makefile

View File

@ -66,6 +66,7 @@ endif
SUBDIRS = \
include \
$(LIBLTDL_SUBDIR) \
asm \
attribute \
communicator \
datatype \
@ -94,6 +95,7 @@ lib_LTLIBRARIES = libmpi.la
libmpi_la_SOURCES =
libmpi_la_LIBADD = \
$(LIBLTDL_LTLIB) \
asm/libasm.la \
attribute/libattribute.la \
class/liblfc.la \
communicator/libcommunicator.la \

80
src/asm/Makefile.am Normal file
View File

@ -0,0 +1,80 @@
#
# Copyright (c) 2004-2005 The Trustees of Indiana University.
# All rights reserved.
# Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
# All rights reserved.
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
include $(top_srcdir)/config/Makefile.options
######################################################################
#
# This is a bit complicated. If there is anything in the library,
# it will always be atomic-asm.s. We just symlink atomic-asm.s to
# the best atomic operations available (as determined at configure
# time)
#
######################################################################
generated/@OMPI_ASM_FILE@: base/@OMPI_ASSEMBLY_ARCH@.asm
$(PERL) "$(top_srcdir)/src/asm/generate-asm.pl" "@OMPI_ASSEMBLY_ARCH@" "@OMPI_ASSEMBLY_FORMAT@" "$(top_srcdir)/src/asm/base" "$(top_builddir)/src/asm/generated/@OMPI_ASM_FILE@"
atomic-asm.s: generated/@OMPI_ASM_FILE@
rm -f atomic-asm.s
@ if test -f $(top_srcdir)/src/asm/generated/@OMPI_ASM_FILE@ ; then \
cmd="ln -s $(top_srcdir)/src/asm/generated/@OMPI_ASM_FILE@ atomic-asm.s" ; \
echo "$$cmd" ; \
$$cmd ; \
else \
cmd="ln -s $(top_builddir)/src/asm/generated/@OMPI_ASM_FILE@ atomic-asm.s" ; \
echo "$$cmd" ; \
$$cmd ; \
fi
if OMPI_HAVE_ASM_FILE
libasm_la_SOURCES = atomic-asm.s
else
libasm_la_SOURCES =
endif
libasm_la_DEPENDENCIES = generated/@OMPI_ASM_FILE@
lib_LTLIBRARIES = libasm.la
EXTRA_DIST = \
asm-data.txt \
generate-asm.pl \
generate-all-asm.sh \
base/AMD64.asm \
base/IA32.asm \
base/POWERPC32.asm \
base/POWERPC64.asm
######################################################################
TESTS = atomic-test
check_PROGRAMS = atomic-test
atomic_test_SOURCES = atomic-test.c
atomic_test_LDADD = libasm.la
######################################################################
clean-local:
rm -f atomic-asm.s
maintainer-clean-local:
rm -f generated/atomic-local.s
######################################################################
#
# Copy over all the generated files
#
dist-hook:
mkdir ${distdir}/generated
sh generate-all-asm.sh "$(PERL)" "$(srcdir)" "$(distdir)"

27
src/asm/asm-data.txt Normal file
View File

@ -0,0 +1,27 @@
#
# Copyright (c) 2004-2005 The Trustees of Indiana University.
# All rights reserved.
# Copyright (c) 2004-2005 The Trustees of the University of Tennessee.
# All rights reserved.
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
# University of Stuttgart. All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
#
# $HEADER$
#
#
# Database for mapping architecture and assembly format to prebuilt
# assembly files.
#
# FORMAT:
# ARCHITECTURE ASSEMBLY FORMAT BASE FILENAME
#
AMD64 .text-.globl-:--.L-@-1-0-1-0 amd64-linux
IA32 .text-.globl-:--.L-@-1-0-1-0 ia32-linux
POWERPC32 .text-.globl-:-_-L--0-1-1-0 powerpc32-osx
POWERPC32 .text-.globl-:-_-L--0-1-1-1 powerpc32-64-osx
POWERPC64 .text-.globl-:-_-L--0-1-1-1 powerpc64-osx

457
src/asm/atomic-test.c Normal file
View File

@ -0,0 +1,457 @@
#undef OMPI_BUILDING
#include "ompi_config.h"
#include <assert.h>
#include <getopt.h>
#ifdef HAVE_PTHREAD_H
#include <pthread.h>
#endif
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "include/sys/atomic.h"
/**
* A testing support library to provide uniform reporting output
*/
static int ompi_n_tests;
static int ompi_n_success;
static int ompi_n_failures;
static char *ompi_description;
static void test_init(char *a)
{
/* local variables */
size_t len;
/* save the descriptive string */
len = strlen(a);
ompi_description = (char *) malloc(len + 1);
assert(ompi_description);
strcpy(ompi_description, a);
/* initialize counters */
ompi_n_tests = 0;
ompi_n_success = 0;
ompi_n_failures = 0;
return;
}
static void test_success(void)
{
ompi_n_tests++;
ompi_n_success++;
}
static void test_failure(char *a)
{
ompi_n_tests++;
ompi_n_failures++;
fprintf(stderr, " Failure : ");
fprintf(stderr, a);
fprintf(stderr, "\n");
fflush(stderr);
}
static int test_verify_int(int expected_result, int test_result)
{
int return_value;
return_value = 1;
if (expected_result != test_result) {
test_failure("Comparison failure");
fprintf(stderr, " Expected result: %d\n", expected_result);
fprintf(stderr, " Test result: %d\n", test_result);
fflush(stderr);
return_value = 0;
} else {
test_success();
}
return return_value;
}
static int test_finalize(void)
{
int return_value;
return_value = 1;
if (ompi_n_tests == ompi_n_success) {
fprintf(stderr, "SUPPORT: OMPI Test Passed: %s: (%d tests)\n",
ompi_description, ompi_n_tests);
fflush(stderr);
} else {
fprintf(stderr,
"SUPPORT: OMPI Test failed: %s (%d of %d failed)\n",
ompi_description, ompi_n_failures, ompi_n_tests);
fflush(stderr);
return_value = 0;
}
return return_value;
}
/* note this is for additional output that does NOT go to STDERR but STDOUT */
static void test_comment (char* userstr)
{
fprintf(stdout, "%s:%s\n", ompi_description, userstr);
}
/* default options */
int nreps = 100;
int nthreads = 2;
int enable_verbose = 0;
int enable_64_bit_tests = 0;
volatile int32_t vol32;
int32_t val32;
int32_t old32;
int32_t new32;
#ifdef ENABLE_64_BIT
volatile int64_t vol64;
int64_t val64;
int64_t old64;
int64_t new64;
#endif
volatile int volint;
int valint;
int oldint;
int newint;
volatile void *volptr;
void *oldptr;
void *newptr;
static void help(void)
{
printf("Usage: threadtest [flags]\n"
"\n"
" Flags may be any of\n"
#ifdef ENABLE_64_BIT
" -l do 64-bit tests\n"
#endif
" -r NREPS number of repetitions\n"
" -t NTRHEADS number of threads\n"
" -v verbose output\n"
" -h print this info\n" "\n"
" Numbers may be postfixed with 'k' or 'm'\n\n");
#ifndef ENABLE_64_BIT
printf(" 64-bit tests are not enabled in this build of the tests\n\n");
#endif
exit(EXIT_SUCCESS);
}
static void usage(void)
{
fprintf(stderr,
"Usage: threadtest [flags]\n" " threadtest -h\n");
exit(EXIT_FAILURE);
}
static void verbose(const char *fmt, ...)
{
if (enable_verbose) {
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
}
static int str2size(char *str)
{
int size;
char mod[32];
switch (sscanf(str, "%d%1[mMkK]", &size, mod)) {
case 1:
return (size);
case 2:
switch (*mod) {
case 'm':
case 'M':
return (size << 20);
case 'k':
case 'K':
return (size << 10);
default:
return (size);
}
default:
return (-1);
}
}
static void *thread_main(void *arg)
{
int rank = (int) arg;
int i;
verbose("thread-%d: Hello\n", rank);
/* thread tests */
for (i = 0; i < nreps; i++) {
ompi_atomic_add_32(&val32, 5);
#ifdef ENABLE_64_BIT
if (enable_64_bit_tests) {
ompi_atomic_add_64(&val64, 5);
}
#endif
ompi_atomic_add(&valint, 5);
}
return (void *) (rank + 1000);
}
int main(int argc, char *argv[])
{
int c;
int tid;
pthread_t *th;
/* option processing */
test_init("atomic operations");
while ((c = getopt(argc, argv, "hlr:t:v")) != -1) {
switch (c) {
case 'h':
help();
break;
case 'l':
#ifdef ENABLE_64_BIT
enable_64_bit_tests = 1;
#else
usage();
#endif
break;
case 'r':
if ((nreps = str2size(optarg)) <= 0) {
usage();
}
break;
case 't':
if ((nthreads = str2size(optarg)) <= 0) {
usage();
}
break;
case 'v':
enable_verbose = 1;
break;
default:
usage();
}
}
if (optind != argc) {
usage();
}
verbose("main: %s\n", argv[0]);
verbose("main: nthreads = %d\n", nthreads);
verbose("main: nreps = %d\n", nreps);
/* first test single-threaded functionality */
/* -- cmpset 32-bit tests -- */
vol32 = 42, old32 = 42, new32 = 50;
test_verify_int(ompi_atomic_cmpset_32(&vol32, old32, new32), 1);
test_verify_int(vol32, new32);
vol32 = 42, old32 = 420, new32 = 50;
test_verify_int(ompi_atomic_cmpset_32(&vol32, old32, new32), 0);
test_verify_int(vol32, 42);
vol32 = 42, old32 = 42, new32 = 50;
test_verify_int(ompi_atomic_cmpset_acq_32(&vol32, old32, new32), 1);
test_verify_int(vol32, new32);
vol32 = 42, old32 = 420, new32 = 50;
test_verify_int(ompi_atomic_cmpset_acq_32(&vol32, old32, new32), 0);
test_verify_int(vol32, 42);
vol32 = 42, old32 = 42, new32 = 50;
test_verify_int(ompi_atomic_cmpset_rel_32(&vol32, old32, new32), 1);
test_verify_int(vol32, new32);
vol32 = 42, old32 = 420, new32 = 50;
test_verify_int(ompi_atomic_cmpset_rel_32(&vol32, old32, new32), 0);
test_verify_int(vol32, 42);
/* -- cmpset 64-bit tests -- */
#ifdef ENABLE_64_BIT
if (enable_64_bit_tests) {
verbose("64 bit serial tests\n");
vol64 = 42, old64 = 42, new64 = 50;
test_verify_int(1, ompi_atomic_cmpset_64(&vol64, old64, new64));
test_verify_int(new64, vol64);
verbose("64 bit serial test 2\n");
vol64 = 42, old64 = 420, new64 = 50;
test_verify_int(ompi_atomic_cmpset_64(&vol64, old64, new64), 0);
test_verify_int(vol64, 42);
vol64 = 42, old64 = 42, new64 = 50;
test_verify_int(ompi_atomic_cmpset_acq_64(&vol64, old64, new64), 1);
test_verify_int(vol64, new64);
vol64 = 42, old64 = 420, new64 = 50;
test_verify_int(ompi_atomic_cmpset_acq_64(&vol64, old64, new64), 0);
test_verify_int(vol64, 42);
vol64 = 42, old64 = 42, new64 = 50;
test_verify_int(ompi_atomic_cmpset_rel_64(&vol64, old64, new64), 1);
test_verify_int(vol64, new64);
vol64 = 42, old64 = 420, new64 = 50;
test_verify_int(ompi_atomic_cmpset_rel_64(&vol64, old64, new64), 0);
test_verify_int(vol64, 42);
}
#endif
/* -- cmpset int tests -- */
volint = 42, oldint = 42, newint = 50;
test_verify_int(ompi_atomic_cmpset(&volint, oldint, newint), 1);
test_verify_int(volint, newint);
volint = 42, oldint = 420, newint = 50;
test_verify_int(ompi_atomic_cmpset(&volint, oldint, newint), 0);
test_verify_int(volint, 42);
volint = 42, oldint = 42, newint = 50;
test_verify_int(ompi_atomic_cmpset_acq(&volint, oldint, newint), 1);
test_verify_int(volint, newint);
volint = 42, oldint = 420, newint = 50;
test_verify_int(ompi_atomic_cmpset_acq(&volint, oldint, newint), 0);
test_verify_int(volint, 42);
volint = 42, oldint = 42, newint = 50;
test_verify_int(ompi_atomic_cmpset_rel(&volint, oldint, newint), 1);
test_verify_int(volint, newint);
volint = 42, oldint = 420, newint = 50;
test_verify_int(ompi_atomic_cmpset_rel(&volint, oldint, newint), 0);
test_verify_int(volint, 42);
/* -- cmpset ptr tests -- */
volptr = (void *) 42, oldptr = (void *) 42, newptr = (void *) 50;
test_verify_int(ompi_atomic_cmpset(&volptr, oldptr, newptr), 1);
test_verify_int(volptr, newptr);
volptr = (void *) 42, oldptr = (void *) 420, newptr = (void *) 50;
test_verify_int(ompi_atomic_cmpset(&volptr, oldptr, newptr), 0);
test_verify_int(volptr, (void *) 42);
volptr = (void *) 42, oldptr = (void *) 42, newptr = (void *) 50;
test_verify_int(ompi_atomic_cmpset_acq(&volptr, oldptr, newptr), 1);
test_verify_int(volptr, newptr);
volptr = (void *) 42, oldptr = (void *) 420, newptr = (void *) 50;
test_verify_int(ompi_atomic_cmpset_acq(&volptr, oldptr, newptr), 0);
test_verify_int(volptr, (void *) 42);
volptr = (void *) 42, oldptr = (void *) 42, newptr = (void *) 50;
test_verify_int(ompi_atomic_cmpset_rel(&volptr, oldptr, newptr), 1);
test_verify_int(volptr, newptr);
volptr = (void *) 42, oldptr = (void *) 420, newptr = (void *) 50;
test_verify_int(ompi_atomic_cmpset_rel(&volptr, oldptr, newptr), 0);
test_verify_int(volptr, (void *) 42);
/* -- add_32 tests -- */
val32 = 42;
test_verify_int(ompi_atomic_add_32(&val32, 5), (42 + 5));
test_verify_int((42 + 5), val32);
/* -- add_64 tests -- */
#ifdef ENABLE_64_BIT
if (enable_64_bit_tests) {
val64 = 42;
test_verify_int(ompi_atomic_add_64(&val64, 5), (42 + 5));
test_verify_int((42 + 5), val64);
}
#endif
/* -- add_int tests -- */
valint = 42;
ompi_atomic_add(&valint, 5);
test_verify_int((42 + 5), valint);
/* threaded tests */
val32 = 0;
#ifdef ENABLE_64_BIT
val64 = 0ul;
#endif
valint = 0;
/* -- create the thread set -- */
th = (pthread_t *) malloc(nthreads * sizeof(pthread_t));
if (!th) {
perror("malloc");
exit(EXIT_FAILURE);
}
for (tid = 0; tid < nthreads; tid++) {
if (pthread_create(&th[tid], NULL, thread_main, (void *) tid) != 0) {
perror("pthread_create");
exit(EXIT_FAILURE);
}
}
/* -- wait for the thread set to finish -- */
for (tid = 0; tid < nthreads; tid++) {
void *thread_return;
if (pthread_join(th[tid], &thread_return) != 0) {
perror("pthread_join");
exit(EXIT_FAILURE);
}
verbose("main: thread %d returned %d\n", tid, (int) thread_return);
}
free(th);
test_verify_int((5 * nthreads * nreps), val32);
#ifdef ENABLE_64_BIT
if (enable_64_bit_tests) {
test_verify_int((5 * nthreads * nreps), val64);
}
#endif
test_verify_int((5 * nthreads * nreps), valint);
test_finalize();
return 0;
}

73
src/asm/base/AMD64.asm Normal file
View File

@ -0,0 +1,73 @@
TEXT
START_FUNC(ompi_atomic_mb)
pushq %rbp
movq %rsp, %rbp
leave
ret
END_FUNC(ompi_atomic_mb)
START_FUNC(ompi_atomic_rmb)
pushq %rbp
movq %rsp, %rbp
leave
ret
END_FUNC(ompi_atomic_rmb)
START_FUNC(ompi_atomic_wmb)
pushq %rbp
movq %rsp, %rbp
leave
ret
END_FUNC(ompi_atomic_wmb)
START_FUNC(ompi_atomic_cmpset_32)
pushq %rbp
movq %rsp, %rbp
movq %rdi, -8(%rbp)
movl %esi, -12(%rbp)
movl %edx, -16(%rbp)
movl -16(%rbp), %ecx
movq -8(%rbp), %rdx
movl -12(%rbp), %eax
#APP
cmpxchgl %ecx,(%rdx)
#NO_APP
movq %rax, -24(%rbp)
movl -24(%rbp), %eax
movl %eax, -28(%rbp)
movl -28(%rbp), %eax
cmpl -12(%rbp), %eax
sete %al
movzbl %al, %eax
movl %eax, -28(%rbp)
movl -28(%rbp), %eax
leave
ret
END_FUNC(ompi_atomic_cmpset_32)
START_FUNC(ompi_atomic_cmpset_64)
pushq %rbp
movq %rsp, %rbp
movq %rdi, -8(%rbp)
movq %rsi, -16(%rbp)
movq %rdx, -24(%rbp)
movq -24(%rbp), %rcx
movq -8(%rbp), %rdx
movq -16(%rbp), %rax
#APP
cmpxchgq %rcx,(%rdx)
#NO_APP
movq %rax, -32(%rbp)
movq -32(%rbp), %rax
cmpq -16(%rbp), %rax
sete %al
movzbl %al, %eax
leave
ret
END_FUNC(ompi_atomic_cmpset_64)

108
src/asm/base/IA32.asm Normal file
View File

@ -0,0 +1,108 @@
TEXT
START_FUNC(ompi_atomic_mb)
pushl %ebp
movl %esp, %ebp
leave
ret
END_FUNC(ompi_atomic_mb)
START_FUNC(ompi_atomic_rmb)
pushl %ebp
movl %esp, %ebp
leave
ret
END_FUNC(ompi_atomic_rmb)
START_FUNC(ompi_atomic_wmb)
pushl %ebp
movl %esp, %ebp
leave
ret
END_FUNC(ompi_atomic_wmb)
START_FUNC(ompi_atomic_cmpset_32)
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
movl 16(%ebp), %ecx
movl 12(%ebp), %eax
#APP
lock cmpxchgl %ecx,(%edx)
sete %dl
#NO_APP
movzbl %dl, %eax
leave
ret
END_FUNC(ompi_atomic_cmpset_32)
START_FUNC(ompi_atomic_cmpset_64)
pushl %ebp
movl %esp, %ebp
subl $32, %esp
movl %ebx, -12(%ebp)
movl %esi, -8(%ebp)
movl %edi, -4(%ebp)
movl 8(%ebp), %edi
movl 12(%ebp), %eax
movl 16(%ebp), %edx
movl %eax, -24(%ebp)
movl %edx, -20(%ebp)
movl 20(%ebp), %eax
movl 24(%ebp), %edx
movl %eax, -32(%ebp)
movl %edx, -28(%ebp)
movl -24(%ebp), %ebx
movl -20(%ebp), %edx
movl -32(%ebp), %esi
movl -28(%ebp), %ecx
movl %ebx, %eax
#APP
push %ebx
movl %esi, %ebx
lock cmpxchg8b (%edi)
sete %dl
pop %ebx
#NO_APP
movzbl %dl, %eax
movl -12(%ebp), %ebx
movl -8(%ebp), %esi
movl -4(%ebp), %edi
movl %ebp, %esp
popl %ebp
ret
END_FUNC(ompi_atomic_cmpset_64)
START_FUNC(ompi_atomic_add_32)
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movl 12(%ebp), %edx
#APP
lock addl %edx,(%eax)
#NO_APP
movl (%eax), %eax
leave
ret
END_FUNC(ompi_atomic_add_32)
START_FUNC(ompi_atomic_sub_32)
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movl 12(%ebp), %edx
#APP
lock subl %edx,(%eax)
#NO_APP
movl (%eax), %eax
leave
ret
END_FUNC(ompi_atomic_sub_32)

143
src/asm/base/POWERPC32.asm Normal file
View File

@ -0,0 +1,143 @@
TEXT
ALIGN(4)
START_FUNC(ompi_atomic_mb)
sync
blr
END_FUNC(ompi_atomic_mb)
START_FUNC(ompi_atomic_rmb)
lwsync
blr
END_FUNC(ompi_atomic_rmb)
START_FUNC(ompi_atomic_wmb)
eieio
blr
END_FUNC(ompi_atomic_wmb)
START_FUNC(ompi_atomic_cmpset_32)
1: lwarx r0, 0, r3
cmpw 0, r0, r4
bne- 2f
stwcx. r5, 0, r3
bne- 1b
sync
2:
xor r3,r0,r4