1dnl /*D PAC_C_MEMATOMIC - Try and determine how to implement memory-atomic
2dnl   operations with the selected C compiler
3dnl
4dnl Synopsis:
5dnl PAC_C_MEMATOMIC
6dnl
7dnl Notes:
8dnl Defines names of the following form
9dnl + HAVE_GCC_ASM_AND_X86_{MFENCE,LFENCE,SFENCE} - gcc __asm__ will issue
10dnl    mfence, lfence, or sfence
11dnl . HAVE___ASM_AND_X86_{MFENCE,LFENCE,SFENCE} - __asm _emit will issue
12dnl    mfence, lfence, or sfence
13dnl . HAVE_ASM_AND_X86_{MFENCE,LFENCE,SFENCE} - asm("...") will issue
14dnl    mfence, lfence, or sfence
15dnl . HAVE__INTERLOCKEDEXCHANGE - _InterlockedExchange intrinsic is available
16dnl    (IA64)
17dnl . HAVE_GCC_ASM_SPARC_MEMBAR - gcc __asm__ will issue SPARC architecture
18dnl    memory barrier instruction
19dnl . HAVE_SOLARIS_ASM_SPARC_MEMBAR - Solaris asm() will issue SPARC
20dnl    architecture memory barrier instruction
21dnl . HAVE_GCC_ASM_SPARC_STBAR - gcc __asm__ will issue stbar
22dnl - HAVE_SOLARIS_ASM_SPARC_STBAR - Solaris __asm() will issue stbar
23dnl
24dnl D*/
25AC_DEFUN([PAC_C_MEMATOMIC],[
26AC_CACHE_CHECK([for x86 mfence instruction using __asm__],
27    pac_cv_have_gcc_asm_and_x86_mfence,[
28AC_TRY_RUN([
29int main(int argc, char **argv)
30{
31    __asm__ __volatile__  ( ".byte 0x0f, 0xae, 0xf0" ::: "memory" );
32    exit(0);
33}
34],
35pac_cv_have_gcc_asm_and_x86_mfence=yes,pac_cv_have_gcc_asm_and_x86_mfence=no)])
36
37if test "$pac_cv_have_gcc_asm_and_x86_mfence" = "yes" ; then
38    AC_DEFINE(HAVE_GCC_ASM_AND_X86_MFENCE, 1, [Define if using gcc on a x86 system with the mfence instruction])
39fi
40
41AC_CACHE_CHECK([for x86 sfence instruction using __asm__],
42    pac_cv_have_gcc_asm_and_x86_sfence,[
43AC_TRY_RUN([
44int main(int argc, char **argv)
45{
46    __asm__ __volatile__  ( ".byte 0x0f, 0xae, 0xf8" ::: "memory" );
47    exit(0);
48}
49],
50pac_cv_have_gcc_asm_and_x86_sfence=yes,pac_cv_have_gcc_asm_and_x86_sfence=no)])
51
52if test "$pac_cv_have_gcc_asm_and_x86_sfence" = "yes" ; then
53    AC_DEFINE(HAVE_GCC_ASM_AND_X86_SFENCE, 1, [Define if using gcc on a x86 system with the sfence instruction])
54fi
55
56AC_CACHE_CHECK([for x86 lfence instruction using __asm__],
57    pac_cv_have_gcc_asm_and_x86_lfence,[
58AC_TRY_RUN([
59int main(int argc, char **argv)
60{
61    __asm__ __volatile__  ( ".byte 0x0f, 0xae, 0xe8" ::: "memory" );
62    exit(0);
63}
64],
65pac_cv_have_gcc_asm_and_x86_lfence=yes,pac_cv_have_gcc_asm_and_x86_lfence=no)])
66
67if test "$pac_cv_have_gcc_asm_and_x86_lfence" = "yes" ; then
68    AC_DEFINE(HAVE_GCC_ASM_AND_X86_LFENCE, 1, [Define if using gcc on a x86 system with the lfence instruction])
69fi
70
71dnl Some compilers, like icc, may want __asm _emit
72AC_CACHE_CHECK([for x86 mfence instruction using __asm],
73     pac_cv_have___asm_and_x86_mfence,[
74AC_TRY_RUN([
75int main(int argc, char **argv)
76{
77    __asm _emit 0x0f __asm _emit 0xae __asm _emit 0xf0 ;
78    exit(0);
79}
80],
81pac_cv_have___asm_and_x86_mfence=yes,pac_cv_have___asm_and_x86_mfence=no)])
82
83if test "$pac_cv_have___asm_and_x86_mfence" = "yes" ; then
84    AC_DEFINE(HAVE___ASM_AND_X86_MFENCE, 1, [Define if using __asm on a x86 system with the mfence instruction])
85fi
86
87AC_CACHE_CHECK([for x86 sfence instruction using __asm],
88    pac_cv_have___asm_and_x86_sfence,[
89AC_TRY_RUN([
90int main(int argc, char **argv)
91{
92    __asm sfence ;
93    exit(0);
94}
95],
96pac_cv_have___asm_and_x86_sfence=yes,pac_cv_have___asm_and_x86_sfence=no)])
97
98if test "$pac_cv_have___asm_and_x86_sfence" = "yes" ; then
99    AC_DEFINE(HAVE___ASM_AND_X86_SFENCE, 1, [Define if using __asm on a x86 system with the sfence instruction])
100fi
101
102AC_CACHE_CHECK([for x86 lfence instruction using __asm],
103    pac_cv_have___asm_and_x86_lfence,[
104AC_TRY_RUN([
105int main(int argc, char **argv)
106{
107    __asm _emit 0x0f __asm _emit 0xae __asm _emit 0xe8 ;
108    exit(0);
109}
110],
111pac_cv_have___asm_and_x86_lfence=yes,pac_cv_have___asm_and_x86_lfence=no)])
112
113if test "$lac_cv_have___asm_and_x86_lfence" = "yes" ; then
114    AC_DEFINE(HAVE___ASM_AND_X86_LFENCE, 1, [Define if using __asm on a x86 system with the lfence instruction])
115fi
116
117dnl
118dnl Some compilers, such as pgcc, may require additional arguments.
119dnl pgcc may need -Masmkeyword flag.  We may want to try this with and
120dnl without adding -Masmkeyword to CFLAGS
121
122AC_CACHE_CHECK([for x86 mfence instruction using asm()],
123    pac_cv_have_asm_and_x86_mfence,[
124AC_TRY_RUN([
125int main(int argc, char **argv)
126{
127    asm("_emit 0x0f __asm _emit 0xae __asm _emit 0xf0");
128    exit(0);
129}
130],
131pac_cv_have_asm_and_x86_mfence=yes,pac_cv_have_asm_and_x86_mfence=no)])
132
133if test "$pac_cv_have_asm_and_x86_mfence" = "yes" ; then
134    AC_DEFINE(HAVE_ASM_AND_X86_MFENCE, 1, [Define if using asm() on a x86 system with the mfence instruction])
135fi
136
137AC_CACHE_CHECK([for x86 sfence instruction using asm()],
138    pac_cv_have_asm_and_x86_sfence,[
139AC_TRY_RUN([
140int main(int argc, char **argv)
141{
142    asm("sfence");
143    exit(0);
144}
145],
146pac_cv_have_asm_and_x86_sfence=yes,pac_cv_have_asm_and_x86_sfence=no)])
147
148if test "$pac_cv_have_asm_and_x86_sfence" = "yes" ; then
149    AC_DEFINE(HAVE_ASM_AND_X86_SFENCE, 1, [Define if using asm() on a x86 system with the sfence instruction])
150fi
151
152AC_CACHE_CHECK([for x86 lfence instruction using asm()],
153    pac_cv_have_asm_and_x86_lfence,[
154AC_TRY_RUN([
155int main(int argc, char **argv)
156{
157    asm("_emit 0x0f __asm _emit 0xae __asm _emit 0xe8");
158    exit(0);
159}
160],
161pac_cv_have_asm_and_x86_lfence=yes,pac_cv_have_asm_and_x86_lfence=no)])
162
163if test "$pac_cv_have_asm_and_x86_lfence" = "yes" ; then
164    AC_DEFINE(HAVE_ASM_AND_X86_LFENCE, 1, [Define if using asm() on a x86 system with the lfence instruction])
165fi
166
167AC_CACHE_CHECK([for _InterlockedExchange intrinsic],
168    pac_cv_have__InterlockedExchange,[
169AC_TRY_RUN([
170int main(int argc, char **argv)
171{
172    unsigned long lock, *lock_ptr;
173    lock_ptr = &lock;
174    _InterlockedExchange(lock_ptr, 1);
175    exit(0);
176}
177],
178pac_cv_have__InterlockedExchange=yes,pac_cv_have__InterlockedExchange=no)])
179
180if test "$pac_cv_have__InterlockedExchange" = "yes" ; then
181    AC_DEFINE(HAVE__INTERLOCKEDEXCHANGE, 1, [Define if _InterlockedExchange intrinsic is available])
182fi
183
184AC_CACHE_CHECK([for SPARC membar instruction with gcc],
185    pac_cv_gcc_sparc_membar,[
186AC_TRY_RUN([
187int main(int argc, char **argv){
188    __asm__ __volatile__ ( "membar #StoreLoad | #StoreStore" : : : "memory" );
189    exit(0);
190}],pac_cv_gcc_sparc_membar=yes,pac_cv_gcc_sparc_membar=no)])
191if test "$pac_cv_gcc_sparc_membar" = yes ; then
192    AC_DEFINE(HAVE_GCC_ASM_SPARC_MEMBAR,1,[Define if gcc asm membar supported])
193fi
194
195AC_CACHE_CHECK([for SPARC membar instruction with Solaris C],
196    pac_cv_solaris_sparc_membar,[
197AC_TRY_RUN([
198int main(int argc, char **argv){
199    __asm ( "membar #StoreLoad | #StoreStore");
200    exit(0);
201}],pac_cv_solaris_sparc_membar=yes,pac_cv_solaris_sparc_membar=no)])
202if test "$pac_cv_solaris_sparc_membar" = yes ; then
203    AC_DEFINE(HAVE_SOLARIS_ASM_SPARC_MEMBAR,1,[Define if solaris asm membar supported])
204fi
205
206AC_CACHE_CHECK([for SPARC stbar instruction with gcc],
207    pac_cv_gcc_sparc_stbar,[
208AC_TRY_RUN([
209int main(int argc, char **argv){
210    __asm__ __volatile__ ( "stbar" : : : "memory" );
211    exit(0);
212}],pac_cv_gcc_sparc_stbar=yes,pac_cv_gcc_sparc_stbar=no)])
213if test "$pac_cv_gcc_sparc_stbar" = yes ; then
214    AC_DEFINE(HAVE_GCC_ASM_SPARC_STBAR,1,[Define if gcc asm stbar supported])
215fi
216
217AC_CACHE_CHECK([for SPARC stbar instruction with Solaris C],
218    pac_cv_solaris_sparc_stbar,[
219AC_TRY_RUN([
220int main(int argc, char **argv){
221    __asm ( "stbar" );
222    exit(0);
223}],pac_cv_solaris_sparc_stbar=yes,pac_cv_solaris_sparc_stbar=no)])
224if test "$pac_cv_solaris_sparc_stbar" = yes ; then
225    AC_DEFINE(HAVE_SOLARIS_ASM_SPARC_STBAR,1,[Define if solaris asm stbar supported])
226fi
227])