1dnl
2dnl Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
3dnl                         University Research and Technology
4dnl                         Corporation.  All rights reserved.
5dnl Copyright (c) 2004-2018 The University of Tennessee and The University
6dnl                         of Tennessee Research Foundation.  All rights
7dnl                         reserved.
8dnl Copyright (c) 2004-2006 High Performance Computing Center Stuttgart,
9dnl                         University of Stuttgart.  All rights reserved.
10dnl Copyright (c) 2004-2005 The Regents of the University of California.
11dnl                         All rights reserved.
12dnl Copyright (c) 2008-2018 Cisco Systems, Inc.  All rights reserved.
13dnl Copyright (c) 2010      Oracle and/or its affiliates.  All rights reserved.
14dnl Copyright (c) 2015-2018 Research Organization for Information Science
15dnl                         and Technology (RIST).  All rights reserved.
16dnl Copyright (c) 2014-2018 Los Alamos National Security, LLC. All rights
17dnl                         reserved.
18dnl Copyright (c) 2017      Amazon.com, Inc. or its affiliates.  All Rights
19dnl                         reserved.
20dnl Copyright (c) 2020      Google, LLC. All rights reserved.
21dnl Copyright (c) 2020      Intel, Inc.  All rights reserved.
22dnl $COPYRIGHT$
23dnl
24dnl Additional copyrights may follow
25dnl
26dnl $HEADER$
27dnl
28
29dnl This is a C test to see if 128-bit __atomic_compare_exchange_n()
30dnl actually works (e.g., it compiles and links successfully on
31dnl ARM64+clang, but returns incorrect answers as of August 2018).
32AC_DEFUN([PMIX_ATOMIC_COMPARE_EXCHANGE_N_TEST_SOURCE],[[
33#include <stdint.h>
34#include <stdbool.h>
35#include <stdlib.h>
36typedef union {
37    uint64_t fake@<:@2@:>@;
38    __int128 real;
39} pmix128;
40static void test1(void)
41{
42    // As of Aug 2018, we could not figure out a way to assign 128-bit
43    // constants -- the compilers would not accept it.  So use a fake
44    // union to assign 2 uin64_t's to make a single __int128.
45    pmix128 ptr      = { .fake = { 0xFFEEDDCCBBAA0099, 0x8877665544332211 }};
46    pmix128 expected = { .fake = { 0x11EEDDCCBBAA0099, 0x88776655443322FF }};
47    pmix128 desired  = { .fake = { 0x1122DDCCBBAA0099, 0x887766554433EEFF }};
48    bool r = __atomic_compare_exchange_n(&ptr.real, &expected.real,
49                                         desired.real, true,
50                                         __ATOMIC_RELAXED, __ATOMIC_RELAXED);
51    if ( !(r == false && ptr.real == expected.real)) {
52        exit(1);
53    }
54}
55static void test2(void)
56{
57    pmix128 ptr =      { .fake = { 0xFFEEDDCCBBAA0099, 0x8877665544332211 }};
58    pmix128 expected = ptr;
59    pmix128 desired =  { .fake = { 0x1122DDCCBBAA0099, 0x887766554433EEFF }};
60    bool r = __atomic_compare_exchange_n(&ptr.real, &expected.real,
61                                         desired.real, true,
62                                         __ATOMIC_RELAXED, __ATOMIC_RELAXED);
63    if (!(r == true && ptr.real == desired.real)) {
64        exit(2);
65    }
66}
67int main(int argc, char** argv)
68{
69    test1();
70    test2();
71    return 0;
72}
73]])
74
75dnl ------------------------------------------------------------------
76
77dnl This is a C test to see if 128-bit __sync_bool_compare_and_swap()
78dnl actually works (e.g., it compiles and links successfully on
79dnl ARM64+clang, but returns incorrect answers as of August 2018).
80AC_DEFUN([PMIX_SYNC_BOOL_COMPARE_AND_SWAP_TEST_SOURCE],[[
81#include <stdint.h>
82#include <stdbool.h>
83#include <stdlib.h>
84typedef union {
85    uint64_t fake@<:@2@:>@;
86    __int128 real;
87} pmix128;
88static void test1(void)
89{
90    // As of Aug 2018, we could not figure out a way to assign 128-bit
91    // constants -- the compilers would not accept it.  So use a fake
92    // union to assign 2 uin64_t's to make a single __int128.
93    pmix128 ptr    = { .fake = { 0xFFEEDDCCBBAA0099, 0x8877665544332211 }};
94    pmix128 oldval = { .fake = { 0x11EEDDCCBBAA0099, 0x88776655443322FF }};
95    pmix128 newval = { .fake = { 0x1122DDCCBBAA0099, 0x887766554433EEFF }};
96    bool r = __sync_bool_compare_and_swap(&ptr.real, oldval.real, newval.real);
97    if (!(r == false && ptr.real != newval.real)) {
98        exit(1);
99    }
100}
101static void test2(void)
102{
103    pmix128 ptr    = { .fake = { 0xFFEEDDCCBBAA0099, 0x8877665544332211 }};
104    pmix128 oldval = ptr;
105    pmix128 newval = { .fake = { 0x1122DDCCBBAA0099, 0x887766554433EEFF }};
106    bool r = __sync_bool_compare_and_swap(&ptr.real, oldval.real, newval.real);
107    if (!(r == true && ptr.real == newval.real)) {
108        exit(2);
109    }
110}
111int main(int argc, char** argv)
112{
113    test1();
114    test2();
115    return 0;
116}
117]])
118
119dnl This is a C test to see if 128-bit __atomic_compare_exchange_n()
120dnl actually works (e.g., it compiles and links successfully on
121dnl ARM64+clang, but returns incorrect answers as of August 2018).
122AC_DEFUN([PMIX_ATOMIC_COMPARE_EXCHANGE_STRONG_TEST_SOURCE],[[
123#include <stdint.h>
124#include <stdbool.h>
125#include <stdlib.h>
126#include <stdatomic.h>
127typedef union {
128    uint64_t fake@<:@2@:>@;
129    _Atomic __int128 real;
130    __int128 real2;
131} pmix128;
132static void test1(void)
133{
134    // As of Aug 2018, we could not figure out a way to assign 128-bit
135    // constants -- the compilers would not accept it.  So use a fake
136    // union to assign 2 uin64_t's to make a single __int128.
137    pmix128 ptr      = { .fake = { 0xFFEEDDCCBBAA0099, 0x8877665544332211 }};
138    pmix128 expected = { .fake = { 0x11EEDDCCBBAA0099, 0x88776655443322FF }};
139    pmix128 desired  = { .fake = { 0x1122DDCCBBAA0099, 0x887766554433EEFF }};
140    bool r = atomic_compare_exchange_strong (&ptr.real, &expected.real2,
141                                             desired.real);
142    if ( !(r == false && ptr.real == expected.real)) {
143        exit(1);
144    }
145}
146static void test2(void)
147{
148    pmix128 ptr =      { .fake = { 0xFFEEDDCCBBAA0099, 0x8877665544332211 }};
149    pmix128 expected = ptr;
150    pmix128 desired =  { .fake = { 0x1122DDCCBBAA0099, 0x887766554433EEFF }};
151    bool r = atomic_compare_exchange_strong (&ptr.real, &expected.real2,
152                                             desired.real);
153    if (!(r == true && ptr.real == desired.real)) {
154        exit(2);
155    }
156}
157int main(int argc, char** argv)
158{
159    test1();
160    test2();
161    return 0;
162}
163]])
164
165dnl ------------------------------------------------------------------
166
167dnl
168dnl Check to see if a specific function is linkable.
169dnl
170dnl Check with:
171dnl 1. No compiler/linker flags.
172dnl 2. CFLAGS += -mcx16
173dnl 3. LIBS += -latomic
174dnl 4. Finally, if it links ok with any of #1, #2, or #3, actually try
175dnl to run the test code (if we're not cross-compiling) and verify
176dnl that it actually gives us the correct result.
177dnl
178dnl Note that we unfortunately can't use AC SEARCH_LIBS because its
179dnl check incorrectly fails (because these functions are special compiler
180dnl intrinsics -- SEARCH_LIBS tries with "check FUNC()", which the
181dnl compiler complains doesn't match the internal prototype).  So we have
182dnl to use our own LINK_IFELSE tests.  Indeed, since these functions are
183dnl so special, we actually need a valid source code that calls the
184dnl functions with correct arguments, etc.  It's not enough, for example,
185dnl to do the usual "try to set a function pointer to the symbol" trick to
186dnl determine if these functions are available, because the compiler may
187dnl not implement these as actual symbols.  So just try to link a real
188dnl test code.
189dnl
190dnl $1: function name to print
191dnl $2: program to test
192dnl $3: action if any of 1, 2, or 3 succeeds
193dnl #4: action if all of 1, 2, and 3 fail
194dnl
195AC_DEFUN([PMIX_ASM_CHECK_ATOMIC_FUNC],[
196    PMIX_VAR_SCOPE_PUSH([pmix_asm_check_func_happy pmix_asm_check_func_CFLAGS_save pmix_asm_check_func_LIBS_save])
197    pmix_asm_check_func_CFLAGS_save=$CFLAGS
198    pmix_asm_check_func_LIBS_save=$LIBS
199    dnl Check with no compiler/linker flags
200    AC_MSG_CHECKING([for $1])
201    AC_LINK_IFELSE([$2],
202        [pmix_asm_check_func_happy=1
203         AC_MSG_RESULT([yes])],
204        [pmix_asm_check_func_happy=0
205         AC_MSG_RESULT([no])])
206    dnl If that didn't work, try again with CFLAGS+=mcx16
207    AS_IF([test $pmix_asm_check_func_happy -eq 0],
208        [AC_MSG_CHECKING([for $1 with -mcx16])
209         CFLAGS="$CFLAGS -mcx16"
210         AC_LINK_IFELSE([$2],
211             [pmix_asm_check_func_happy=1
212              AC_MSG_RESULT([yes])],
213             [pmix_asm_check_func_happy=0
214              CFLAGS=$pmix_asm_check_func_CFLAGS_save
215              AC_MSG_RESULT([no])])
216         ])
217    dnl If that didn't work, try again with LIBS+=-latomic
218    AS_IF([test $pmix_asm_check_func_happy -eq 0],
219        [AC_MSG_CHECKING([for $1 with -latomic])
220         LIBS="$LIBS -latomic"
221         AC_LINK_IFELSE([$2],
222             [pmix_asm_check_func_happy=1
223              AC_MSG_RESULT([yes])],
224             [pmix_asm_check_func_happy=0
225              LIBS=$pmix_asm_check_func_LIBS_save
226              AC_MSG_RESULT([no])])
227         ])
228    dnl If we have it, try it and make sure it gives a correct result.
229    dnl As of Aug 2018, we know that it links but does *not* work on clang
230    dnl 6 on ARM64.
231    AS_IF([test $pmix_asm_check_func_happy -eq 1],
232        [AC_MSG_CHECKING([if $1() gives correct results])
233         AC_RUN_IFELSE([$2],
234              [AC_MSG_RESULT([yes])],
235              [pmix_asm_check_func_happy=0
236               AC_MSG_RESULT([no])],
237              [AC_MSG_RESULT([cannot test -- assume yes (cross compiling)])])
238         ])
239    dnl If we were unsuccessful, restore CFLAGS/LIBS
240    AS_IF([test $pmix_asm_check_func_happy -eq 0],
241        [CFLAGS=$pmix_asm_check_func_CFLAGS_save
242         LIBS=$pmix_asm_check_func_LIBS_save])
243    dnl Run the user actions
244    AS_IF([test $pmix_asm_check_func_happy -eq 1], [$3], [$4])
245    PMIX_VAR_SCOPE_POP
246])
247
248dnl ------------------------------------------------------------------
249
250AC_DEFUN([PMIX_CHECK_SYNC_BUILTIN_CSWAP_INT128], [
251  PMIX_VAR_SCOPE_PUSH([sync_bool_compare_and_swap_128_result])
252  # Do we have __sync_bool_compare_and_swap?
253  # Use a special macro because we need to check with a few different
254  # CFLAGS/LIBS.
255  PMIX_ASM_CHECK_ATOMIC_FUNC([__sync_bool_compare_and_swap],
256      [AC_LANG_SOURCE(PMIX_SYNC_BOOL_COMPARE_AND_SWAP_TEST_SOURCE)],
257      [sync_bool_compare_and_swap_128_result=1],
258      [sync_bool_compare_and_swap_128_result=0])
259  AC_DEFINE_UNQUOTED([PMIX_HAVE_SYNC_BUILTIN_CSWAP_INT128],
260        [$sync_bool_compare_and_swap_128_result],
261        [Whether the __sync builtin atomic compare and swap supports 128-bit values])
262  PMIX_VAR_SCOPE_POP
263])
264
265AC_DEFUN([PMIX_CHECK_GCC_BUILTIN_CSWAP_INT128], [
266  PMIX_VAR_SCOPE_PUSH([atomic_compare_exchange_n_128_result atomic_compare_exchange_n_128_CFLAGS_save atomic_compare_exchange_n_128_LIBS_save])
267  atomic_compare_exchange_n_128_CFLAGS_save=$CFLAGS
268  atomic_compare_exchange_n_128_LIBS_save=$LIBS
269  # Do we have __sync_bool_compare_and_swap?
270  # Use a special macro because we need to check with a few different
271  # CFLAGS/LIBS.
272  PMIX_ASM_CHECK_ATOMIC_FUNC([__atomic_compare_exchange_n],
273      [AC_LANG_SOURCE(PMIX_ATOMIC_COMPARE_EXCHANGE_N_TEST_SOURCE)],
274      [atomic_compare_exchange_n_128_result=1],
275      [atomic_compare_exchange_n_128_result=0])
276  # If we have it and it works, check to make sure it is always lock
277  # free.
278  AS_IF([test $atomic_compare_exchange_n_128_result -eq 1],
279        [AC_MSG_CHECKING([if __int128 atomic compare-and-swap is always lock-free])
280         AC_RUN_IFELSE([AC_LANG_PROGRAM([], [if (!__atomic_always_lock_free(16, 0)) { return 1; }])],
281              [AC_MSG_RESULT([yes])],
282              [atomic_compare_exchange_n_128_result=0
283               # If this test fails, need to reset CFLAGS/LIBS (the
284               # above tests atomically set CFLAGS/LIBS or not; this
285               # test is running after the fact, so we have to undo
286               # the side-effects of setting CFLAGS/LIBS if the above
287               # tests passed).
288               CFLAGS=$atomic_compare_exchange_n_128_CFLAGS_save
289               LIBS=$atomic_compare_exchange_n_128_LIBS_save
290               AC_MSG_RESULT([no])],
291              [AC_MSG_RESULT([cannot test -- assume yes (cross compiling)])])
292        ])
293  AC_DEFINE_UNQUOTED([PMIX_HAVE_GCC_BUILTIN_CSWAP_INT128],
294        [$atomic_compare_exchange_n_128_result],
295        [Whether the __atomic builtin atomic compare swap is both supported and lock-free on 128-bit values])
296  dnl If we could not find decent support for 128-bits __atomic let's
297  dnl try the GCC _sync
298  AS_IF([test $atomic_compare_exchange_n_128_result -eq 0],
299      [PMIX_CHECK_SYNC_BUILTIN_CSWAP_INT128])
300  PMIX_VAR_SCOPE_POP
301])
302
303AC_DEFUN([PMIX_CHECK_GCC_ATOMIC_BUILTINS], [
304  if test -z "$pmix_cv_have___atomic" ; then
305    AC_MSG_CHECKING([for 32-bit GCC built-in atomics])
306    AC_TRY_LINK([
307#include <stdint.h>
308uint32_t tmp, old = 0;
309uint64_t tmp64, old64 = 0;], [
310__atomic_thread_fence(__ATOMIC_SEQ_CST);
311__atomic_compare_exchange_n(&tmp, &old, 1, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
312__atomic_add_fetch(&tmp, 1, __ATOMIC_RELAXED);
313__atomic_compare_exchange_n(&tmp64, &old64, 1, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
314__atomic_add_fetch(&tmp64, 1, __ATOMIC_RELAXED);],
315        [pmix_cv_have___atomic=yes],
316        [pmix_cv_have___atomic=no])
317    AC_MSG_RESULT([$pmix_cv_have___atomic])
318    if test $pmix_cv_have___atomic = "yes" ; then
319    AC_MSG_CHECKING([for 64-bit GCC built-in atomics])
320    AC_TRY_LINK([
321#include <stdint.h>
322uint64_t tmp64, old64 = 0;], [
323__atomic_compare_exchange_n(&tmp64, &old64, 1, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
324__atomic_add_fetch(&tmp64, 1, __ATOMIC_RELAXED);],
325            [pmix_cv_have___atomic_64=yes],
326            [pmix_cv_have___atomic_64=no])
327    AC_MSG_RESULT([$pmix_cv_have___atomic_64])
328    if test $pmix_cv_have___atomic_64 = "yes" ; then
329        AC_MSG_CHECKING([if 64-bit GCC built-in atomics are lock-free])
330        AC_RUN_IFELSE([AC_LANG_PROGRAM([], [if (!__atomic_is_lock_free (8, 0)) { return 1; }])],
331              [AC_MSG_RESULT([yes])],
332              [AC_MSG_RESULT([no])
333               pmix_cv_have___atomic_64=no],
334              [AC_MSG_RESULT([cannot test -- assume yes (cross compiling)])])
335    fi
336    else
337    pmix_cv_have___atomic_64=no
338    fi
339    # Check for 128-bit support
340    PMIX_CHECK_GCC_BUILTIN_CSWAP_INT128
341  fi
342])
343
344AC_DEFUN([PMIX_CHECK_C11_CSWAP_INT128], [
345  PMIX_VAR_SCOPE_PUSH([atomic_compare_exchange_result atomic_compare_exchange_CFLAGS_save atomic_compare_exchange_LIBS_save])
346  atomic_compare_exchange_CFLAGS_save=$CFLAGS
347  atomic_compare_exchange_LIBS_save=$LIBS
348  # Do we have C11 atomics on 128-bit integers?
349  # Use a special macro because we need to check with a few different
350  # CFLAGS/LIBS.
351  PMIX_ASM_CHECK_ATOMIC_FUNC([atomic_compare_exchange_strong_16],
352      [AC_LANG_SOURCE(PMIX_ATOMIC_COMPARE_EXCHANGE_STRONG_TEST_SOURCE)],
353      [atomic_compare_exchange_result=1],
354      [atomic_compare_exchange_result=0])
355  # If we have it and it works, check to make sure it is always lock
356  # free.
357  AS_IF([test $atomic_compare_exchange_result -eq 1],
358        [AC_MSG_CHECKING([if C11 __int128 atomic compare-and-swap is always lock-free])
359         AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdatomic.h>], [_Atomic __int128_t x; if (!atomic_is_lock_free(&x)) { return 1; }])],
360              [AC_MSG_RESULT([yes])],
361              [atomic_compare_exchange_result=0
362               # If this test fails, need to reset CFLAGS/LIBS (the
363               # above tests atomically set CFLAGS/LIBS or not; this
364               # test is running after the fact, so we have to undo
365               # the side-effects of setting CFLAGS/LIBS if the above
366               # tests passed).
367               CFLAGS=$atomic_compare_exchange_CFLAGS_save
368               LIBS=$atomic_compare_exchange_LIBS_save
369               AC_MSG_RESULT([no])],
370              [AC_MSG_RESULT([cannot test -- assume yes (cross compiling)])])
371        ])
372  AC_DEFINE_UNQUOTED([PMIX_HAVE_C11_CSWAP_INT128],
373        [$atomic_compare_exchange_result],
374        [Whether C11 atomic compare swap is both supported and lock-free on 128-bit values])
375  dnl If we could not find decent support for 128-bits atomic let's
376  dnl try the GCC _sync
377  AS_IF([test $atomic_compare_exchange_result -eq 0],
378      [PMIX_CHECK_SYNC_BUILTIN_CSWAP_INT128])
379  PMIX_VAR_SCOPE_POP
380])
381
382dnl #################################################################
383dnl
384dnl PMIX_CHECK_ASM_TEXT
385dnl
386dnl Determine how to set current mode as text.
387dnl
388dnl #################################################################
389AC_DEFUN([PMIX_CHECK_ASM_TEXT],[
390    AC_MSG_CHECKING([directive for setting text section])
391    pmix_cv_asm_text=""
392    if test "$pmix_cv_c_compiler_vendor" = "microsoft" ; then
393        # text section will be brought in with the rest of
394        # header for MS - leave blank for now
395        pmix_cv_asm_text=""
396    else
397        case $host in
398            *-aix*)
399                pmix_cv_asm_text=[".csect .text[PR]"]
400            ;;
401            *)
402                pmix_cv_asm_text=".text"
403            ;;
404        esac
405    fi
406    AC_MSG_RESULT([$pmix_cv_asm_text])
407    AC_DEFINE_UNQUOTED([PMIX_ASM_TEXT], ["$pmix_cv_asm_text"],
408                       [Assembly directive for setting text section])
409    PMIX_ASM_TEXT="$pmix_cv_asm_text"
410    AC_SUBST(PMIX_ASM_TEXT)
411])dnl
412
413
414dnl #################################################################
415dnl
416dnl PMIX_CHECK_ASM_GLOBAL
417dnl
418dnl Sets PMIX_ASM_GLOBAL to the value to prefix global values
419dnl
420dnl I'm sure if I don't have a test for this, there will be some
421dnl dumb platform that uses something else
422dnl
423dnl #################################################################
424AC_DEFUN([PMIX_CHECK_ASM_GLOBAL],[
425    AC_MSG_CHECKING([directive for exporting symbols])
426    pmix_cv_asm_global=""
427    if test "$pmix_cv_c_compiler_vendor" = "microsoft" ; then
428        pmix_cv_asm_global="PUBLIC"
429    else
430        case $host in
431            *)
432                pmix_cv_asm_global=".globl"
433            ;;
434        esac
435    fi
436    AC_MSG_RESULT([$pmix_cv_asm_global])
437    AC_DEFINE_UNQUOTED([PMIX_ASM_GLOBAL], ["$pmix_cv_asm_global"],
438                       [Assembly directive for exporting symbols])
439    PMIX_ASM_GLOBAL="$pmix_cv_asm_global"
440    AC_SUBST(PMIX_AS_GLOBAL)
441])dnl
442
443
444dnl #################################################################
445dnl
446dnl PMIX_CHECK_ASM_LSYM
447dnl
448dnl Sets PMIX_ASM_LSYM to the prefix value on a symbol to make it
449dnl an internal label (jump target and whatnot)
450dnl
451dnl We look for L .L $ L$ (in that order) for something that both
452dnl assembles and does not leave a label in the output of nm.  Fall
453dnl back to L if nothing else seems to work :/
454dnl
455dnl #################################################################
456
457# _PMIX_CHECK_ASM_LSYM([variable-to-set])
458# ---------------------------------------
459AC_DEFUN([_PMIX_CHECK_ASM_LSYM],[
460    AC_REQUIRE([AC_PROG_GREP])
461    $1="L"
462    for sym in L .L $ L$ ; do
463        asm_result=0
464        echo "configure: trying $sym" >&AC_FD_CC
465        PMIX_TRY_ASSEMBLE([foobar$pmix_cv_asm_label_suffix
466${sym}mytestlabel$pmix_cv_asm_label_suffix],
467            [# ok, we succeeded at assembling.  see if we can nm,
468             # throwing the results in a file
469            if $NM conftest.$OBJEXT > conftest.out 2>&AC_FD_CC ; then
470                if test "`$GREP mytestlabel conftest.out`" = "" ; then
471                    # there was no symbol...  looks promising to me
472                    $1="$sym"
473                    asm_result=1
474                elif test ["`$GREP ' [Nt] .*mytestlabel' conftest.out`"] = "" ; then
475                    # see if we have a non-global-ish symbol
476                    # but we should see if we can do better.
477                    $1="$sym"
478                fi
479            else
480                # not so much on the NM goodness :/
481                echo "$NM failed.  Output from NM was:" >&AC_FD_CC
482                cat conftest.out >&AC_FD_CC
483                AC_MSG_WARN([$NM could not read object file])
484            fi
485            ])
486        if test "$asm_result" = "1" ; then
487            break
488        fi
489    done
490    rm -f conftest.out
491    unset asm_result sym
492])
493
494# PMIX_CHECK_ASM_LSYM()
495# ---------------------
496AC_DEFUN([PMIX_CHECK_ASM_LSYM],[
497    AC_REQUIRE([AC_PROG_NM])
498    AC_CACHE_CHECK([prefix for lsym labels],
499                   [pmix_cv_asm_lsym],
500                   [_PMIX_CHECK_ASM_LSYM([pmix_cv_asm_lsym])])
501    AC_DEFINE_UNQUOTED([PMIX_ASM_LSYM], ["$pmix_cv_asm_lsym"],
502                       [Assembly prefix for lsym labels])
503    PMIX_ASM_LSYM="$pmix_cv_asm_lsym"
504    AC_SUBST(PMIX_ASM_LSYM)
505])dnl
506
507dnl #################################################################
508dnl
509dnl PMIX_CHECK_ASM_PROC
510dnl
511dnl Sets a cv-flag, if the compiler needs a proc/endp-definition to
512dnl link with C.
513dnl
514dnl #################################################################
515AC_DEFUN([PMIX_CHECK_ASM_PROC],[
516    AC_CACHE_CHECK([if .proc/endp is needed],
517                   [pmix_cv_asm_need_proc],
518                   [pmix_cv_asm_need_proc="no"
519                    PMIX_TRY_ASSEMBLE([
520     .proc mysym
521mysym:
522     .endp mysym],
523                          [pmix_cv_asm_need_proc="yes"])
524                    rm -f conftest.out])
525    if test "$pmix_cv_asm_need_proc" = "yes" ; then
526       pmix_cv_asm_proc=".proc"
527       pmix_cv_asm_endproc=".endp"
528    else
529       pmix_cv_asm_proc="#"
530       pmix_cv_asm_endproc="#"
531    fi
532])dnl
533
534
535dnl #################################################################
536dnl
537dnl PMIX_CHECK_ASM_GSYM
538dnl
539dnl Sets PMIX_ASM_GSYM to the prefix value on a symbol to make it
540dnl a global linkable from C.  Basically, an _ or not.
541dnl
542dnl #################################################################
543AC_DEFUN([PMIX_CHECK_ASM_GSYM],[
544    AC_CACHE_CHECK([prefix for global symbol labels],
545                   [pmix_cv_asm_gsym],
546                   [_PMIX_CHECK_ASM_GSYM])
547    if test "$pmix_cv_asm_gsym" = "none" ; then
548       AC_MSG_ERROR([Could not determine global symbol label prefix])
549    fi
550    AC_DEFINE_UNQUOTED([PMIX_ASM_GSYM], ["$pmix_cv_asm_gsym"],
551                       [Assembly prefix for gsym labels])
552    PMIX_ASM_GSYM="$pmix_cv_asm_gsym"
553    AC_SUBST(PMIX_ASM_GSYM)
554])
555
556AC_DEFUN([_PMIX_CHECK_ASM_GSYM],[
557    pmix_cv_asm_gsym="none"
558    for sym in "_" "" "." ; do
559        asm_result=0
560        echo "configure: trying $sym" >&AC_FD_CC
561cat > conftest_c.c <<EOF
562#ifdef __cplusplus
563extern "C" {
564#endif
565void gsym_test_func(void);
566#ifdef __cplusplus
567}
568#endif
569int
570main()
571{
572    gsym_test_func();
573    return 0;
574}
575EOF
576        PMIX_TRY_ASSEMBLE([
577$pmix_cv_asm_text
578$pmix_cv_asm_proc ${sym}gsym_test_func
579$pmix_cv_asm_global ${sym}gsym_test_func
580${sym}gsym_test_func${pmix_cv_asm_label_suffix}
581$pmix_cv_asm_endproc ${sym}gsym_test_func
582            ],
583            [pmix_compile="$CC $CFLAGS -I. conftest_c.c -c > conftest.cmpl 2>&1"
584             if AC_TRY_EVAL(pmix_compile) ; then
585                # save the warnings
586                 cat conftest.cmpl >&AC_FD_CC
587                 pmix_link="$CC $CFLAGS conftest_c.$OBJEXT conftest.$OBJEXT -o conftest  $LDFLAGS $LIBS > conftest.link 2>&1"
588                 if AC_TRY_EVAL(pmix_link) ; then
589                     # save the warnings
590                     cat conftest.link >&AC_FD_CC
591                     asm_result=1
592                 else
593                     cat conftest.link >&AC_FD_CC
594                     echo "configure: failed C program was: " >&AC_FD_CC
595                     cat conftest_c.c >&AC_FD_CC
596                     echo "configure: failed ASM program was: " >&AC_FD_CC
597                     cat conftest.s >&AC_FD_CC
598                     asm_result=0
599                 fi
600             else
601                # save output and failed program
602                 cat conftest.cmpl >&AC_FD_CC
603                 echo "configure: failed C program was: " >&AC_FD_CC
604                 cat conftest.c >&AC_FD_CC
605                 asm_result=0
606             fi],
607            [asm_result=0])
608        if test "$asm_result" = "1" ; then
609            pmix_cv_asm_gsym="$sym"
610            break
611        fi
612    done
613    rm -rf conftest.*
614])dnl
615
616
617dnl #################################################################
618dnl
619dnl PMIX_CHECK_ASM_LABEL_SUFFIX
620dnl
621dnl Sets PMIX_ASM_LABEL_SUFFIX to the value to suffix for labels
622dnl
623dnl I'm sure if I don't have a test for this, there will be some
624dnl dumb platform that uses something else
625dnl
626dnl #################################################################
627AC_DEFUN([PMIX_CHECK_ASM_LABEL_SUFFIX],[
628    AC_MSG_CHECKING([suffix for labels])
629    pmix_cv_asm_label_suffix=""
630    case $host in
631        *)
632                pmix_cv_asm_label_suffix=":"
633        ;;
634    esac
635    AC_MSG_RESULT([$pmix_cv_asm_label_suffix])
636    AC_DEFINE_UNQUOTED([PMIX_ASM_LABEL_SUFFIX], ["$pmix_cv_asm_label_suffix"],
637                       [Assembly suffix for labels])
638    PMIX_ASM_LABEL_SUFFIX="$pmix_cv_asm_label_suffix"
639    AC_SUBST(PMIX_AS_LABEL_SUFFIX)
640])dnl
641
642
643dnl #################################################################
644dnl
645dnl PMIX_CHECK_ASM_ALIGN_LOG
646dnl
647dnl Sets PMIX_ASM_ALIGN_LOG to 1 if align is specified
648dnl logarithmically, 0 otherwise
649dnl
650dnl #################################################################
651AC_DEFUN([PMIX_CHECK_ASM_ALIGN_LOG],[
652    AC_REQUIRE([AC_PROG_NM])
653    AC_REQUIRE([AC_PROG_GREP])
654    AC_CACHE_CHECK([if .align directive takes logarithmic value],
655                   [pmix_cv_asm_align_log],
656                   [ PMIX_TRY_ASSEMBLE([        $pmix_cv_asm_text
657        .align 4
658        $pmix_cv_asm_global foo
659        .byte 1
660        .align 4
661foo$pmix_cv_asm_label_suffix
662        .byte 2],
663        [pmix_asm_addr=[`$NM conftest.$OBJEXT | $GREP foo | sed -e 's/.*\([0-9a-fA-F][0-9a-fA-F]\).*foo.*/\1/'`]],
664        [pmix_asm_addr=""])
665    # test for both 16 and 10 (decimal and hex notations)
666    echo "configure: .align test address offset is $pmix_asm_addr" >&AC_FD_CC
667    if test "$pmix_asm_addr" = "16" || test "$pmix_asm_addr" = "10" ; then
668       pmix_cv_asm_align_log="yes"
669    else
670        pmix_cv_asm_align_log="no"
671    fi])
672    if test "$pmix_cv_asm_align_log" = "yes" || test "$pmix_cv_asm_align_log" = "1" ; then
673        pmix_asm_align_log_result=1
674    else
675        pmix_asm_align_log_result=0
676    fi
677    AC_DEFINE_UNQUOTED([PMIX_ASM_ALIGN_LOG],
678                       [$asm_align_log_result],
679                       [Assembly align directive expects logarithmic value])
680    unset omp_asm_addr asm_result
681])dnl
682
683
684dnl #################################################################
685dnl
686dnl PMIX_CHECK_ASM_TYPE
687dnl
688dnl Sets PMIX_ASM_TYPE to the prefix for the function type to
689dnl set a symbol's type as function (needed on ELF for shared
690dnl libraries).  If no .type directive is needed, sets PMIX_ASM_TYPE
691dnl to an empty string
692dnl
693dnl We look for @ \# %
694dnl
695dnl #################################################################
696AC_DEFUN([PMIX_CHECK_ASM_TYPE],[
697        AC_CACHE_CHECK([prefix for function in .type],
698                       [pmix_cv_asm_type],
699                       [_PMIX_CHECK_ASM_TYPE])
700    AC_DEFINE_UNQUOTED([PMIX_ASM_TYPE], ["$pmix_cv_asm_type"],
701                       [How to set function type in .type directive])
702    PMIX_ASM_TYPE="$pmix_cv_asm_type"
703    AC_SUBST(PMIX_ASM_TYPE)
704])
705
706AC_DEFUN([_PMIX_CHECK_ASM_TYPE],[
707    pmix_cv_asm_type=""
708    case "${host}" in
709    *-sun-solaris*)
710        # GCC on solaris seems to accept just about anything, not
711        # that what it defines actually works...  So just hardwire
712        # to the right answer
713        pmix_cv_asm_type="#"
714    ;;
715    *)
716        for type  in @ \# % ; do
717            asm_result=0
718            echo "configure: trying $type" >&AC_FD_CC
719            PMIX_TRY_ASSEMBLE([     .type mysym, ${type}function
720mysym:],
721                 [pmix_cv_asm_type="${type}"
722                    asm_result=1])
723            if test "$asm_result" = "1" ; then
724                break
725            fi
726        done
727    ;;
728    esac
729    rm -f conftest.out
730    unset asm_result type
731])dnl
732
733
734dnl #################################################################
735dnl
736dnl PMIX_CHECK_ASM_SIZE
737dnl
738dnl Sets PMIX_ASM_SIZE to 1 if we should set .size directives for
739dnl each function, 0 otherwise.
740dnl
741dnl #################################################################
742AC_DEFUN([PMIX_CHECK_ASM_SIZE],[
743    AC_CACHE_CHECK([if .size is needed],
744                   [pmix_cv_asm_need_size],
745                   [pmix_cv_asm_need_size="no"
746                    PMIX_TRY_ASSEMBLE([     .size mysym, 1],
747                          [pmix_cv_asm_need_size="yes"])
748                    rm -f conftest.out])
749    if test "$pmix_cv_asm_need_size" = "yes" ; then
750       pmix_asm_size=1
751    else
752       pmix_asm_size=0
753    fi
754    AC_DEFINE_UNQUOTED([PMIX_ASM_SIZE], ["$pmix_asm_size"],
755                       [Do we need to give a .size directive])
756    PMIX_ASM_SIZE="$pmix_asm_size"
757    AC_SUBST(PMIX_ASM_TYPE)
758    unset asm_result
759])dnl
760
761
762# PMIX_CHECK_ASM_GNU_STACKEXEC(var)
763# ----------------------------------
764# sets shell variable var to the things necessary to
765# disable execable stacks with GAS
766AC_DEFUN([PMIX_CHECK_ASM_GNU_STACKEXEC], [
767    AC_REQUIRE([AC_PROG_GREP])
768    AC_CHECK_PROG([OBJDUMP], [objdump], [objdump])
769    AC_CACHE_CHECK([if .note.GNU-stack is needed],
770        [pmix_cv_asm_gnu_stack_result],
771        [AS_IF([test "$OBJDUMP" != ""],
772            [ # first, see if a simple C program has it set
773             cat >conftest.c <<EOF
774int testfunc() {return 0; }
775EOF
776             PMIX_LOG_COMMAND([$CC $CFLAGS -c conftest.c -o conftest.$OBJEXT],
777                 [$OBJDUMP -x conftest.$OBJEXT 2>&1 | $GREP '\.note\.GNU-stack' &> /dev/null && pmix_cv_asm_gnu_stack_result=yes],
778                 [PMIX_LOG_MSG([the failed program was:], 1)
779                  PMIX_LOG_FILE([conftest.c])
780                  pmix_cv_asm_gnu_stack_result=no])
781             if test "$pmix_cv_asm_gnu_stack_result" != "yes" ; then
782                 pmix_cv_asm_gnu_stack_result="no"
783             fi
784             rm -rf conftest.*],
785            [pmix_cv_asm_gnu_stack_result="no"])])
786    if test "$pmix_cv_asm_gnu_stack_result" = "yes" ; then
787        pmix_cv_asm_gnu_stack=1
788    else
789        pmix_cv_asm_gnu_stack=0
790    fi
791])dnl
792
793
794dnl #################################################################
795dnl
796dnl PMIX_CHECK_POWERPC_REG
797dnl
798dnl See if the notation for specifying registers is X (most everyone)
799dnl or rX (OS X)
800dnl
801dnl #################################################################
802AC_DEFUN([PMIX_CHECK_POWERPC_REG],[
803    AC_MSG_CHECKING([if PowerPC registers have r prefix])
804    PMIX_TRY_ASSEMBLE([$pmix_cv_asm_text
805        addi 1,1,0],
806        [pmix_cv_asm_powerpc_r_reg=0],
807        [PMIX_TRY_ASSEMBLE([$pmix_cv_asm_text
808        addi r1,r1,0],
809            [pmix_cv_asm_powerpc_r_reg=1],
810            [AC_MSG_ERROR([Can not determine how to use PPC registers])])])
811    if test "$pmix_cv_asm_powerpc_r_reg" = "1" ; then
812        AC_MSG_RESULT([yes])
813    else
814        AC_MSG_RESULT([no])
815    fi
816    AC_DEFINE_UNQUOTED([PMIX_POWERPC_R_REGISTERS],
817                       [$pmix_cv_asm_powerpc_r_reg],
818                       [Whether r notation is used for ppc registers])
819])dnl
820
821
822dnl #################################################################
823dnl
824dnl PMIX_CHECK_POWERPC_64BIT
825dnl
826dnl On some powerpc chips (the PPC970 or G5), the OS usually runs in
827dnl 32 bit mode, even though the hardware can do 64bit things.  If
828dnl the compiler will let us, emit code for 64bit test and set type
829dnl operations (on a long long).
830dnl
831dnl #################################################################
832AC_DEFUN([PMIX_CHECK_POWERPC_64BIT],[
833    if test "$ac_cv_sizeof_long" != "4" ; then
834        # this function should only be called in the 32 bit case
835        AC_MSG_ERROR([CHECK_POWERPC_64BIT called on 64 bit platform.  Internal error.])
836    fi
837    AC_MSG_CHECKING([for 64-bit PowerPC assembly support])
838        case $host in
839            *-darwin*)
840                ppc64_result=0
841                if test "$pmix_cv_asm_powerpc_r_reg" = "1" ; then
842                   ldarx_asm="        ldarx r1,r1,r1";
843                else
844                   ldarx_asm="        ldarx 1,1,1";
845                fi
846                PMIX_TRY_ASSEMBLE([$pmix_cv_asm_text
847        $ldarx_asm],
848                    [ppc64_result=1],
849                    [ppc64_result=0])
850            ;;
851            *)
852                ppc64_result=0
853            ;;
854        esac
855    if test "$ppc64_result" = "1" ; then
856        AC_MSG_RESULT([yes])
857        ifelse([$1],,:,[$1])
858    else
859        AC_MSG_RESULT([no])
860        ifelse([$2],,:,[$2])
861    fi
862    unset ppc64_result ldarx_asm
863])dnl
864
865
866dnl #################################################################
867dnl
868dnl PMIX_CHECK_CMPXCHG16B
869dnl
870dnl #################################################################
871AC_DEFUN([PMIX_CMPXCHG16B_TEST_SOURCE],[[
872#include <stdint.h>
873#include <assert.h>
874union pmix_counted_pointer_t {
875    struct {
876        uint64_t counter;
877        uint64_t item;
878    } data;
879#if defined(HAVE___INT128) && HAVE___INT128
880    __int128 value;
881#elif defined(HAVE_INT128_T) && HAVE_INT128_T
882    int128_t value;
883#endif
884};
885typedef union pmix_counted_pointer_t pmix_counted_pointer_t;
886int main(int argc, char* argv) {
887    volatile pmix_counted_pointer_t a;
888    pmix_counted_pointer_t b;
889    a.data.counter = 0;
890    a.data.item = 0x1234567890ABCDEF;
891    b.data.counter = a.data.counter;
892    b.data.item = a.data.item;
893    /* bozo checks */
894    assert(16 == sizeof(pmix_counted_pointer_t));
895    assert(a.data.counter == b.data.counter);
896    assert(a.data.item == b.data.item);
897    /*
898     * the following test fails on buggy compilers
899     * so far, with icc -o conftest conftest.c
900     *  - intel icc 14.0.0.080 (aka 2013sp1)
901     *  - intel icc 14.0.1.106 (aka 2013sp1u1)
902     * older and more recents compilers work fine
903     * buggy compilers work also fine but only with -O0
904     */
905#if (defined(HAVE___INT128) && HAVE___INT128) || (defined(HAVE_INT128_T) && HAVE_INT128_T)
906    return (a.value != b.value);
907#else
908    return 0;
909#endif
910}
911]])
912
913AC_DEFUN([PMIX_CHECK_CMPXCHG16B],[
914    PMIX_VAR_SCOPE_PUSH([cmpxchg16b_result])
915    PMIX_ASM_CHECK_ATOMIC_FUNC([cmpxchg16b],
916                               [AC_LANG_PROGRAM([[unsigned char tmp[16];]],
917                                                [[__asm__ __volatile__ ("lock cmpxchg16b (%%rsi)" : : "S" (tmp) : "memory", "cc");]])],
918                               [cmpxchg16b_result=1],
919                               [cmpxchg16b_result=0])
920    # If we have it, make sure it works.
921    AS_IF([test $cmpxchg16b_result -eq 1],
922          [AC_MSG_CHECKING([if cmpxchg16b_result works])
923           AC_RUN_IFELSE([AC_LANG_SOURCE(PMIX_CMPXCHG16B_TEST_SOURCE)],
924                         [AC_MSG_RESULT([yes])],
925                         [cmpxchg16b_result=0
926                          AC_MSG_RESULT([no])],
927                         [AC_MSG_RESULT([cannot test -- assume yes (cross compiling)])])
928          ])
929    AC_DEFINE_UNQUOTED([PMIX_HAVE_CMPXCHG16B], [$cmpxchg16b_result],
930        [Whether the processor supports the cmpxchg16b instruction])
931    PMIX_VAR_SCOPE_POP
932])dnl
933
934dnl #################################################################
935dnl
936dnl PMIX_CHECK_INLINE_GCC
937dnl
938dnl Check if the compiler is capable of doing GCC-style inline
939dnl assembly.  Some compilers emit a warning and ignore the inline
940dnl assembly (xlc on OS X) and compile without error.  Therefore,
941dnl the test attempts to run the emitted code to check that the
942dnl assembly is actually run.  To run this test, one argument to
943dnl the macro must be an assembly instruction in gcc format to move
944dnl the value 0 into the register containing the variable ret.
945dnl For PowerPC, this would be:
946dnl
947dnl   "li %0,0" : "=&r"(ret)
948dnl
949dnl For testing ia32 assembly, the assembly instruction xaddl is
950dnl tested.  The xaddl instruction is used by some of the atomic
951dnl implementations so it makes sense to test for it.  In addition,
952dnl some compilers (i.e. earlier versions of Sun Studio 12) do not
953dnl necessarily handle xaddl properly, so that needs to be detected
954dnl during configure time.
955dnl
956dnl DEFINE PMIX_GCC_INLINE_ASSEMBLY to 0 or 1 depending on GCC
957dnl                support
958dnl
959dnl #################################################################
960AC_DEFUN([PMIX_CHECK_INLINE_C_GCC],[
961    assembly="$1"
962    asm_result="unknown"
963    AC_MSG_CHECKING([if $CC supports GCC inline assembly])
964    if test ! "$assembly" = "" ; then
965        AC_RUN_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],[[
966int ret = 1;
967int negone = -1;
968__asm__ __volatile__ ($assembly);
969return ret;
970                                                             ]])],
971                      [asm_result="yes"], [asm_result="no"],
972                      [asm_result="unknown"])
973    else
974        assembly="test skipped - assuming no"
975    fi
976    # if we're cross compiling, just try to compile and figure good enough
977    if test "$asm_result" = "unknown" ; then
978        AC_LINK_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],[[
979int ret = 1;
980int negone = -1;
981__asm__ __volatile__ ($assembly);
982return ret;
983                                                              ]])],
984                       [asm_result="yes"], [asm_result="no"])
985    fi
986    AC_MSG_RESULT([$asm_result])
987    if test "$asm_result" = "yes" ; then
988        PMIX_C_GCC_INLINE_ASSEMBLY=1
989        pmix_cv_asm_inline_supported="yes"
990    else
991        PMIX_C_GCC_INLINE_ASSEMBLY=0
992    fi
993    AC_DEFINE_UNQUOTED([PMIX_C_GCC_INLINE_ASSEMBLY],
994                       [$PMIX_C_GCC_INLINE_ASSEMBLY],
995                       [Whether C compiler supports GCC style inline assembly])
996    unset PMIX_C_GCC_INLINE_ASSEMBLY assembly asm_result
997])dnl
998
999dnl #################################################################
1000dnl
1001dnl PMIX_CONFIG_ASM
1002dnl
1003dnl DEFINE PMIX_ASSEMBLY_ARCH to something in sys/architecture.h
1004dnl DEFINE PMIX_ASSEMBLY_FORMAT to string containing correct
1005dnl                             format for assembly (not user friendly)
1006dnl SUBST PMIX_ASSEMBLY_FORMAT to string containing correct
1007dnl                             format for assembly (not user friendly)
1008dnl
1009dnl #################################################################
1010AC_DEFUN([PMIX_CONFIG_ASM],[
1011    AC_REQUIRE([PMIX_SETUP_CC])
1012    AC_REQUIRE([AM_PROG_AS])
1013    AC_ARG_ENABLE([c11-atomics],[AC_HELP_STRING([--enable-c11-atomics],
1014                  [Enable use of C11 atomics if available (default: enabled)])])
1015    AC_ARG_ENABLE([builtin-atomics],
1016      [AC_HELP_STRING([--enable-builtin-atomics],
1017         [Enable use of GCC built-in atomics (default: autodetect)])])
1018    PMIX_CHECK_C11_CSWAP_INT128
1019    pmix_cv_asm_builtin="BUILTIN_NO"
1020    PMIX_CHECK_GCC_ATOMIC_BUILTINS
1021    if test "x$enable_c11_atomics" != "xno" && test "$pmix_cv_c11_supported" = "yes" ; then
1022        pmix_cv_asm_builtin="BUILTIN_C11"
1023        PMIX_CHECK_C11_CSWAP_INT128
1024    elif test "x$enable_c11_atomics" = "xyes"; then
1025        AC_MSG_WARN([C11 atomics were requested but are not supported])
1026        AC_MSG_ERROR([Cannot continue])
1027    elif test "$enable_builtin_atomics" = "yes" ; then
1028    if test $pmix_cv_have___atomic = "yes" ; then
1029       pmix_cv_asm_builtin="BUILTIN_GCC"
1030    else
1031        AC_MSG_WARN([GCC built-in atomics requested but not found.])
1032        AC_MSG_ERROR([Cannot continue])
1033    fi
1034    fi
1035        PMIX_CHECK_ASM_PROC
1036        PMIX_CHECK_ASM_TEXT
1037        PMIX_CHECK_ASM_GLOBAL
1038        PMIX_CHECK_ASM_GNU_STACKEXEC
1039        PMIX_CHECK_ASM_LABEL_SUFFIX
1040        PMIX_CHECK_ASM_GSYM
1041        PMIX_CHECK_ASM_LSYM
1042        PMIX_CHECK_ASM_TYPE
1043        PMIX_CHECK_ASM_SIZE
1044        PMIX_CHECK_ASM_ALIGN_LOG
1045        # find our architecture for purposes of assembly stuff
1046        pmix_cv_asm_arch="UNSUPPORTED"
1047        PMIX_GCC_INLINE_ASSIGN=""
1048    if test "$pmix_cv_have___atomic_64" ; then
1049            PMIX_ASM_SUPPORT_64BIT=1
1050    else
1051        PMIX_ASM_SUPPORT_64BIT=0
1052    fi
1053        case "${host}" in
1054        x86_64-*x32)
1055            pmix_cv_asm_arch="X86_64"
1056            PMIX_ASM_SUPPORT_64BIT=1
1057            PMIX_GCC_INLINE_ASSIGN='"xaddl %1,%0" : "=m"(ret), "+r"(negone) : "m"(ret)'
1058            ;;
1059        i?86-*|x86_64*|amd64*)
1060            if test "$ac_cv_sizeof_long" = "4" ; then
1061                pmix_cv_asm_arch="IA32"
1062            else
1063                pmix_cv_asm_arch="X86_64"
1064            fi
1065            PMIX_ASM_SUPPORT_64BIT=1
1066            PMIX_GCC_INLINE_ASSIGN='"xaddl %1,%0" : "=m"(ret), "+r"(negone) : "m"(ret)'
1067            PMIX_CHECK_CMPXCHG16B
1068            ;;
1069        aarch64*)
1070            pmix_cv_asm_arch="ARM64"
1071            PMIX_ASM_SUPPORT_64BIT=1
1072            PMIX_ASM_ARM_VERSION=8
1073            PMIX_GCC_INLINE_ASSIGN='"mov %0, #0" : "=&r"(ret)'
1074            ;;
1075        armv7*|arm-*-linux-gnueabihf)
1076            pmix_cv_asm_arch="ARM"
1077            PMIX_ASM_SUPPORT_64BIT=1
1078            PMIX_ASM_ARM_VERSION=7
1079            PMIX_GCC_INLINE_ASSIGN='"mov %0, #0" : "=&r"(ret)'
1080            ;;
1081        armv6*)
1082            pmix_cv_asm_arch="ARM"
1083            PMIX_ASM_SUPPORT_64BIT=0
1084            PMIX_ASM_ARM_VERSION=6
1085            CCASFLAGS="$CCASFLAGS -march=armv7-a"
1086            PMIX_GCC_INLINE_ASSIGN='"mov %0, #0" : "=&r"(ret)'
1087            ;;
1088        powerpc-*|powerpc64-*|powerpcle-*|powerpc64le-*|rs6000-*|ppc-*)
1089            PMIX_CHECK_POWERPC_REG
1090            if test "$ac_cv_sizeof_long" = "4" ; then
1091                pmix_cv_asm_arch="POWERPC32"
1092                # Note that on some platforms (Apple G5), even if we are
1093                # compiling in 32 bit mode (and therefore should assume
1094                # sizeof(long) == 4), we can use the 64 bit test and set
1095                # operations.
1096                PMIX_CHECK_POWERPC_64BIT(PMIX_ASM_SUPPORT_64BIT=1)
1097            elif test "$ac_cv_sizeof_long" = "8" ; then
1098                PMIX_ASM_SUPPORT_64BIT=1
1099                pmix_cv_asm_arch="POWERPC64"
1100            else
1101                AC_MSG_ERROR([Could not determine PowerPC word size: $ac_cv_sizeof_long])
1102            fi
1103            PMIX_GCC_INLINE_ASSIGN='"1: li %0,0" : "=&r"(ret)'
1104            ;;
1105        *)
1106        if test $pmix_cv_have___atomic = "yes" ; then
1107        pmix_cv_asm_builtin="BUILTIN_GCC"
1108        else
1109        AC_MSG_ERROR([No atomic primitives available for $host])
1110        fi
1111        ;;
1112        esac
1113    if ! test -z "$PMIX_ASM_ARM_VERSION" ; then
1114        AC_DEFINE_UNQUOTED([PMIX_ASM_ARM_VERSION], [$PMIX_ASM_ARM_VERSION],
1115                               [What ARM assembly version to use])
1116    fi
1117    if test "$pmix_cv_asm_builtin" = "BUILTIN_GCC" ; then
1118         AC_DEFINE([PMIX_C_GCC_INLINE_ASSEMBLY], [1],
1119           [Whether C compiler supports GCC style inline assembly])
1120    else
1121         AC_DEFINE_UNQUOTED([PMIX_ASM_SUPPORT_64BIT],
1122                [$PMIX_ASM_SUPPORT_64BIT],
1123                [Whether we can do 64bit assembly operations or not.  Should not be used outside of the assembly header files])
1124         AC_SUBST([PMIX_ASM_SUPPORT_64BIT])
1125         pmix_cv_asm_inline_supported="no"
1126         # now that we know our architecture, try to inline assemble
1127         PMIX_CHECK_INLINE_C_GCC([$PMIX_GCC_INLINE_ASSIGN])
1128         # format:
1129         #   config_file-text-global-label_suffix-gsym-lsym-type-size-align_log-ppc_r_reg-64_bit-gnu_stack
1130         asm_format="default"
1131         asm_format="${asm_format}-${pmix_cv_asm_text}-${pmix_cv_asm_global}"
1132         asm_format="${asm_format}-${pmix_cv_asm_label_suffix}-${pmix_cv_asm_gsym}"
1133         asm_format="${asm_format}-${pmix_cv_asm_lsym}"
1134         asm_format="${asm_format}-${pmix_cv_asm_type}-${pmix_asm_size}"
1135         asm_format="${asm_format}-${pmix_asm_align_log_result}"
1136         if test "$pmix_cv_asm_arch" = "POWERPC32" || test "$pmix_cv_asm_arch" = "POWERPC64" ; then
1137             asm_format="${asm_format}-${pmix_cv_asm_powerpc_r_reg}"
1138         else
1139             asm_format="${asm_format}-1"
1140         fi
1141         asm_format="${asm_format}-${PMIX_ASM_SUPPORT_64BIT}"
1142         pmix_cv_asm_format="${asm_format}-${pmix_cv_asm_gnu_stack}"
1143         # For the Makefile, need to escape the $ as $$.  Don't display
1144         # this version, but make sure the Makefile gives the right thing
1145         # when regenerating the files because the base has been touched.
1146         PMIX_ASSEMBLY_FORMAT=`echo "$pmix_cv_asm_format" | sed -e 's/\\\$/\\\$\\\$/'`
1147        AC_MSG_CHECKING([for assembly format])
1148        AC_MSG_RESULT([$pmix_cv_asm_format])
1149        AC_DEFINE_UNQUOTED([PMIX_ASSEMBLY_FORMAT], ["$PMIX_ASSEMBLY_FORMAT"],
1150                           [Format of assembly file])
1151        AC_SUBST([PMIX_ASSEMBLY_FORMAT])
1152      fi # if pmix_cv_asm_builtin = BUILTIN_GCC
1153    result="PMIX_$pmix_cv_asm_arch"
1154    PMIX_ASSEMBLY_ARCH="$pmix_cv_asm_arch"
1155    AC_MSG_CHECKING([for assembly architecture])
1156    AC_MSG_RESULT([$pmix_cv_asm_arch])
1157    AC_DEFINE_UNQUOTED([PMIX_ASSEMBLY_ARCH], [$result],
1158        [Architecture type of assembly to use for atomic operations and CMA])
1159    AC_SUBST([PMIX_ASSEMBLY_ARCH])
1160    # Check for RDTSCP support
1161    result=0
1162    AS_IF([test "$pmix_cv_asm_arch" = "PMIX_X86_64" || test "$pmix_cv_asm_arch" = "PMIX_IA32"],
1163          [AC_MSG_CHECKING([for RDTSCP assembly support])
1164           AC_LANG_PUSH([C])
1165           AC_TRY_RUN([[
1166int main(int argc, char* argv[])
1167{
1168  unsigned int rax, rdx;
1169  __asm__ __volatile__ ("rdtscp\n": "=a" (rax), "=d" (rdx):: "%rax", "%rdx");
1170  return 0;
1171}
1172           ]],
1173           [result=1
1174            AC_MSG_RESULT([yes])],
1175           [AC_MSG_RESULT([no])],
1176           [#cross compile not supported
1177            AC_MSG_RESULT(["no (cross compiling)"])])
1178           AC_LANG_POP([C])])
1179    AC_DEFINE_UNQUOTED([PMIX_ASSEMBLY_SUPPORTS_RDTSCP], [$result],
1180                       [Whether we have support for RDTSCP instruction])
1181    result="PMIX_$pmix_cv_asm_builtin"
1182    PMIX_ASSEMBLY_BUILTIN="$pmix_cv_asm_builtin"
1183    AC_MSG_CHECKING([for builtin atomics])
1184    AC_MSG_RESULT([$pmix_cv_asm_builtin])
1185    AC_DEFINE_UNQUOTED([PMIX_ASSEMBLY_BUILTIN], [$result],
1186        [Whether to use builtin atomics])
1187    AC_SUBST([PMIX_ASSEMBLY_BUILTIN])
1188    PMIX_ASM_FIND_FILE
1189    unset result asm_format
1190])dnl
1191
1192
1193dnl #################################################################
1194dnl
1195dnl PMIX_ASM_FIND_FILE
1196dnl
1197dnl
1198dnl do all the evil mojo to provide a working assembly file
1199dnl
1200dnl #################################################################
1201AC_DEFUN([PMIX_ASM_FIND_FILE], [
1202    AC_REQUIRE([AC_PROG_GREP])
1203    AC_REQUIRE([AC_PROG_FGREP])
1204if test "$pmix_cv_asm_arch" != "WINDOWS" && test "$pmix_cv_asm_builtin" != "BUILTIN_GCC" && test "$pmix_cv_asm_builtin" != "BUILTIN_OSX"  && test "$pmix_cv_asm_inline_arch" = "no" ; then
1205    AC_MSG_ERROR([no atomic support available. exiting])
1206else
1207    # On windows with VC++, atomics are done with compiler primitives
1208    pmix_cv_asm_file=""
1209fi
1210])dnl
1211