]> pd.if.org Git - liblfds/blob - liblfds/liblfds7.1.0/liblfds710/inc/liblfds710/lfds710_porting_abstraction_layer_compiler.h
Initial import (all versions, including the new 7.1.0)
[liblfds] / liblfds / liblfds7.1.0 / liblfds710 / inc / liblfds710 / lfds710_porting_abstraction_layer_compiler.h
1 /****************************************************************************/
2 #if( defined __GNUC__ )
3   // TRD : makes checking GCC versions much tidier
4   #define LFDS710_PAL_GCC_VERSION ( __GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__ )
5 #endif
6
7
8
9
10
11 /****************************************************************************/
12 #if( defined _MSC_VER && _MSC_VER >= 1400 )
13
14   #ifdef LFDS710_PAL_COMPILER
15     #error More than one porting abstraction layer matches the current platform in lfds710_porting_abstraction_layer_compiler.h
16   #endif
17
18   #define LFDS710_PAL_COMPILER
19
20   #define LFDS710_PAL_COMPILER_STRING            "MSVC"
21
22   #define LFDS710_PAL_ALIGN(alignment)           __declspec( align(alignment) )
23   #define LFDS710_PAL_INLINE                     __forceinline
24
25   #define LFDS710_PAL_BARRIER_COMPILER_LOAD      _ReadBarrier()
26   #define LFDS710_PAL_BARRIER_COMPILER_STORE     _WriteBarrier()
27   #define LFDS710_PAL_BARRIER_COMPILER_FULL      _ReadWriteBarrier()
28
29   /* TRD : there are four processors to consider;
30
31            . ARM32    (32 bit, ADD, CAS, DWCAS, EXCHANGE, SET) (defined _M_ARM)
32            . Itanium  (64 bit, ADD, CAS,        EXCHANGE, SET) (defined _M_IA64)
33            . x64      (64 bit, ADD, CAS, DWCAS, EXCHANGE, SET) (defined _M_X64 || defined _M_AMD64)
34            . x86      (32 bit, ADD, CAS, DWCAS, EXCHANGE, SET) (defined _M_IX86)
35
36            can't find any indications of 64-bit ARM support yet
37
38            ARM has better intrinsics than the others, as there are no-fence variants
39
40            in theory we also have to deal with 32-bit Windows on a 64-bit platform,
41            and I presume we'd see the compiler properly indicate this in its macros,
42            but this would require that we use 32-bit atomics on the 64-bit platforms,
43            while keeping 64-bit cache line lengths and so on, and this is just so
44            wierd a thing to do these days that it's not supported
45   */
46
47   #if( defined _M_ARM )
48     #define LFDS710_PAL_BARRIER_PROCESSOR_LOAD   __dmb( _ARM_BARRIER_ISH )
49     #define LFDS710_PAL_BARRIER_PROCESSOR_STORE  __dmb( _ARM_BARRIER_ISHST )
50     #define LFDS710_PAL_BARRIER_PROCESSOR_FULL   __dmb( _ARM_BARRIER_ISH )
51
52     #define LFDS710_PAL_ATOMIC_ADD( pointer_to_target, value, result, result_type )                                  \
53     {                                                                                                                \
54       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                             \
55       (result) = (result_type) _InterlockedAdd_nf( (int long volatile *) (pointer_to_target), (int long) (value) );  \
56       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                             \
57     }
58
59     #define LFDS710_PAL_ATOMIC_CAS( pointer_to_destination, pointer_to_compare, new_destination, cas_strength, result )                                                                                          \
60     {                                                                                                                                                                                                            \
61       lfds710_pal_uint_t                                                                                                                                                                                         \
62         original_compare;                                                                                                                                                                                        \
63                                                                                                                                                                                                                  \
64       original_compare = (lfds710_pal_uint_t) *(pointer_to_compare);                                                                                                                                             \
65                                                                                                                                                                                                                  \
66       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                                                                                                         \
67       *(lfds710_pal_uint_t *) (pointer_to_compare) = (lfds710_pal_uint_t) _InterlockedCompareExchange_nf( (long volatile *) (pointer_to_destination), (long) (new_destination), (long) *(pointer_to_compare) );  \
68       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                                                                                                         \
69                                                                                                                                                                                                                  \
70       result = (char unsigned) ( original_compare == (lfds710_pal_uint_t) *(pointer_to_compare) );                                                                                                               \
71     }
72
73     #define LFDS710_PAL_ATOMIC_DWCAS( pointer_to_destination, pointer_to_compare, pointer_to_new_destination, cas_strength, result )                                                                        \
74     {                                                                                                                                                                                                       \
75       __int64                                                                                                                                                                                               \
76         original_compare;                                                                                                                                                                                   \
77                                                                                                                                                                                                             \
78       original_compare = *(__int64 *) (pointer_to_compare);                                                                                                                                                 \
79                                                                                                                                                                                                             \
80       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                                                                                                    \
81       *(__int64 *) (pointer_to_compare) = _InterlockedCompareExchange64_nf( (__int64 volatile *) (pointer_to_destination), *(__int64 *) (pointer_to_new_destination), *(__int64 *) (pointer_to_compare) );  \
82       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                                                                                                    \
83                                                                                                                                                                                                             \
84       (result) = (char unsigned) ( *(__int64 *) (pointer_to_compare) == original_compare );                                                                                                                 \
85     }
86
87     #define LFDS710_PAL_ATOMIC_EXCHANGE( pointer_to_destination, exchange, exchange_type )                                            \
88     {                                                                                                                                 \
89       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                              \
90       (exchange) = (exchange_type) _InterlockedExchange_nf( (int long volatile *) (pointer_to_destination), (int long) (exchange) );  \
91       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                              \
92     }
93
94     #define LFDS710_PAL_ATOMIC_SET( pointer_to_destination, new_value )                                          \
95     {                                                                                                            \
96       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                         \
97       (void) _InterlockedExchange_nf( (int long volatile *) (pointer_to_destination), (int long) (new_value) );  \
98       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                         \
99     }
100   #endif
101
102   #if( defined _M_IA64 )
103     #define LFDS710_PAL_BARRIER_PROCESSOR_LOAD   __mf()
104     #define LFDS710_PAL_BARRIER_PROCESSOR_STORE  __mf()
105     #define LFDS710_PAL_BARRIER_PROCESSOR_FULL   __mf()
106
107     #define LFDS710_PAL_ATOMIC_ADD( pointer_to_target, value, result, result_type )                                   \
108     {                                                                                                                 \
109       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                              \
110       (result) = (result_type) _InterlockedAdd64_acq( (__int64 volatile *) (pointer_to_target), (__int64) (value) );  \
111       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                              \
112     }
113
114     #define LFDS710_PAL_ATOMIC_CAS( pointer_to_destination, pointer_to_compare, new_destination, cas_strength, result )                                                                                                      \
115     {                                                                                                                                                                                                                        \
116       lfds710_pal_uint_t                                                                                                                                                                                                     \
117         original_compare;                                                                                                                                                                                                    \
118                                                                                                                                                                                                                              \
119       original_compare = (lfds710_pal_uint_t) *(pointer_to_compare);                                                                                                                                                         \
120                                                                                                                                                                                                                              \
121       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                                                                                                                     \
122       *(lfds710_pal_uint_t *) (pointer_to_compare) = (lfds710_pal_uint_t) _InterlockedCompareExchange64_acq( (__int64 volatile *) (pointer_to_destination), (__int64) (new_destination), (__int64) *(pointer_to_compare) );  \
123       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                                                                                                                     \
124                                                                                                                                                                                                                              \
125       result = (char unsigned) ( original_compare == (lfds710_pal_uint_t) *(pointer_to_compare) );                                                                                                                           \
126     }
127
128     #define LFDS710_PAL_ATOMIC_EXCHANGE( pointer_to_destination, exchange, exchange_type )                                             \
129     {                                                                                                                                  \
130       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                               \
131       (exchange) = (exchange_type) _InterlockedExchange64_acq( (__int64 volatile *) (pointer_to_destination), (__int64) (exchange) );  \
132       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                               \
133     }
134
135     #define LFDS710_PAL_ATOMIC_SET( pointer_to_destination, new_value )                                           \
136     {                                                                                                             \
137       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                          \
138       (void) _InterlockedExchange64_acq( (__int64 volatile *) (pointer_to_destination), (__int64) (new_value) );  \
139       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                          \
140     }
141   #endif
142
143   #if( defined _M_X64 || defined _M_AMD64 )
144     #define LFDS710_PAL_BARRIER_PROCESSOR_LOAD   _mm_lfence()
145     #define LFDS710_PAL_BARRIER_PROCESSOR_STORE  _mm_sfence()
146     #define LFDS710_PAL_BARRIER_PROCESSOR_FULL   _mm_mfence()
147
148     // TRD : no _InterlockedAdd64 for x64 - only the badly named _InterlockedExchangeAdd64, which is the same as _InterlockedAdd64 but returns the *original* value (which we must then add to before we return)
149     #define LFDS710_PAL_ATOMIC_ADD( pointer_to_target, value, result, result_type )                                       \
150     {                                                                                                                     \
151       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                  \
152       (result) = (result_type) _InterlockedExchangeAdd64( (__int64 volatile *) (pointer_to_target), (__int64) (value) );  \
153       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                  \
154       result += value;                                                                                                    \
155     }
156
157     #define LFDS710_PAL_ATOMIC_CAS( pointer_to_destination, pointer_to_compare, new_destination, cas_strength, result )                                                                                                  \
158     {                                                                                                                                                                                                                    \
159       lfds710_pal_uint_t                                                                                                                                                                                                 \
160         original_compare;                                                                                                                                                                                                \
161                                                                                                                                                                                                                          \
162       original_compare = (lfds710_pal_uint_t) *(pointer_to_compare);                                                                                                                                                     \
163                                                                                                                                                                                                                          \
164       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                                                                                                                 \
165       *(lfds710_pal_uint_t *) (pointer_to_compare) = (lfds710_pal_uint_t) _InterlockedCompareExchange64( (__int64 volatile *) (pointer_to_destination), (__int64) (new_destination), (__int64) *(pointer_to_compare) );  \
166       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                                                                                                                 \
167                                                                                                                                                                                                                          \
168       result = (char unsigned) ( original_compare == (lfds710_pal_uint_t) *(pointer_to_compare) );                                                                                                                       \
169     }
170
171     #if( _MSC_VER >= 1500 )
172       #define LFDS710_PAL_ATOMIC_DWCAS( pointer_to_destination, pointer_to_compare, pointer_to_new_destination, cas_strength, result )                                                                                                       \
173       {                                                                                                                                                                                                                                      \
174         LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                                                                                                                                   \
175         (result) = (char unsigned) _InterlockedCompareExchange128( (__int64 volatile *) (pointer_to_destination), (__int64) (pointer_to_new_destination[1]), (__int64) (pointer_to_new_destination[0]), (__int64 *) (pointer_to_compare) );  \
176         LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                                                                                                                                   \
177       }
178     #endif
179
180     #define LFDS710_PAL_ATOMIC_EXCHANGE( pointer_to_destination, exchange, exchange_type )                                         \
181     {                                                                                                                              \
182       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                           \
183       (exchange) = (exchange_type) _InterlockedExchange64( (__int64 volatile *) (pointer_to_destination), (__int64) (exchange) );  \
184       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                           \
185     }
186
187     #define LFDS710_PAL_ATOMIC_SET( pointer_to_destination, new_value )                                       \
188     {                                                                                                         \
189       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                      \
190       (void) _InterlockedExchange64( (__int64 volatile *) (pointer_to_destination), (__int64) (new_value) );  \
191       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                      \
192     }
193   #endif
194
195   #if( defined _M_IX86 )
196     #define LFDS710_PAL_BARRIER_PROCESSOR_LOAD   lfds710_misc_force_store()
197     #define LFDS710_PAL_BARRIER_PROCESSOR_STORE  lfds710_misc_force_store()
198     #define LFDS710_PAL_BARRIER_PROCESSOR_FULL   lfds710_misc_force_store()
199
200     // TRD : no _InterlockedAdd for x86 - only the badly named _InterlockedExchangeAdd, which is the same as _InterlockedAdd but returns the *original* value (which we must then add to before we return)
201     #define LFDS710_PAL_ATOMIC_ADD( pointer_to_target, value, result, result_type )                                     \
202     {                                                                                                                   \
203       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                \
204       (result) = (result_type) _InterlockedExchangeAdd( (__int64 volatile *) (pointer_to_target), (__int64) (value) );  \
205       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                \
206       result += value;                                                                                                  \
207     }
208
209     #define LFDS710_PAL_ATOMIC_CAS( pointer_to_destination, pointer_to_compare, new_destination, cas_strength, result )                                                                                       \
210     {                                                                                                                                                                                                         \
211       lfds710_pal_uint_t                                                                                                                                                                                      \
212         original_compare;                                                                                                                                                                                     \
213                                                                                                                                                                                                               \
214       /* LFDS710_PAL_ASSERT( (pointer_to_destination) != NULL ); */                                                                                                                                           \
215       /* LFDS710_PAL_ASSERT( (pointer_to_compare) != NULL ); */                                                                                                                                               \
216       /* TRD : new_destination can be any value in its range */                                                                                                                                               \
217       /* TRD : cas_strength can be any value in its range */                                                                                                                                                  \
218       /* TRD : result can be any value in its range */                                                                                                                                                        \
219                                                                                                                                                                                                               \
220       original_compare = (lfds710_pal_uint_t) *(pointer_to_compare);                                                                                                                                          \
221                                                                                                                                                                                                               \
222       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                                                                                                      \
223       *(lfds710_pal_uint_t *) (pointer_to_compare) = (lfds710_pal_uint_t) _InterlockedCompareExchange( (long volatile *) (pointer_to_destination), (long) (new_destination), (long) *(pointer_to_compare) );  \
224       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                                                                                                      \
225                                                                                                                                                                                                               \
226       result = (char unsigned) ( original_compare == (lfds710_pal_uint_t) *(pointer_to_compare) );                                                                                                            \
227     }
228
229     #define LFDS710_PAL_ATOMIC_DWCAS( pointer_to_destination, pointer_to_compare, pointer_to_new_destination, cas_strength, result )                                                                     \
230     {                                                                                                                                                                                                    \
231       __int64                                                                                                                                                                                            \
232         original_compare;                                                                                                                                                                                \
233                                                                                                                                                                                                          \
234       original_compare = *(__int64 *) (pointer_to_compare);                                                                                                                                              \
235                                                                                                                                                                                                          \
236       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                                                                                                 \
237       *(__int64 *) (pointer_to_compare) = _InterlockedCompareExchange64( (__int64 volatile *) (pointer_to_destination), *(__int64 *) (pointer_to_new_destination), *(__int64 *) (pointer_to_compare) );  \
238       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                                                                                                 \
239                                                                                                                                                                                                          \
240       (result) = (char unsigned) ( *(__int64 *) (pointer_to_compare) == original_compare );                                                                                                              \
241     }
242
243     #define LFDS710_PAL_ATOMIC_EXCHANGE( pointer_to_destination, exchange, exchange_type )                                         \
244     {                                                                                                                              \
245       /* LFDS710_PAL_ASSERT( (pointer_to_destination) != NULL ); */                                                                \
246       /* LFDS710_PAL_ASSERT( (pointer_to_exchange) != NULL ); */                                                                   \
247                                                                                                                                    \
248       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                           \
249       (exchange) = (exchange_type) _InterlockedExchange( (int long volatile *) (pointer_to_destination), (int long) (exchange) );  \
250       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                           \
251     }
252
253     #define LFDS710_PAL_ATOMIC_SET( pointer_to_destination, new_value )                                       \
254     {                                                                                                         \
255       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                      \
256       (void) _InterlockedExchange( (int long volatile *) (pointer_to_destination), (int long) (new_value) );  \
257       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                      \
258     }
259   #endif
260
261 #endif
262
263
264
265
266
267 /****************************************************************************/
268 #if( defined __GNUC__ && LFDS710_PAL_GCC_VERSION >= 412 && LFDS710_PAL_GCC_VERSION < 473 )
269
270   #ifdef LFDS710_PAL_COMPILER
271     #error More than one porting abstraction layer matches the current platform in lfds710_porting_abstraction_layer_compiler.h
272   #endif
273
274   #define LFDS710_PAL_COMPILER
275
276   #define LFDS710_PAL_COMPILER_STRING          "GCC < 4.7.3"
277
278   #define LFDS710_PAL_ALIGN(alignment)         __attribute__( (aligned(alignment)) )
279   #define LFDS710_PAL_INLINE                   inline
280
281   static LFDS710_PAL_INLINE void lfds710_pal_barrier_compiler( void )
282   {
283     __asm__ __volatile__ ( "" : : : "memory" );
284   }
285
286   #define LFDS710_PAL_BARRIER_COMPILER_LOAD    lfds710_pal_barrier_compiler()
287   #define LFDS710_PAL_BARRIER_COMPILER_STORE   lfds710_pal_barrier_compiler()
288   #define LFDS710_PAL_BARRIER_COMPILER_FULL    lfds710_pal_barrier_compiler()
289
290   #define LFDS710_PAL_BARRIER_PROCESSOR_LOAD   __sync_synchronize()
291   #define LFDS710_PAL_BARRIER_PROCESSOR_STORE  __sync_synchronize()
292   #define LFDS710_PAL_BARRIER_PROCESSOR_FULL   __sync_synchronize()
293
294   #define LFDS710_PAL_ATOMIC_ADD( pointer_to_target, value, result, result_type )                                               \
295   {                                                                                                                             \
296     LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                          \
297     (result) = (result_type) __sync_add_and_fetch( (lfds710_pal_uint_t *) (pointer_to_target), (lfds710_pal_uint_t) (value) );  \
298     LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                          \
299   }
300
301   #define LFDS710_PAL_ATOMIC_CAS( pointer_to_destination, pointer_to_compare, new_destination, cas_strength, result )       \
302   {                                                                                                                         \
303     lfds710_pal_uint_t                                                                                                      \
304       original_compare;                                                                                                     \
305                                                                                                                             \
306     original_compare = (lfds710_pal_uint_t) *(pointer_to_compare);                                                          \
307                                                                                                                             \
308     LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                      \
309     *(pointer_to_compare) = __sync_val_compare_and_swap( pointer_to_destination, *(pointer_to_compare), new_destination );  \
310     LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                      \
311                                                                                                                             \
312     result = (unsigned char) ( original_compare == (lfds710_pal_uint_t) *(pointer_to_compare) );                            \
313   }
314
315   // TRD : ARM and x86 have DWCAS which we can get via GCC intrinsics
316   #if( defined __arm__ || defined __i686__ || defined __i586__ || defined __i486__ )
317     #define LFDS710_PAL_ATOMIC_DWCAS( pointer_to_destination, pointer_to_compare, pointer_to_new_destination, cas_strength, result )                                                                                                   \
318     {                                                                                                                                                                                                                                  \
319       int long long unsigned                                                                                                                                                                                                           \
320         original_destination;                                                                                                                                                                                                          \
321                                                                                                                                                                                                                                        \
322       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                                                                                                                               \
323       original_destination = __sync_val_compare_and_swap( (int long long unsigned volatile *) (pointer_to_destination), *(int long long unsigned *) (pointer_to_compare), *(int long long unsigned *) (pointer_to_new_destination) );  \
324       LFDS710_PAL_BARRIER_COMPILER_FULL;                                                                                                                                                                                               \
325                                                                                                                                                                                                                                        \
326       (result) = (char unsigned) ( original_destination == *(int long long unsigned *) (pointer_to_compare) );                                                                                                                         \
327                                                                                                                                                                                                                                        \
328       *(int long long unsigned *) (pointer_to_compare) = original_destination;                                                                                                                                                         \
329     }
330   #endif
331
332   #define LFDS710_PAL_ATOMIC_EXCHANGE( pointer_to_destination, exchange, exchange_type )          \
333   {                                                                                               \
334     /* LFDS710_PAL_ASSERT( (pointer_to_destination) != NULL ); */                                 \
335     /* TRD : exchange can be any value in its range */                                            \
336     /* TRD : exchange_type can be any value in its range */                                       \
337                                                                                                   \
338     LFDS710_PAL_BARRIER_COMPILER_FULL;                                                            \
339     (exchange) = (exchange_type) __sync_lock_test_and_set( pointer_to_destination, (exchange) );  \
340     LFDS710_PAL_BARRIER_COMPILER_FULL;                                                            \
341   }
342
343   #define LFDS710_PAL_ATOMIC_SET( pointer_to_destination, new_value )        \
344   {                                                                          \
345     LFDS710_PAL_BARRIER_COMPILER_FULL;                                       \
346     (void) __sync_lock_test_and_set( pointer_to_destination, (new_value) );  \
347     LFDS710_PAL_BARRIER_COMPILER_FULL;                                       \
348   }
349
350 #endif
351
352
353
354
355
356 /****************************************************************************/
357 #if( defined __GNUC__ && LFDS710_PAL_GCC_VERSION >= 473 )
358
359   #ifdef LFDS710_PAL_COMPILER
360     #error More than one porting abstraction layer matches the current platform in lfds710_porting_abstraction_layer_compiler.h
361   #endif
362
363   #define LFDS710_PAL_COMPILER
364
365   #define LFDS710_PAL_COMPILER_STRING          "GCC >= 4.7.3"
366
367   #define LFDS710_PAL_ALIGN(alignment)         __attribute__( (aligned(alignment)) )
368   #define LFDS710_PAL_INLINE                   inline
369
370   // TRD : GCC >= 4.7.3 compiler barriers are built into the intrinsics
371   #define LFDS710_PAL_COMPILER_BARRIERS_MISSING_PRESUMED_HAVING_A_GOOD_TIME
372
373   #define LFDS710_PAL_BARRIER_PROCESSOR_LOAD   __atomic_thread_fence( __ATOMIC_ACQUIRE )
374   #define LFDS710_PAL_BARRIER_PROCESSOR_STORE  __atomic_thread_fence( __ATOMIC_RELEASE )
375   #define LFDS710_PAL_BARRIER_PROCESSOR_FULL   __atomic_thread_fence( __ATOMIC_ACQ_REL )
376
377   #define LFDS710_PAL_ATOMIC_ADD( pointer_to_target, value, result, result_type )                   \
378   {                                                                                                 \
379     (result) = (result_type) __atomic_add_fetch( (pointer_to_target), (value), __ATOMIC_RELAXED );  \
380   }
381
382   #define LFDS710_PAL_ATOMIC_CAS( pointer_to_destination, pointer_to_compare, new_destination, cas_strength, result )                                                       \
383   {                                                                                                                                                                         \
384     result = (char unsigned) __atomic_compare_exchange_n( pointer_to_destination, pointer_to_compare, new_destination, cas_strength, __ATOMIC_RELAXED, __ATOMIC_RELAXED );  \
385   }
386
387   // TRD : ARM and x86 have DWCAS which we can get via GCC intrinsics
388   #if( defined __arm__ || defined __i686__ || defined __i586__ || defined __i486__ )
389     #define LFDS710_PAL_ATOMIC_DWCAS( pointer_to_destination, pointer_to_compare, pointer_to_new_destination, cas_strength, result )                                                                                                                                                          \
390     {                                                                                                                                                                                                                                                                                         \
391       (result) = (char unsigned) __atomic_compare_exchange_n( (int long long unsigned volatile *) (pointer_to_destination), (int long long unsigned *) (pointer_to_compare), *(int long long unsigned *) (pointer_to_new_destination), (cas_strength), __ATOMIC_RELAXED, __ATOMIC_RELAXED );  \
392     }
393   #endif
394
395   #if( defined __x86_64__ )
396     /* TRD : On 64 bit platforms, unsigned long long int is 64 bit, so we must manually use cmpxchg16b, 
397              as __sync_val_compare_and_swap() will only emit cmpxchg8b
398     */
399
400     // TRD : lfds710_pal_uint_t volatile (*destination)[2], lfds710_pal_uint_t (*compare)[2], lfds710_pal_uint_t (*new_destination)[2], enum lfds710_misc_cas_strength cas_strength, char unsigned result
401
402     #define LFDS710_PAL_ATOMIC_DWCAS( pointer_to_destination, pointer_to_compare, pointer_to_new_destination, cas_strength, result )                             \
403     {                                                                                                                                                            \
404       (result) = 0;                                                                                                                                              \
405                                                                                                                                                                  \
406       __asm__ __volatile__                                                                                                                                       \
407       (                                                                                                                                                          \
408         "lock;"           /* make cmpxchg16b atomic        */                                                                                                    \
409         "cmpxchg16b %0;"  /* cmpxchg16b sets ZF on success */                                                                                                    \
410         "setz       %4;"  /* if ZF set, set result to 1    */                                                                                                    \
411                                                                                                                                                                  \
412         /* output */                                                                                                                                             \
413         : "+m" ((pointer_to_destination)[0]), "+m" ((pointer_to_destination)[1]), "+a" ((pointer_to_compare)[0]), "+d" ((pointer_to_compare)[1]), "=q" (result)  \
414                                                                                                                                                                  \
415         /* input */                                                                                                                                              \
416         : "b" ((pointer_to_new_destination)[0]), "c" ((pointer_to_new_destination)[1])                                                                           \
417                                                                                                                                                                  \
418         /* clobbered */                                                                                                                                          \
419         :                                                                                                                                                        \
420       );                                                                                                                                                         \
421     }
422   #endif
423
424   #define LFDS710_PAL_ATOMIC_EXCHANGE( pointer_to_destination, exchange, exchange_type )                         \
425   {                                                                                                              \
426     (exchange) = (exchange_type) __atomic_exchange_n( (pointer_to_destination), (exchange), __ATOMIC_RELAXED );  \
427   }
428
429   #define LFDS710_PAL_ATOMIC_SET( pointer_to_destination, new_value )                       \
430   {                                                                                         \
431     (void) __atomic_exchange_n( (pointer_to_destination), (new_value), __ATOMIC_RELAXED );  \
432   }
433
434 #endif
435
436
437
438
439
440 /****************************************************************************/
441 #if( !defined LFDS710_PAL_COMPILER )
442
443   #error No matching porting abstraction layer in lfds710_porting_abstraction_layer_compiler.h
444
445 #endif
446