17cc577a4SJonathan Peyton /*
2de4749b7SJonathan Peyton  * kmp_atomic.cpp -- ATOMIC implementation routines
37cc577a4SJonathan Peyton  */
47cc577a4SJonathan Peyton 
57cc577a4SJonathan Peyton //===----------------------------------------------------------------------===//
67cc577a4SJonathan Peyton //
757b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
857b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
957b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
107cc577a4SJonathan Peyton //
117cc577a4SJonathan Peyton //===----------------------------------------------------------------------===//
127cc577a4SJonathan Peyton 
137cc577a4SJonathan Peyton #include "kmp_atomic.h"
147cc577a4SJonathan Peyton #include "kmp.h" // TRUE, asm routines prototypes
157cc577a4SJonathan Peyton 
167cc577a4SJonathan Peyton typedef unsigned char uchar;
177cc577a4SJonathan Peyton typedef unsigned short ushort;
187cc577a4SJonathan Peyton 
197cc577a4SJonathan Peyton /*!
207cc577a4SJonathan Peyton @defgroup ATOMIC_OPS Atomic Operations
213041982dSJonathan Peyton These functions are used for implementing the many different varieties of atomic
223041982dSJonathan Peyton operations.
237cc577a4SJonathan Peyton 
243041982dSJonathan Peyton The compiler is at liberty to inline atomic operations that are naturally
253041982dSJonathan Peyton supported by the target architecture. For instance on IA-32 architecture an
263041982dSJonathan Peyton atomic like this can be inlined
277cc577a4SJonathan Peyton @code
287cc577a4SJonathan Peyton static int s = 0;
297cc577a4SJonathan Peyton #pragma omp atomic
307cc577a4SJonathan Peyton     s++;
317cc577a4SJonathan Peyton @endcode
327cc577a4SJonathan Peyton using the single instruction: `lock; incl s`
337cc577a4SJonathan Peyton 
343041982dSJonathan Peyton However the runtime does provide entrypoints for these operations to support
353041982dSJonathan Peyton compilers that choose not to inline them. (For instance,
363041982dSJonathan Peyton `__kmpc_atomic_fixed4_add` could be used to perform the increment above.)
377cc577a4SJonathan Peyton 
383041982dSJonathan Peyton The names of the functions are encoded by using the data type name and the
393041982dSJonathan Peyton operation name, as in these tables.
407cc577a4SJonathan Peyton 
417cc577a4SJonathan Peyton Data Type  | Data type encoding
427cc577a4SJonathan Peyton -----------|---------------
437cc577a4SJonathan Peyton int8_t     | `fixed1`
447cc577a4SJonathan Peyton uint8_t    | `fixed1u`
457cc577a4SJonathan Peyton int16_t    | `fixed2`
467cc577a4SJonathan Peyton uint16_t   | `fixed2u`
477cc577a4SJonathan Peyton int32_t    | `fixed4`
487cc577a4SJonathan Peyton uint32_t   | `fixed4u`
497cc577a4SJonathan Peyton int32_t    | `fixed8`
507cc577a4SJonathan Peyton uint32_t   | `fixed8u`
517cc577a4SJonathan Peyton float      | `float4`
527cc577a4SJonathan Peyton double     | `float8`
537cc577a4SJonathan Peyton float 10 (8087 eighty bit float)  | `float10`
547cc577a4SJonathan Peyton complex<float>   |  `cmplx4`
557cc577a4SJonathan Peyton complex<double>  | `cmplx8`
567cc577a4SJonathan Peyton complex<float10> | `cmplx10`
577cc577a4SJonathan Peyton <br>
587cc577a4SJonathan Peyton 
597cc577a4SJonathan Peyton Operation | Operation encoding
607cc577a4SJonathan Peyton ----------|-------------------
617cc577a4SJonathan Peyton + | add
627cc577a4SJonathan Peyton - | sub
637cc577a4SJonathan Peyton \* | mul
647cc577a4SJonathan Peyton / | div
657cc577a4SJonathan Peyton & | andb
667cc577a4SJonathan Peyton << | shl
677cc577a4SJonathan Peyton \>\> | shr
687cc577a4SJonathan Peyton \| | orb
697cc577a4SJonathan Peyton ^  | xor
707cc577a4SJonathan Peyton && | andl
717cc577a4SJonathan Peyton \|\| | orl
727cc577a4SJonathan Peyton maximum | max
737cc577a4SJonathan Peyton minimum | min
747cc577a4SJonathan Peyton .eqv.   | eqv
757cc577a4SJonathan Peyton .neqv.  | neqv
767cc577a4SJonathan Peyton 
777cc577a4SJonathan Peyton <br>
783041982dSJonathan Peyton For non-commutative operations, `_rev` can also be added for the reversed
793041982dSJonathan Peyton operation. For the functions that capture the result, the suffix `_cpt` is
803041982dSJonathan Peyton added.
817cc577a4SJonathan Peyton 
827cc577a4SJonathan Peyton Update Functions
837cc577a4SJonathan Peyton ================
843041982dSJonathan Peyton The general form of an atomic function that just performs an update (without a
853041982dSJonathan Peyton `capture`)
867cc577a4SJonathan Peyton @code
873041982dSJonathan Peyton void __kmpc_atomic_<datatype>_<operation>( ident_t *id_ref, int gtid, TYPE *
883041982dSJonathan Peyton lhs, TYPE rhs );
897cc577a4SJonathan Peyton @endcode
907cc577a4SJonathan Peyton @param ident_t  a pointer to source location
917cc577a4SJonathan Peyton @param gtid  the global thread id
927cc577a4SJonathan Peyton @param lhs   a pointer to the left operand
937cc577a4SJonathan Peyton @param rhs   the right operand
947cc577a4SJonathan Peyton 
957cc577a4SJonathan Peyton `capture` functions
967cc577a4SJonathan Peyton ===================
973041982dSJonathan Peyton The capture functions perform an atomic update and return a result, which is
983041982dSJonathan Peyton either the value before the capture, or that after. They take an additional
993041982dSJonathan Peyton argument to determine which result is returned.
1007cc577a4SJonathan Peyton Their general form is therefore
1017cc577a4SJonathan Peyton @code
1023041982dSJonathan Peyton TYPE __kmpc_atomic_<datatype>_<operation>_cpt( ident_t *id_ref, int gtid, TYPE *
1033041982dSJonathan Peyton lhs, TYPE rhs, int flag );
1047cc577a4SJonathan Peyton @endcode
1057cc577a4SJonathan Peyton @param ident_t  a pointer to source location
1067cc577a4SJonathan Peyton @param gtid  the global thread id
1077cc577a4SJonathan Peyton @param lhs   a pointer to the left operand
1087cc577a4SJonathan Peyton @param rhs   the right operand
1093041982dSJonathan Peyton @param flag  one if the result is to be captured *after* the operation, zero if
1103041982dSJonathan Peyton captured *before*.
1117cc577a4SJonathan Peyton 
1123041982dSJonathan Peyton The one set of exceptions to this is the `complex<float>` type where the value
1133041982dSJonathan Peyton is not returned, rather an extra argument pointer is passed.
1147cc577a4SJonathan Peyton 
1157cc577a4SJonathan Peyton They look like
1167cc577a4SJonathan Peyton @code
1173041982dSJonathan Peyton void __kmpc_atomic_cmplx4_<op>_cpt(  ident_t *id_ref, int gtid, kmp_cmplx32 *
1183041982dSJonathan Peyton lhs, kmp_cmplx32 rhs, kmp_cmplx32 * out, int flag );
1197cc577a4SJonathan Peyton @endcode
1207cc577a4SJonathan Peyton 
1217cc577a4SJonathan Peyton Read and Write Operations
1227cc577a4SJonathan Peyton =========================
1233041982dSJonathan Peyton The OpenMP<sup>*</sup> standard now supports atomic operations that simply
1243041982dSJonathan Peyton ensure that the value is read or written atomically, with no modification
1253041982dSJonathan Peyton performed. In many cases on IA-32 architecture these operations can be inlined
1263041982dSJonathan Peyton since the architecture guarantees that no tearing occurs on aligned objects
1277cc577a4SJonathan Peyton accessed with a single memory operation of up to 64 bits in size.
1287cc577a4SJonathan Peyton 
1297cc577a4SJonathan Peyton The general form of the read operations is
1307cc577a4SJonathan Peyton @code
1317cc577a4SJonathan Peyton TYPE __kmpc_atomic_<type>_rd ( ident_t *id_ref, int gtid, TYPE * loc );
1327cc577a4SJonathan Peyton @endcode
1337cc577a4SJonathan Peyton 
1347cc577a4SJonathan Peyton For the write operations the form is
1357cc577a4SJonathan Peyton @code
1363041982dSJonathan Peyton void __kmpc_atomic_<type>_wr ( ident_t *id_ref, int gtid, TYPE * lhs, TYPE rhs
1373041982dSJonathan Peyton );
1387cc577a4SJonathan Peyton @endcode
1397cc577a4SJonathan Peyton 
1407cc577a4SJonathan Peyton Full list of functions
1417cc577a4SJonathan Peyton ======================
1427cc577a4SJonathan Peyton This leads to the generation of 376 atomic functions, as follows.
1437cc577a4SJonathan Peyton 
1444c6a098aSKazuaki Ishizaki Functions for integers
1457cc577a4SJonathan Peyton ---------------------
1463041982dSJonathan Peyton There are versions here for integers of size 1,2,4 and 8 bytes both signed and
1473041982dSJonathan Peyton unsigned (where that matters).
1487cc577a4SJonathan Peyton @code
1497cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_add
1507cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_add_cpt
1517cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_add_fp
1527cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_andb
1537cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_andb_cpt
1547cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_andl
1557cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_andl_cpt
1567cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_div
1577cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_div_cpt
1587cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_div_cpt_rev
1597cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_div_float8
1607cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_div_fp
1617cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_div_rev
1627cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_eqv
1637cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_eqv_cpt
1647cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_max
1657cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_max_cpt
1667cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_min
1677cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_min_cpt
1687cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_mul
1697cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_mul_cpt
1707cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_mul_float8
1717cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_mul_fp
1727cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_neqv
1737cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_neqv_cpt
1747cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_orb
1757cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_orb_cpt
1767cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_orl
1777cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_orl_cpt
1787cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_rd
1797cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_shl
1807cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_shl_cpt
1817cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_shl_cpt_rev
1827cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_shl_rev
1837cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_shr
1847cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_shr_cpt
1857cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_shr_cpt_rev
1867cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_shr_rev
1877cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_sub
1887cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_sub_cpt
1897cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_sub_cpt_rev
1907cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_sub_fp
1917cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_sub_rev
1927cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_swp
1937cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_wr
1947cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_xor
1957cc577a4SJonathan Peyton     __kmpc_atomic_fixed1_xor_cpt
1967cc577a4SJonathan Peyton     __kmpc_atomic_fixed1u_add_fp
1977cc577a4SJonathan Peyton     __kmpc_atomic_fixed1u_sub_fp
1987cc577a4SJonathan Peyton     __kmpc_atomic_fixed1u_mul_fp
1997cc577a4SJonathan Peyton     __kmpc_atomic_fixed1u_div
2007cc577a4SJonathan Peyton     __kmpc_atomic_fixed1u_div_cpt
2017cc577a4SJonathan Peyton     __kmpc_atomic_fixed1u_div_cpt_rev
2027cc577a4SJonathan Peyton     __kmpc_atomic_fixed1u_div_fp
2037cc577a4SJonathan Peyton     __kmpc_atomic_fixed1u_div_rev
2047cc577a4SJonathan Peyton     __kmpc_atomic_fixed1u_shr
2057cc577a4SJonathan Peyton     __kmpc_atomic_fixed1u_shr_cpt
2067cc577a4SJonathan Peyton     __kmpc_atomic_fixed1u_shr_cpt_rev
2077cc577a4SJonathan Peyton     __kmpc_atomic_fixed1u_shr_rev
2087cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_add
2097cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_add_cpt
2107cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_add_fp
2117cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_andb
2127cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_andb_cpt
2137cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_andl
2147cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_andl_cpt
2157cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_div
2167cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_div_cpt
2177cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_div_cpt_rev
2187cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_div_float8
2197cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_div_fp
2207cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_div_rev
2217cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_eqv
2227cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_eqv_cpt
2237cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_max
2247cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_max_cpt
2257cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_min
2267cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_min_cpt
2277cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_mul
2287cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_mul_cpt
2297cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_mul_float8
2307cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_mul_fp
2317cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_neqv
2327cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_neqv_cpt
2337cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_orb
2347cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_orb_cpt
2357cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_orl
2367cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_orl_cpt
2377cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_rd
2387cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_shl
2397cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_shl_cpt
2407cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_shl_cpt_rev
2417cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_shl_rev
2427cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_shr
2437cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_shr_cpt
2447cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_shr_cpt_rev
2457cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_shr_rev
2467cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_sub
2477cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_sub_cpt
2487cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_sub_cpt_rev
2497cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_sub_fp
2507cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_sub_rev
2517cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_swp
2527cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_wr
2537cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_xor
2547cc577a4SJonathan Peyton     __kmpc_atomic_fixed2_xor_cpt
2557cc577a4SJonathan Peyton     __kmpc_atomic_fixed2u_add_fp
2567cc577a4SJonathan Peyton     __kmpc_atomic_fixed2u_sub_fp
2577cc577a4SJonathan Peyton     __kmpc_atomic_fixed2u_mul_fp
2587cc577a4SJonathan Peyton     __kmpc_atomic_fixed2u_div
2597cc577a4SJonathan Peyton     __kmpc_atomic_fixed2u_div_cpt
2607cc577a4SJonathan Peyton     __kmpc_atomic_fixed2u_div_cpt_rev
2617cc577a4SJonathan Peyton     __kmpc_atomic_fixed2u_div_fp
2627cc577a4SJonathan Peyton     __kmpc_atomic_fixed2u_div_rev
2637cc577a4SJonathan Peyton     __kmpc_atomic_fixed2u_shr
2647cc577a4SJonathan Peyton     __kmpc_atomic_fixed2u_shr_cpt
2657cc577a4SJonathan Peyton     __kmpc_atomic_fixed2u_shr_cpt_rev
2667cc577a4SJonathan Peyton     __kmpc_atomic_fixed2u_shr_rev
2677cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_add
2687cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_add_cpt
2697cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_add_fp
2707cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_andb
2717cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_andb_cpt
2727cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_andl
2737cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_andl_cpt
2747cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_div
2757cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_div_cpt
2767cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_div_cpt_rev
2777cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_div_float8
2787cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_div_fp
2797cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_div_rev
2807cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_eqv
2817cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_eqv_cpt
2827cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_max
2837cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_max_cpt
2847cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_min
2857cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_min_cpt
2867cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_mul
2877cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_mul_cpt
2887cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_mul_float8
2897cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_mul_fp
2907cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_neqv
2917cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_neqv_cpt
2927cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_orb
2937cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_orb_cpt
2947cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_orl
2957cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_orl_cpt
2967cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_rd
2977cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_shl
2987cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_shl_cpt
2997cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_shl_cpt_rev
3007cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_shl_rev
3017cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_shr
3027cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_shr_cpt
3037cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_shr_cpt_rev
3047cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_shr_rev
3057cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_sub
3067cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_sub_cpt
3077cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_sub_cpt_rev
3087cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_sub_fp
3097cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_sub_rev
3107cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_swp
3117cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_wr
3127cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_xor
3137cc577a4SJonathan Peyton     __kmpc_atomic_fixed4_xor_cpt
3147cc577a4SJonathan Peyton     __kmpc_atomic_fixed4u_add_fp
3157cc577a4SJonathan Peyton     __kmpc_atomic_fixed4u_sub_fp
3167cc577a4SJonathan Peyton     __kmpc_atomic_fixed4u_mul_fp
3177cc577a4SJonathan Peyton     __kmpc_atomic_fixed4u_div
3187cc577a4SJonathan Peyton     __kmpc_atomic_fixed4u_div_cpt
3197cc577a4SJonathan Peyton     __kmpc_atomic_fixed4u_div_cpt_rev
3207cc577a4SJonathan Peyton     __kmpc_atomic_fixed4u_div_fp
3217cc577a4SJonathan Peyton     __kmpc_atomic_fixed4u_div_rev
3227cc577a4SJonathan Peyton     __kmpc_atomic_fixed4u_shr
3237cc577a4SJonathan Peyton     __kmpc_atomic_fixed4u_shr_cpt
3247cc577a4SJonathan Peyton     __kmpc_atomic_fixed4u_shr_cpt_rev
3257cc577a4SJonathan Peyton     __kmpc_atomic_fixed4u_shr_rev
3267cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_add
3277cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_add_cpt
3287cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_add_fp
3297cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_andb
3307cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_andb_cpt
3317cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_andl
3327cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_andl_cpt
3337cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_div
3347cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_div_cpt
3357cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_div_cpt_rev
3367cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_div_float8
3377cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_div_fp
3387cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_div_rev
3397cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_eqv
3407cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_eqv_cpt
3417cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_max
3427cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_max_cpt
3437cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_min
3447cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_min_cpt
3457cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_mul
3467cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_mul_cpt
3477cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_mul_float8
3487cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_mul_fp
3497cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_neqv
3507cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_neqv_cpt
3517cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_orb
3527cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_orb_cpt
3537cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_orl
3547cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_orl_cpt
3557cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_rd
3567cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_shl
3577cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_shl_cpt
3587cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_shl_cpt_rev
3597cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_shl_rev
3607cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_shr
3617cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_shr_cpt
3627cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_shr_cpt_rev
3637cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_shr_rev
3647cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_sub
3657cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_sub_cpt
3667cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_sub_cpt_rev
3677cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_sub_fp
3687cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_sub_rev
3697cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_swp
3707cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_wr
3717cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_xor
3727cc577a4SJonathan Peyton     __kmpc_atomic_fixed8_xor_cpt
3737cc577a4SJonathan Peyton     __kmpc_atomic_fixed8u_add_fp
3747cc577a4SJonathan Peyton     __kmpc_atomic_fixed8u_sub_fp
3757cc577a4SJonathan Peyton     __kmpc_atomic_fixed8u_mul_fp
3767cc577a4SJonathan Peyton     __kmpc_atomic_fixed8u_div
3777cc577a4SJonathan Peyton     __kmpc_atomic_fixed8u_div_cpt
3787cc577a4SJonathan Peyton     __kmpc_atomic_fixed8u_div_cpt_rev
3797cc577a4SJonathan Peyton     __kmpc_atomic_fixed8u_div_fp
3807cc577a4SJonathan Peyton     __kmpc_atomic_fixed8u_div_rev
3817cc577a4SJonathan Peyton     __kmpc_atomic_fixed8u_shr
3827cc577a4SJonathan Peyton     __kmpc_atomic_fixed8u_shr_cpt
3837cc577a4SJonathan Peyton     __kmpc_atomic_fixed8u_shr_cpt_rev
3847cc577a4SJonathan Peyton     __kmpc_atomic_fixed8u_shr_rev
3857cc577a4SJonathan Peyton @endcode
3867cc577a4SJonathan Peyton 
3877cc577a4SJonathan Peyton Functions for floating point
3887cc577a4SJonathan Peyton ----------------------------
3893041982dSJonathan Peyton There are versions here for floating point numbers of size 4, 8, 10 and 16
3903041982dSJonathan Peyton bytes. (Ten byte floats are used by X87, but are now rare).
3917cc577a4SJonathan Peyton @code
3927cc577a4SJonathan Peyton     __kmpc_atomic_float4_add
3937cc577a4SJonathan Peyton     __kmpc_atomic_float4_add_cpt
3947cc577a4SJonathan Peyton     __kmpc_atomic_float4_add_float8
3957cc577a4SJonathan Peyton     __kmpc_atomic_float4_add_fp
3967cc577a4SJonathan Peyton     __kmpc_atomic_float4_div
3977cc577a4SJonathan Peyton     __kmpc_atomic_float4_div_cpt
3987cc577a4SJonathan Peyton     __kmpc_atomic_float4_div_cpt_rev
3997cc577a4SJonathan Peyton     __kmpc_atomic_float4_div_float8
4007cc577a4SJonathan Peyton     __kmpc_atomic_float4_div_fp
4017cc577a4SJonathan Peyton     __kmpc_atomic_float4_div_rev
4027cc577a4SJonathan Peyton     __kmpc_atomic_float4_max
4037cc577a4SJonathan Peyton     __kmpc_atomic_float4_max_cpt
4047cc577a4SJonathan Peyton     __kmpc_atomic_float4_min
4057cc577a4SJonathan Peyton     __kmpc_atomic_float4_min_cpt
4067cc577a4SJonathan Peyton     __kmpc_atomic_float4_mul
4077cc577a4SJonathan Peyton     __kmpc_atomic_float4_mul_cpt
4087cc577a4SJonathan Peyton     __kmpc_atomic_float4_mul_float8
4097cc577a4SJonathan Peyton     __kmpc_atomic_float4_mul_fp
4107cc577a4SJonathan Peyton     __kmpc_atomic_float4_rd
4117cc577a4SJonathan Peyton     __kmpc_atomic_float4_sub
4127cc577a4SJonathan Peyton     __kmpc_atomic_float4_sub_cpt
4137cc577a4SJonathan Peyton     __kmpc_atomic_float4_sub_cpt_rev
4147cc577a4SJonathan Peyton     __kmpc_atomic_float4_sub_float8
4157cc577a4SJonathan Peyton     __kmpc_atomic_float4_sub_fp
4167cc577a4SJonathan Peyton     __kmpc_atomic_float4_sub_rev
4177cc577a4SJonathan Peyton     __kmpc_atomic_float4_swp
4187cc577a4SJonathan Peyton     __kmpc_atomic_float4_wr
4197cc577a4SJonathan Peyton     __kmpc_atomic_float8_add
4207cc577a4SJonathan Peyton     __kmpc_atomic_float8_add_cpt
4217cc577a4SJonathan Peyton     __kmpc_atomic_float8_add_fp
4227cc577a4SJonathan Peyton     __kmpc_atomic_float8_div
4237cc577a4SJonathan Peyton     __kmpc_atomic_float8_div_cpt
4247cc577a4SJonathan Peyton     __kmpc_atomic_float8_div_cpt_rev
4257cc577a4SJonathan Peyton     __kmpc_atomic_float8_div_fp
4267cc577a4SJonathan Peyton     __kmpc_atomic_float8_div_rev
4277cc577a4SJonathan Peyton     __kmpc_atomic_float8_max
4287cc577a4SJonathan Peyton     __kmpc_atomic_float8_max_cpt
4297cc577a4SJonathan Peyton     __kmpc_atomic_float8_min
4307cc577a4SJonathan Peyton     __kmpc_atomic_float8_min_cpt
4317cc577a4SJonathan Peyton     __kmpc_atomic_float8_mul
4327cc577a4SJonathan Peyton     __kmpc_atomic_float8_mul_cpt
4337cc577a4SJonathan Peyton     __kmpc_atomic_float8_mul_fp
4347cc577a4SJonathan Peyton     __kmpc_atomic_float8_rd
4357cc577a4SJonathan Peyton     __kmpc_atomic_float8_sub
4367cc577a4SJonathan Peyton     __kmpc_atomic_float8_sub_cpt
4377cc577a4SJonathan Peyton     __kmpc_atomic_float8_sub_cpt_rev
4387cc577a4SJonathan Peyton     __kmpc_atomic_float8_sub_fp
4397cc577a4SJonathan Peyton     __kmpc_atomic_float8_sub_rev
4407cc577a4SJonathan Peyton     __kmpc_atomic_float8_swp
4417cc577a4SJonathan Peyton     __kmpc_atomic_float8_wr
4427cc577a4SJonathan Peyton     __kmpc_atomic_float10_add
4437cc577a4SJonathan Peyton     __kmpc_atomic_float10_add_cpt
4447cc577a4SJonathan Peyton     __kmpc_atomic_float10_add_fp
4457cc577a4SJonathan Peyton     __kmpc_atomic_float10_div
4467cc577a4SJonathan Peyton     __kmpc_atomic_float10_div_cpt
4477cc577a4SJonathan Peyton     __kmpc_atomic_float10_div_cpt_rev
4487cc577a4SJonathan Peyton     __kmpc_atomic_float10_div_fp
4497cc577a4SJonathan Peyton     __kmpc_atomic_float10_div_rev
4507cc577a4SJonathan Peyton     __kmpc_atomic_float10_mul
4517cc577a4SJonathan Peyton     __kmpc_atomic_float10_mul_cpt
4527cc577a4SJonathan Peyton     __kmpc_atomic_float10_mul_fp
4537cc577a4SJonathan Peyton     __kmpc_atomic_float10_rd
4547cc577a4SJonathan Peyton     __kmpc_atomic_float10_sub
4557cc577a4SJonathan Peyton     __kmpc_atomic_float10_sub_cpt
4567cc577a4SJonathan Peyton     __kmpc_atomic_float10_sub_cpt_rev
4577cc577a4SJonathan Peyton     __kmpc_atomic_float10_sub_fp
4587cc577a4SJonathan Peyton     __kmpc_atomic_float10_sub_rev
4597cc577a4SJonathan Peyton     __kmpc_atomic_float10_swp
4607cc577a4SJonathan Peyton     __kmpc_atomic_float10_wr
4617cc577a4SJonathan Peyton     __kmpc_atomic_float16_add
4627cc577a4SJonathan Peyton     __kmpc_atomic_float16_add_cpt
4637cc577a4SJonathan Peyton     __kmpc_atomic_float16_div
4647cc577a4SJonathan Peyton     __kmpc_atomic_float16_div_cpt
4657cc577a4SJonathan Peyton     __kmpc_atomic_float16_div_cpt_rev
4667cc577a4SJonathan Peyton     __kmpc_atomic_float16_div_rev
4677cc577a4SJonathan Peyton     __kmpc_atomic_float16_max
4687cc577a4SJonathan Peyton     __kmpc_atomic_float16_max_cpt
4697cc577a4SJonathan Peyton     __kmpc_atomic_float16_min
4707cc577a4SJonathan Peyton     __kmpc_atomic_float16_min_cpt
4717cc577a4SJonathan Peyton     __kmpc_atomic_float16_mul
4727cc577a4SJonathan Peyton     __kmpc_atomic_float16_mul_cpt
4737cc577a4SJonathan Peyton     __kmpc_atomic_float16_rd
4747cc577a4SJonathan Peyton     __kmpc_atomic_float16_sub
4757cc577a4SJonathan Peyton     __kmpc_atomic_float16_sub_cpt
4767cc577a4SJonathan Peyton     __kmpc_atomic_float16_sub_cpt_rev
4777cc577a4SJonathan Peyton     __kmpc_atomic_float16_sub_rev
4787cc577a4SJonathan Peyton     __kmpc_atomic_float16_swp
4797cc577a4SJonathan Peyton     __kmpc_atomic_float16_wr
4807cc577a4SJonathan Peyton @endcode
4817cc577a4SJonathan Peyton 
4827cc577a4SJonathan Peyton Functions for Complex types
4837cc577a4SJonathan Peyton ---------------------------
4843041982dSJonathan Peyton Functions for complex types whose component floating point variables are of size
4853041982dSJonathan Peyton 4,8,10 or 16 bytes. The names here are based on the size of the component float,
486ed5fe645SKelvin Li *not* the size of the complex type. So `__kmpc_atomic_cmplx8_add` is an
487ed5fe645SKelvin Li operation on a `complex<double>` or `complex(kind=8)`, *not* `complex<float>`.
4887cc577a4SJonathan Peyton 
4897cc577a4SJonathan Peyton @code
4907cc577a4SJonathan Peyton     __kmpc_atomic_cmplx4_add
4917cc577a4SJonathan Peyton     __kmpc_atomic_cmplx4_add_cmplx8
4927cc577a4SJonathan Peyton     __kmpc_atomic_cmplx4_add_cpt
4937cc577a4SJonathan Peyton     __kmpc_atomic_cmplx4_div
4947cc577a4SJonathan Peyton     __kmpc_atomic_cmplx4_div_cmplx8
4957cc577a4SJonathan Peyton     __kmpc_atomic_cmplx4_div_cpt
4967cc577a4SJonathan Peyton     __kmpc_atomic_cmplx4_div_cpt_rev
4977cc577a4SJonathan Peyton     __kmpc_atomic_cmplx4_div_rev
4987cc577a4SJonathan Peyton     __kmpc_atomic_cmplx4_mul
4997cc577a4SJonathan Peyton     __kmpc_atomic_cmplx4_mul_cmplx8
5007cc577a4SJonathan Peyton     __kmpc_atomic_cmplx4_mul_cpt
5017cc577a4SJonathan Peyton     __kmpc_atomic_cmplx4_rd
5027cc577a4SJonathan Peyton     __kmpc_atomic_cmplx4_sub
5037cc577a4SJonathan Peyton     __kmpc_atomic_cmplx4_sub_cmplx8
5047cc577a4SJonathan Peyton     __kmpc_atomic_cmplx4_sub_cpt
5057cc577a4SJonathan Peyton     __kmpc_atomic_cmplx4_sub_cpt_rev
5067cc577a4SJonathan Peyton     __kmpc_atomic_cmplx4_sub_rev
5077cc577a4SJonathan Peyton     __kmpc_atomic_cmplx4_swp
5087cc577a4SJonathan Peyton     __kmpc_atomic_cmplx4_wr
5097cc577a4SJonathan Peyton     __kmpc_atomic_cmplx8_add
5107cc577a4SJonathan Peyton     __kmpc_atomic_cmplx8_add_cpt
5117cc577a4SJonathan Peyton     __kmpc_atomic_cmplx8_div
5127cc577a4SJonathan Peyton     __kmpc_atomic_cmplx8_div_cpt
5137cc577a4SJonathan Peyton     __kmpc_atomic_cmplx8_div_cpt_rev
5147cc577a4SJonathan Peyton     __kmpc_atomic_cmplx8_div_rev
5157cc577a4SJonathan Peyton     __kmpc_atomic_cmplx8_mul
5167cc577a4SJonathan Peyton     __kmpc_atomic_cmplx8_mul_cpt
5177cc577a4SJonathan Peyton     __kmpc_atomic_cmplx8_rd
5187cc577a4SJonathan Peyton     __kmpc_atomic_cmplx8_sub
5197cc577a4SJonathan Peyton     __kmpc_atomic_cmplx8_sub_cpt
5207cc577a4SJonathan Peyton     __kmpc_atomic_cmplx8_sub_cpt_rev
5217cc577a4SJonathan Peyton     __kmpc_atomic_cmplx8_sub_rev
5227cc577a4SJonathan Peyton     __kmpc_atomic_cmplx8_swp
5237cc577a4SJonathan Peyton     __kmpc_atomic_cmplx8_wr
5247cc577a4SJonathan Peyton     __kmpc_atomic_cmplx10_add
5257cc577a4SJonathan Peyton     __kmpc_atomic_cmplx10_add_cpt
5267cc577a4SJonathan Peyton     __kmpc_atomic_cmplx10_div
5277cc577a4SJonathan Peyton     __kmpc_atomic_cmplx10_div_cpt
5287cc577a4SJonathan Peyton     __kmpc_atomic_cmplx10_div_cpt_rev
5297cc577a4SJonathan Peyton     __kmpc_atomic_cmplx10_div_rev
5307cc577a4SJonathan Peyton     __kmpc_atomic_cmplx10_mul
5317cc577a4SJonathan Peyton     __kmpc_atomic_cmplx10_mul_cpt
5327cc577a4SJonathan Peyton     __kmpc_atomic_cmplx10_rd
5337cc577a4SJonathan Peyton     __kmpc_atomic_cmplx10_sub
5347cc577a4SJonathan Peyton     __kmpc_atomic_cmplx10_sub_cpt
5357cc577a4SJonathan Peyton     __kmpc_atomic_cmplx10_sub_cpt_rev
5367cc577a4SJonathan Peyton     __kmpc_atomic_cmplx10_sub_rev
5377cc577a4SJonathan Peyton     __kmpc_atomic_cmplx10_swp
5387cc577a4SJonathan Peyton     __kmpc_atomic_cmplx10_wr
5397cc577a4SJonathan Peyton     __kmpc_atomic_cmplx16_add
5407cc577a4SJonathan Peyton     __kmpc_atomic_cmplx16_add_cpt
5417cc577a4SJonathan Peyton     __kmpc_atomic_cmplx16_div
5427cc577a4SJonathan Peyton     __kmpc_atomic_cmplx16_div_cpt
5437cc577a4SJonathan Peyton     __kmpc_atomic_cmplx16_div_cpt_rev
5447cc577a4SJonathan Peyton     __kmpc_atomic_cmplx16_div_rev
5457cc577a4SJonathan Peyton     __kmpc_atomic_cmplx16_mul
5467cc577a4SJonathan Peyton     __kmpc_atomic_cmplx16_mul_cpt
5477cc577a4SJonathan Peyton     __kmpc_atomic_cmplx16_rd
5487cc577a4SJonathan Peyton     __kmpc_atomic_cmplx16_sub
5497cc577a4SJonathan Peyton     __kmpc_atomic_cmplx16_sub_cpt
5507cc577a4SJonathan Peyton     __kmpc_atomic_cmplx16_sub_cpt_rev
5517cc577a4SJonathan Peyton     __kmpc_atomic_cmplx16_swp
5527cc577a4SJonathan Peyton     __kmpc_atomic_cmplx16_wr
5537cc577a4SJonathan Peyton @endcode
5547cc577a4SJonathan Peyton */
5557cc577a4SJonathan Peyton 
5567cc577a4SJonathan Peyton /*!
5577cc577a4SJonathan Peyton @ingroup ATOMIC_OPS
5587cc577a4SJonathan Peyton @{
5597cc577a4SJonathan Peyton */
5607cc577a4SJonathan Peyton 
5617cc577a4SJonathan Peyton /*
5627cc577a4SJonathan Peyton  * Global vars
5637cc577a4SJonathan Peyton  */
5647cc577a4SJonathan Peyton 
5657cc577a4SJonathan Peyton #ifndef KMP_GOMP_COMPAT
5667cc577a4SJonathan Peyton int __kmp_atomic_mode = 1; // Intel perf
5677cc577a4SJonathan Peyton #else
5687cc577a4SJonathan Peyton int __kmp_atomic_mode = 2; // GOMP compatibility
5697cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
5707cc577a4SJonathan Peyton 
5717cc577a4SJonathan Peyton KMP_ALIGN(128)
5727cc577a4SJonathan Peyton 
5733041982dSJonathan Peyton // Control access to all user coded atomics in Gnu compat mode
5743041982dSJonathan Peyton kmp_atomic_lock_t __kmp_atomic_lock;
5753041982dSJonathan Peyton // Control access to all user coded atomics for 1-byte fixed data types
5763041982dSJonathan Peyton kmp_atomic_lock_t __kmp_atomic_lock_1i;
5773041982dSJonathan Peyton // Control access to all user coded atomics for 2-byte fixed data types
5783041982dSJonathan Peyton kmp_atomic_lock_t __kmp_atomic_lock_2i;
5793041982dSJonathan Peyton // Control access to all user coded atomics for 4-byte fixed data types
5803041982dSJonathan Peyton kmp_atomic_lock_t __kmp_atomic_lock_4i;
5813041982dSJonathan Peyton // Control access to all user coded atomics for kmp_real32 data type
5823041982dSJonathan Peyton kmp_atomic_lock_t __kmp_atomic_lock_4r;
5833041982dSJonathan Peyton // Control access to all user coded atomics for 8-byte fixed data types
5843041982dSJonathan Peyton kmp_atomic_lock_t __kmp_atomic_lock_8i;
5853041982dSJonathan Peyton // Control access to all user coded atomics for kmp_real64 data type
5863041982dSJonathan Peyton kmp_atomic_lock_t __kmp_atomic_lock_8r;
5873041982dSJonathan Peyton // Control access to all user coded atomics for complex byte data type
5883041982dSJonathan Peyton kmp_atomic_lock_t __kmp_atomic_lock_8c;
5893041982dSJonathan Peyton // Control access to all user coded atomics for long double data type
5903041982dSJonathan Peyton kmp_atomic_lock_t __kmp_atomic_lock_10r;
5913041982dSJonathan Peyton // Control access to all user coded atomics for _Quad data type
5923041982dSJonathan Peyton kmp_atomic_lock_t __kmp_atomic_lock_16r;
5933041982dSJonathan Peyton // Control access to all user coded atomics for double complex data type
5943041982dSJonathan Peyton kmp_atomic_lock_t __kmp_atomic_lock_16c;
5953041982dSJonathan Peyton // Control access to all user coded atomics for long double complex type
5963041982dSJonathan Peyton kmp_atomic_lock_t __kmp_atomic_lock_20c;
5973041982dSJonathan Peyton // Control access to all user coded atomics for _Quad complex data type
5983041982dSJonathan Peyton kmp_atomic_lock_t __kmp_atomic_lock_32c;
5997cc577a4SJonathan Peyton 
6003041982dSJonathan Peyton /* 2007-03-02:
6013041982dSJonathan Peyton    Without "volatile" specifier in OP_CMPXCHG and MIN_MAX_CMPXCHG we have a bug
6023041982dSJonathan Peyton    on *_32 and *_32e. This is just a temporary workaround for the problem. It
6033041982dSJonathan Peyton    seems the right solution is writing OP_CMPXCHG and MIN_MAX_CMPXCHG routines
6043041982dSJonathan Peyton    in assembler language. */
6057cc577a4SJonathan Peyton #define KMP_ATOMIC_VOLATILE volatile
6067cc577a4SJonathan Peyton 
6077cc577a4SJonathan Peyton #if (KMP_ARCH_X86) && KMP_HAVE_QUAD
6087cc577a4SJonathan Peyton 
operator +(Quad_a4_t & lhs,Quad_a4_t & rhs)60944a11c34SHansang Bae static inline Quad_a4_t operator+(Quad_a4_t &lhs, Quad_a4_t &rhs) {
61044a11c34SHansang Bae   return lhs.q + rhs.q;
611bd3a7633SJonathan Peyton }
operator -(Quad_a4_t & lhs,Quad_a4_t & rhs)61244a11c34SHansang Bae static inline Quad_a4_t operator-(Quad_a4_t &lhs, Quad_a4_t &rhs) {
61344a11c34SHansang Bae   return lhs.q - rhs.q;
614bd3a7633SJonathan Peyton }
operator *(Quad_a4_t & lhs,Quad_a4_t & rhs)61544a11c34SHansang Bae static inline Quad_a4_t operator*(Quad_a4_t &lhs, Quad_a4_t &rhs) {
61644a11c34SHansang Bae   return lhs.q * rhs.q;
617bd3a7633SJonathan Peyton }
operator /(Quad_a4_t & lhs,Quad_a4_t & rhs)61844a11c34SHansang Bae static inline Quad_a4_t operator/(Quad_a4_t &lhs, Quad_a4_t &rhs) {
61944a11c34SHansang Bae   return lhs.q / rhs.q;
620bd3a7633SJonathan Peyton }
operator <(Quad_a4_t & lhs,Quad_a4_t & rhs)6213041982dSJonathan Peyton static inline bool operator<(Quad_a4_t &lhs, Quad_a4_t &rhs) {
6223041982dSJonathan Peyton   return lhs.q < rhs.q;
6233041982dSJonathan Peyton }
operator >(Quad_a4_t & lhs,Quad_a4_t & rhs)6243041982dSJonathan Peyton static inline bool operator>(Quad_a4_t &lhs, Quad_a4_t &rhs) {
6253041982dSJonathan Peyton   return lhs.q > rhs.q;
6263041982dSJonathan Peyton }
6277cc577a4SJonathan Peyton 
operator +(Quad_a16_t & lhs,Quad_a16_t & rhs)62844a11c34SHansang Bae static inline Quad_a16_t operator+(Quad_a16_t &lhs, Quad_a16_t &rhs) {
62944a11c34SHansang Bae   return lhs.q + rhs.q;
630bd3a7633SJonathan Peyton }
operator -(Quad_a16_t & lhs,Quad_a16_t & rhs)63144a11c34SHansang Bae static inline Quad_a16_t operator-(Quad_a16_t &lhs, Quad_a16_t &rhs) {
63244a11c34SHansang Bae   return lhs.q - rhs.q;
633bd3a7633SJonathan Peyton }
operator *(Quad_a16_t & lhs,Quad_a16_t & rhs)63444a11c34SHansang Bae static inline Quad_a16_t operator*(Quad_a16_t &lhs, Quad_a16_t &rhs) {
63544a11c34SHansang Bae   return lhs.q * rhs.q;
636bd3a7633SJonathan Peyton }
operator /(Quad_a16_t & lhs,Quad_a16_t & rhs)63744a11c34SHansang Bae static inline Quad_a16_t operator/(Quad_a16_t &lhs, Quad_a16_t &rhs) {
63844a11c34SHansang Bae   return lhs.q / rhs.q;
639bd3a7633SJonathan Peyton }
operator <(Quad_a16_t & lhs,Quad_a16_t & rhs)6403041982dSJonathan Peyton static inline bool operator<(Quad_a16_t &lhs, Quad_a16_t &rhs) {
6413041982dSJonathan Peyton   return lhs.q < rhs.q;
6423041982dSJonathan Peyton }
operator >(Quad_a16_t & lhs,Quad_a16_t & rhs)6433041982dSJonathan Peyton static inline bool operator>(Quad_a16_t &lhs, Quad_a16_t &rhs) {
6443041982dSJonathan Peyton   return lhs.q > rhs.q;
6453041982dSJonathan Peyton }
6467cc577a4SJonathan Peyton 
operator +(kmp_cmplx128_a4_t & lhs,kmp_cmplx128_a4_t & rhs)64744a11c34SHansang Bae static inline kmp_cmplx128_a4_t operator+(kmp_cmplx128_a4_t &lhs,
64844a11c34SHansang Bae                                           kmp_cmplx128_a4_t &rhs) {
64944a11c34SHansang Bae   return lhs.q + rhs.q;
650bd3a7633SJonathan Peyton }
operator -(kmp_cmplx128_a4_t & lhs,kmp_cmplx128_a4_t & rhs)65144a11c34SHansang Bae static inline kmp_cmplx128_a4_t operator-(kmp_cmplx128_a4_t &lhs,
65244a11c34SHansang Bae                                           kmp_cmplx128_a4_t &rhs) {
65344a11c34SHansang Bae   return lhs.q - rhs.q;
654bd3a7633SJonathan Peyton }
operator *(kmp_cmplx128_a4_t & lhs,kmp_cmplx128_a4_t & rhs)65544a11c34SHansang Bae static inline kmp_cmplx128_a4_t operator*(kmp_cmplx128_a4_t &lhs,
65644a11c34SHansang Bae                                           kmp_cmplx128_a4_t &rhs) {
65744a11c34SHansang Bae   return lhs.q * rhs.q;
658bd3a7633SJonathan Peyton }
operator /(kmp_cmplx128_a4_t & lhs,kmp_cmplx128_a4_t & rhs)65944a11c34SHansang Bae static inline kmp_cmplx128_a4_t operator/(kmp_cmplx128_a4_t &lhs,
66044a11c34SHansang Bae                                           kmp_cmplx128_a4_t &rhs) {
66144a11c34SHansang Bae   return lhs.q / rhs.q;
662bd3a7633SJonathan Peyton }
6637cc577a4SJonathan Peyton 
operator +(kmp_cmplx128_a16_t & lhs,kmp_cmplx128_a16_t & rhs)66444a11c34SHansang Bae static inline kmp_cmplx128_a16_t operator+(kmp_cmplx128_a16_t &lhs,
6653041982dSJonathan Peyton                                            kmp_cmplx128_a16_t &rhs) {
66644a11c34SHansang Bae   return lhs.q + rhs.q;
667bd3a7633SJonathan Peyton }
operator -(kmp_cmplx128_a16_t & lhs,kmp_cmplx128_a16_t & rhs)66844a11c34SHansang Bae static inline kmp_cmplx128_a16_t operator-(kmp_cmplx128_a16_t &lhs,
6693041982dSJonathan Peyton                                            kmp_cmplx128_a16_t &rhs) {
67044a11c34SHansang Bae   return lhs.q - rhs.q;
671bd3a7633SJonathan Peyton }
operator *(kmp_cmplx128_a16_t & lhs,kmp_cmplx128_a16_t & rhs)67244a11c34SHansang Bae static inline kmp_cmplx128_a16_t operator*(kmp_cmplx128_a16_t &lhs,
6733041982dSJonathan Peyton                                            kmp_cmplx128_a16_t &rhs) {
67444a11c34SHansang Bae   return lhs.q * rhs.q;
675bd3a7633SJonathan Peyton }
operator /(kmp_cmplx128_a16_t & lhs,kmp_cmplx128_a16_t & rhs)67644a11c34SHansang Bae static inline kmp_cmplx128_a16_t operator/(kmp_cmplx128_a16_t &lhs,
6773041982dSJonathan Peyton                                            kmp_cmplx128_a16_t &rhs) {
67844a11c34SHansang Bae   return lhs.q / rhs.q;
679bd3a7633SJonathan Peyton }
6807cc577a4SJonathan Peyton 
681e4b4f994SJonathan Peyton #endif // (KMP_ARCH_X86) && KMP_HAVE_QUAD
6827cc577a4SJonathan Peyton 
6833041982dSJonathan Peyton // ATOMIC implementation routines -----------------------------------------
6843041982dSJonathan Peyton // One routine for each operation and operand type.
6857cc577a4SJonathan Peyton // All routines declarations looks like
6867cc577a4SJonathan Peyton // void __kmpc_atomic_RTYPE_OP( ident_t*, int, TYPE *lhs, TYPE rhs );
6877cc577a4SJonathan Peyton 
6887cc577a4SJonathan Peyton #define KMP_CHECK_GTID                                                         \
6897cc577a4SJonathan Peyton   if (gtid == KMP_GTID_UNKNOWN) {                                              \
6907cc577a4SJonathan Peyton     gtid = __kmp_entry_gtid();                                                 \
6917cc577a4SJonathan Peyton   } // check and get gtid when needed
6927cc577a4SJonathan Peyton 
6937cc577a4SJonathan Peyton // Beginning of a definition (provides name, parameters, gebug trace)
6943041982dSJonathan Peyton //     TYPE_ID - operands type and size (fixed*, fixed*u for signed, unsigned
6953041982dSJonathan Peyton //     fixed)
6967cc577a4SJonathan Peyton //     OP_ID   - operation identifier (add, sub, mul, ...)
6977cc577a4SJonathan Peyton //     TYPE    - operands' type
6987cc577a4SJonathan Peyton #define ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, RET_TYPE)                           \
6993041982dSJonathan Peyton   RET_TYPE __kmpc_atomic_##TYPE_ID##_##OP_ID(ident_t *id_ref, int gtid,        \
7003041982dSJonathan Peyton                                              TYPE *lhs, TYPE rhs) {            \
7017cc577a4SJonathan Peyton     KMP_DEBUG_ASSERT(__kmp_init_serial);                                       \
7027cc577a4SJonathan Peyton     KA_TRACE(100, ("__kmpc_atomic_" #TYPE_ID "_" #OP_ID ": T#%d\n", gtid));
7037cc577a4SJonathan Peyton 
7047cc577a4SJonathan Peyton // ------------------------------------------------------------------------
7057cc577a4SJonathan Peyton // Lock variables used for critical sections for various size operands
7067cc577a4SJonathan Peyton #define ATOMIC_LOCK0 __kmp_atomic_lock // all types, for Gnu compat
7077cc577a4SJonathan Peyton #define ATOMIC_LOCK1i __kmp_atomic_lock_1i // char
7087cc577a4SJonathan Peyton #define ATOMIC_LOCK2i __kmp_atomic_lock_2i // short
7097cc577a4SJonathan Peyton #define ATOMIC_LOCK4i __kmp_atomic_lock_4i // long int
7107cc577a4SJonathan Peyton #define ATOMIC_LOCK4r __kmp_atomic_lock_4r // float
7117cc577a4SJonathan Peyton #define ATOMIC_LOCK8i __kmp_atomic_lock_8i // long long int
7127cc577a4SJonathan Peyton #define ATOMIC_LOCK8r __kmp_atomic_lock_8r // double
7137cc577a4SJonathan Peyton #define ATOMIC_LOCK8c __kmp_atomic_lock_8c // float complex
7147cc577a4SJonathan Peyton #define ATOMIC_LOCK10r __kmp_atomic_lock_10r // long double
7157cc577a4SJonathan Peyton #define ATOMIC_LOCK16r __kmp_atomic_lock_16r // _Quad
7167cc577a4SJonathan Peyton #define ATOMIC_LOCK16c __kmp_atomic_lock_16c // double complex
7177cc577a4SJonathan Peyton #define ATOMIC_LOCK20c __kmp_atomic_lock_20c // long double complex
7187cc577a4SJonathan Peyton #define ATOMIC_LOCK32c __kmp_atomic_lock_32c // _Quad complex
7197cc577a4SJonathan Peyton 
7207cc577a4SJonathan Peyton // ------------------------------------------------------------------------
7217cc577a4SJonathan Peyton // Operation on *lhs, rhs bound by critical section
7227cc577a4SJonathan Peyton //     OP     - operator (it's supposed to contain an assignment)
7237cc577a4SJonathan Peyton //     LCK_ID - lock identifier
7247cc577a4SJonathan Peyton // Note: don't check gtid as it should always be valid
7257cc577a4SJonathan Peyton // 1, 2-byte - expect valid parameter, other - check before this macro
7267cc577a4SJonathan Peyton #define OP_CRITICAL(OP, LCK_ID)                                                \
7277cc577a4SJonathan Peyton   __kmp_acquire_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
7287cc577a4SJonathan Peyton                                                                                \
7297cc577a4SJonathan Peyton   (*lhs) OP(rhs);                                                              \
7307cc577a4SJonathan Peyton                                                                                \
7317cc577a4SJonathan Peyton   __kmp_release_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);
7327cc577a4SJonathan Peyton 
73344a11c34SHansang Bae #define OP_UPDATE_CRITICAL(TYPE, OP, LCK_ID)                                   \
73444a11c34SHansang Bae   __kmp_acquire_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
735d8e4cb91STerry Wilmarth   (*lhs) = (TYPE)((*lhs)OP rhs);                                               \
73644a11c34SHansang Bae   __kmp_release_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);
73744a11c34SHansang Bae 
7387cc577a4SJonathan Peyton // ------------------------------------------------------------------------
7397cc577a4SJonathan Peyton // For GNU compatibility, we may need to use a critical section,
7407cc577a4SJonathan Peyton // even though it is not required by the ISA.
7417cc577a4SJonathan Peyton //
7427cc577a4SJonathan Peyton // On IA-32 architecture, all atomic operations except for fixed 4 byte add,
7437cc577a4SJonathan Peyton // sub, and bitwise logical ops, and 1 & 2 byte logical ops use a common
7447cc577a4SJonathan Peyton // critical section.  On Intel(R) 64, all atomic operations are done with fetch
7457cc577a4SJonathan Peyton // and add or compare and exchange.  Therefore, the FLAG parameter to this
7467cc577a4SJonathan Peyton // macro is either KMP_ARCH_X86 or 0 (or 1, for Intel-specific extension which
7477cc577a4SJonathan Peyton // require a critical section, where we predict that they will be implemented
7487cc577a4SJonathan Peyton // in the Gnu codegen by calling GOMP_atomic_start() / GOMP_atomic_end()).
7497cc577a4SJonathan Peyton //
7507cc577a4SJonathan Peyton // When the OP_GOMP_CRITICAL macro is used in a *CRITICAL* macro construct,
7517cc577a4SJonathan Peyton // the FLAG parameter should always be 1.  If we know that we will be using
7527cc577a4SJonathan Peyton // a critical section, then we want to make certain that we use the generic
7537cc577a4SJonathan Peyton // lock __kmp_atomic_lock to protect the atomic update, and not of of the
7547cc577a4SJonathan Peyton // locks that are specialized based upon the size or type of the data.
7557cc577a4SJonathan Peyton //
7567cc577a4SJonathan Peyton // If FLAG is 0, then we are relying on dead code elimination by the build
7577cc577a4SJonathan Peyton // compiler to get rid of the useless block of code, and save a needless
7587cc577a4SJonathan Peyton // branch at runtime.
7597cc577a4SJonathan Peyton 
7607cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
7617cc577a4SJonathan Peyton #define OP_GOMP_CRITICAL(OP, FLAG)                                             \
7627cc577a4SJonathan Peyton   if ((FLAG) && (__kmp_atomic_mode == 2)) {                                    \
7637cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
7647cc577a4SJonathan Peyton     OP_CRITICAL(OP, 0);                                                        \
7657cc577a4SJonathan Peyton     return;                                                                    \
7667cc577a4SJonathan Peyton   }
76744a11c34SHansang Bae 
76844a11c34SHansang Bae #define OP_UPDATE_GOMP_CRITICAL(TYPE, OP, FLAG)                                \
76944a11c34SHansang Bae   if ((FLAG) && (__kmp_atomic_mode == 2)) {                                    \
77044a11c34SHansang Bae     KMP_CHECK_GTID;                                                            \
77144a11c34SHansang Bae     OP_UPDATE_CRITICAL(TYPE, OP, 0);                                           \
77244a11c34SHansang Bae     return;                                                                    \
77344a11c34SHansang Bae   }
7747cc577a4SJonathan Peyton #else
7757cc577a4SJonathan Peyton #define OP_GOMP_CRITICAL(OP, FLAG)
77644a11c34SHansang Bae #define OP_UPDATE_GOMP_CRITICAL(TYPE, OP, FLAG)
7777cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
7787cc577a4SJonathan Peyton 
7797cc577a4SJonathan Peyton #if KMP_MIC
7807cc577a4SJonathan Peyton #define KMP_DO_PAUSE _mm_delay_32(1)
7817cc577a4SJonathan Peyton #else
782aaf16b80SAndreyChurbanov #define KMP_DO_PAUSE
7837cc577a4SJonathan Peyton #endif /* KMP_MIC */
7847cc577a4SJonathan Peyton 
7857cc577a4SJonathan Peyton // ------------------------------------------------------------------------
7867cc577a4SJonathan Peyton // Operation on *lhs, rhs using "compare_and_store" routine
7877cc577a4SJonathan Peyton //     TYPE    - operands' type
7887cc577a4SJonathan Peyton //     BITS    - size in bits, used to distinguish low level calls
7897cc577a4SJonathan Peyton //     OP      - operator
7907cc577a4SJonathan Peyton #define OP_CMPXCHG(TYPE, BITS, OP)                                             \
7917cc577a4SJonathan Peyton   {                                                                            \
7927cc577a4SJonathan Peyton     TYPE old_value, new_value;                                                 \
7937cc577a4SJonathan Peyton     old_value = *(TYPE volatile *)lhs;                                         \
794d8e4cb91STerry Wilmarth     new_value = (TYPE)(old_value OP rhs);                                      \
7953041982dSJonathan Peyton     while (!KMP_COMPARE_AND_STORE_ACQ##BITS(                                   \
7963041982dSJonathan Peyton         (kmp_int##BITS *)lhs, *VOLATILE_CAST(kmp_int##BITS *) & old_value,     \
7973041982dSJonathan Peyton         *VOLATILE_CAST(kmp_int##BITS *) & new_value)) {                        \
7987cc577a4SJonathan Peyton       KMP_DO_PAUSE;                                                            \
7997cc577a4SJonathan Peyton                                                                                \
8007cc577a4SJonathan Peyton       old_value = *(TYPE volatile *)lhs;                                       \
801d8e4cb91STerry Wilmarth       new_value = (TYPE)(old_value OP rhs);                                    \
8027cc577a4SJonathan Peyton     }                                                                          \
8037cc577a4SJonathan Peyton   }
8047cc577a4SJonathan Peyton 
8057cc577a4SJonathan Peyton #if USE_CMPXCHG_FIX
8067cc577a4SJonathan Peyton // 2007-06-25:
8073041982dSJonathan Peyton // workaround for C78287 (complex(kind=4) data type). lin_32, lin_32e, win_32
8083041982dSJonathan Peyton // and win_32e are affected (I verified the asm). Compiler ignores the volatile
8093041982dSJonathan Peyton // qualifier of the temp_val in the OP_CMPXCHG macro. This is a problem of the
8103041982dSJonathan Peyton // compiler. Related tracker is C76005, targeted to 11.0. I verified the asm of
8113041982dSJonathan Peyton // the workaround.
8127cc577a4SJonathan Peyton #define OP_CMPXCHG_WORKAROUND(TYPE, BITS, OP)                                  \
8137cc577a4SJonathan Peyton   {                                                                            \
8147cc577a4SJonathan Peyton     struct _sss {                                                              \
8157cc577a4SJonathan Peyton       TYPE cmp;                                                                \
8167cc577a4SJonathan Peyton       kmp_int##BITS *vvv;                                                      \
8177cc577a4SJonathan Peyton     };                                                                         \
8187cc577a4SJonathan Peyton     struct _sss old_value, new_value;                                          \
8197cc577a4SJonathan Peyton     old_value.vvv = (kmp_int##BITS *)&old_value.cmp;                           \
8207cc577a4SJonathan Peyton     new_value.vvv = (kmp_int##BITS *)&new_value.cmp;                           \
8217cc577a4SJonathan Peyton     *old_value.vvv = *(volatile kmp_int##BITS *)lhs;                           \
82244a11c34SHansang Bae     new_value.cmp = (TYPE)(old_value.cmp OP rhs);                              \
8233041982dSJonathan Peyton     while (!KMP_COMPARE_AND_STORE_ACQ##BITS(                                   \
8243041982dSJonathan Peyton         (kmp_int##BITS *)lhs, *VOLATILE_CAST(kmp_int##BITS *) old_value.vvv,   \
8253041982dSJonathan Peyton         *VOLATILE_CAST(kmp_int##BITS *) new_value.vvv)) {                      \
8267cc577a4SJonathan Peyton       KMP_DO_PAUSE;                                                            \
8277cc577a4SJonathan Peyton                                                                                \
8287cc577a4SJonathan Peyton       *old_value.vvv = *(volatile kmp_int##BITS *)lhs;                         \
82944a11c34SHansang Bae       new_value.cmp = (TYPE)(old_value.cmp OP rhs);                            \
8307cc577a4SJonathan Peyton     }                                                                          \
8317cc577a4SJonathan Peyton   }
8327cc577a4SJonathan Peyton // end of the first part of the workaround for C78287
8337cc577a4SJonathan Peyton #endif // USE_CMPXCHG_FIX
8347cc577a4SJonathan Peyton 
8354fb0aaf0SChristopher Pulido #if KMP_OS_WINDOWS && KMP_ARCH_AARCH64
8364fb0aaf0SChristopher Pulido // Undo explicit type casts to get MSVC ARM64 to build. Uses
8374fb0aaf0SChristopher Pulido // OP_CMPXCHG_WORKAROUND definition for OP_CMPXCHG
8384fb0aaf0SChristopher Pulido #undef OP_CMPXCHG
8394fb0aaf0SChristopher Pulido #define OP_CMPXCHG(TYPE, BITS, OP)                                             \
8404fb0aaf0SChristopher Pulido   {                                                                            \
8414fb0aaf0SChristopher Pulido     struct _sss {                                                              \
8424fb0aaf0SChristopher Pulido       TYPE cmp;                                                                \
8434fb0aaf0SChristopher Pulido       kmp_int##BITS *vvv;                                                      \
8444fb0aaf0SChristopher Pulido     };                                                                         \
8454fb0aaf0SChristopher Pulido     struct _sss old_value, new_value;                                          \
8464fb0aaf0SChristopher Pulido     old_value.vvv = (kmp_int##BITS *)&old_value.cmp;                           \
8474fb0aaf0SChristopher Pulido     new_value.vvv = (kmp_int##BITS *)&new_value.cmp;                           \
8484fb0aaf0SChristopher Pulido     *old_value.vvv = *(volatile kmp_int##BITS *)lhs;                           \
8494fb0aaf0SChristopher Pulido     new_value.cmp = old_value.cmp OP rhs;                                      \
8504fb0aaf0SChristopher Pulido     while (!KMP_COMPARE_AND_STORE_ACQ##BITS(                                   \
8514fb0aaf0SChristopher Pulido         (kmp_int##BITS *)lhs, *VOLATILE_CAST(kmp_int##BITS *) old_value.vvv,   \
8524fb0aaf0SChristopher Pulido         *VOLATILE_CAST(kmp_int##BITS *) new_value.vvv)) {                      \
8534fb0aaf0SChristopher Pulido       KMP_DO_PAUSE;                                                            \
8544fb0aaf0SChristopher Pulido                                                                                \
8554fb0aaf0SChristopher Pulido       *old_value.vvv = *(volatile kmp_int##BITS *)lhs;                         \
8564fb0aaf0SChristopher Pulido       new_value.cmp = old_value.cmp OP rhs;                                    \
8574fb0aaf0SChristopher Pulido     }                                                                          \
8584fb0aaf0SChristopher Pulido   }
8594fb0aaf0SChristopher Pulido 
8604fb0aaf0SChristopher Pulido #undef OP_UPDATE_CRITICAL
8614fb0aaf0SChristopher Pulido #define OP_UPDATE_CRITICAL(TYPE, OP, LCK_ID)                                   \
8624fb0aaf0SChristopher Pulido   __kmp_acquire_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
8634fb0aaf0SChristopher Pulido   (*lhs) = (*lhs)OP rhs;                                                       \
8644fb0aaf0SChristopher Pulido   __kmp_release_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);
8654fb0aaf0SChristopher Pulido 
8664fb0aaf0SChristopher Pulido #endif // KMP_OS_WINDOWS && KMP_ARCH_AARCH64
8674fb0aaf0SChristopher Pulido 
8687cc577a4SJonathan Peyton #if KMP_ARCH_X86 || KMP_ARCH_X86_64
8697cc577a4SJonathan Peyton 
8707cc577a4SJonathan Peyton // ------------------------------------------------------------------------
8717cc577a4SJonathan Peyton // X86 or X86_64: no alignment problems ====================================
8723041982dSJonathan Peyton #define ATOMIC_FIXED_ADD(TYPE_ID, OP_ID, TYPE, BITS, OP, LCK_ID, MASK,         \
8733041982dSJonathan Peyton                          GOMP_FLAG)                                            \
8747cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
87544a11c34SHansang Bae   OP_UPDATE_GOMP_CRITICAL(TYPE, OP, GOMP_FLAG)                                 \
8767cc577a4SJonathan Peyton   /* OP used as a sign for subtraction: (lhs-rhs) --> (lhs+-rhs) */            \
8777cc577a4SJonathan Peyton   KMP_TEST_THEN_ADD##BITS(lhs, OP rhs);                                        \
8787cc577a4SJonathan Peyton   }
8797cc577a4SJonathan Peyton // -------------------------------------------------------------------------
8803041982dSJonathan Peyton #define ATOMIC_CMPXCHG(TYPE_ID, OP_ID, TYPE, BITS, OP, LCK_ID, MASK,           \
8813041982dSJonathan Peyton                        GOMP_FLAG)                                              \
8827cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
88344a11c34SHansang Bae   OP_UPDATE_GOMP_CRITICAL(TYPE, OP, GOMP_FLAG)                                 \
8847cc577a4SJonathan Peyton   OP_CMPXCHG(TYPE, BITS, OP)                                                   \
8857cc577a4SJonathan Peyton   }
8867cc577a4SJonathan Peyton #if USE_CMPXCHG_FIX
8877cc577a4SJonathan Peyton // -------------------------------------------------------------------------
8887cc577a4SJonathan Peyton // workaround for C78287 (complex(kind=4) data type)
8893041982dSJonathan Peyton #define ATOMIC_CMPXCHG_WORKAROUND(TYPE_ID, OP_ID, TYPE, BITS, OP, LCK_ID,      \
8903041982dSJonathan Peyton                                   MASK, GOMP_FLAG)                             \
8917cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
89244a11c34SHansang Bae   OP_UPDATE_GOMP_CRITICAL(TYPE, OP, GOMP_FLAG)                                 \
8937cc577a4SJonathan Peyton   OP_CMPXCHG_WORKAROUND(TYPE, BITS, OP)                                        \
8947cc577a4SJonathan Peyton   }
8957cc577a4SJonathan Peyton // end of the second part of the workaround for C78287
896e4b4f994SJonathan Peyton #endif // USE_CMPXCHG_FIX
8977cc577a4SJonathan Peyton 
8987cc577a4SJonathan Peyton #else
8997cc577a4SJonathan Peyton // -------------------------------------------------------------------------
9007cc577a4SJonathan Peyton // Code for other architectures that don't handle unaligned accesses.
9013041982dSJonathan Peyton #define ATOMIC_FIXED_ADD(TYPE_ID, OP_ID, TYPE, BITS, OP, LCK_ID, MASK,         \
9023041982dSJonathan Peyton                          GOMP_FLAG)                                            \
9037cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
90444a11c34SHansang Bae   OP_UPDATE_GOMP_CRITICAL(TYPE, OP, GOMP_FLAG)                                 \
9057cc577a4SJonathan Peyton   if (!((kmp_uintptr_t)lhs & 0x##MASK)) {                                      \
9067cc577a4SJonathan Peyton     /* OP used as a sign for subtraction: (lhs-rhs) --> (lhs+-rhs) */          \
9077cc577a4SJonathan Peyton     KMP_TEST_THEN_ADD##BITS(lhs, OP rhs);                                      \
9087cc577a4SJonathan Peyton   } else {                                                                     \
9097cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
91044a11c34SHansang Bae     OP_UPDATE_CRITICAL(TYPE, OP,                                               \
91144a11c34SHansang Bae                        LCK_ID) /* unaligned address - use critical */          \
9127cc577a4SJonathan Peyton   }                                                                            \
9137cc577a4SJonathan Peyton   }
9147cc577a4SJonathan Peyton // -------------------------------------------------------------------------
9153041982dSJonathan Peyton #define ATOMIC_CMPXCHG(TYPE_ID, OP_ID, TYPE, BITS, OP, LCK_ID, MASK,           \
9163041982dSJonathan Peyton                        GOMP_FLAG)                                              \
9177cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
91844a11c34SHansang Bae   OP_UPDATE_GOMP_CRITICAL(TYPE, OP, GOMP_FLAG)                                 \
9197cc577a4SJonathan Peyton   if (!((kmp_uintptr_t)lhs & 0x##MASK)) {                                      \
9207cc577a4SJonathan Peyton     OP_CMPXCHG(TYPE, BITS, OP) /* aligned address */                           \
9217cc577a4SJonathan Peyton   } else {                                                                     \
9227cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
92344a11c34SHansang Bae     OP_UPDATE_CRITICAL(TYPE, OP,                                               \
92444a11c34SHansang Bae                        LCK_ID) /* unaligned address - use critical */          \
9257cc577a4SJonathan Peyton   }                                                                            \
9267cc577a4SJonathan Peyton   }
9277cc577a4SJonathan Peyton #if USE_CMPXCHG_FIX
9287cc577a4SJonathan Peyton // -------------------------------------------------------------------------
9297cc577a4SJonathan Peyton // workaround for C78287 (complex(kind=4) data type)
9303041982dSJonathan Peyton #define ATOMIC_CMPXCHG_WORKAROUND(TYPE_ID, OP_ID, TYPE, BITS, OP, LCK_ID,      \
9313041982dSJonathan Peyton                                   MASK, GOMP_FLAG)                             \
9327cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
93344a11c34SHansang Bae   OP_UPDATE_GOMP_CRITICAL(TYPE, OP, GOMP_FLAG)                                 \
9347cc577a4SJonathan Peyton   if (!((kmp_uintptr_t)lhs & 0x##MASK)) {                                      \
9357cc577a4SJonathan Peyton     OP_CMPXCHG(TYPE, BITS, OP) /* aligned address */                           \
9367cc577a4SJonathan Peyton   } else {                                                                     \
9377cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
93844a11c34SHansang Bae     OP_UPDATE_CRITICAL(TYPE, OP,                                               \
93944a11c34SHansang Bae                        LCK_ID) /* unaligned address - use critical */          \
9407cc577a4SJonathan Peyton   }                                                                            \
9417cc577a4SJonathan Peyton   }
9427cc577a4SJonathan Peyton // end of the second part of the workaround for C78287
9437cc577a4SJonathan Peyton #endif // USE_CMPXCHG_FIX
9447cc577a4SJonathan Peyton #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
9457cc577a4SJonathan Peyton 
9467cc577a4SJonathan Peyton // Routines for ATOMIC 4-byte operands addition and subtraction
9473041982dSJonathan Peyton ATOMIC_FIXED_ADD(fixed4, add, kmp_int32, 32, +, 4i, 3,
9483041982dSJonathan Peyton                  0) // __kmpc_atomic_fixed4_add
9493041982dSJonathan Peyton ATOMIC_FIXED_ADD(fixed4, sub, kmp_int32, 32, -, 4i, 3,
9503041982dSJonathan Peyton                  0) // __kmpc_atomic_fixed4_sub
9517cc577a4SJonathan Peyton 
9523041982dSJonathan Peyton ATOMIC_CMPXCHG(float4, add, kmp_real32, 32, +, 4r, 3,
9533041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_float4_add
9543041982dSJonathan Peyton ATOMIC_CMPXCHG(float4, sub, kmp_real32, 32, -, 4r, 3,
9553041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_float4_sub
9567cc577a4SJonathan Peyton 
9577cc577a4SJonathan Peyton // Routines for ATOMIC 8-byte operands addition and subtraction
9583041982dSJonathan Peyton ATOMIC_FIXED_ADD(fixed8, add, kmp_int64, 64, +, 8i, 7,
9593041982dSJonathan Peyton                  KMP_ARCH_X86) // __kmpc_atomic_fixed8_add
9603041982dSJonathan Peyton ATOMIC_FIXED_ADD(fixed8, sub, kmp_int64, 64, -, 8i, 7,
9613041982dSJonathan Peyton                  KMP_ARCH_X86) // __kmpc_atomic_fixed8_sub
9627cc577a4SJonathan Peyton 
9633041982dSJonathan Peyton ATOMIC_CMPXCHG(float8, add, kmp_real64, 64, +, 8r, 7,
9643041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_float8_add
9653041982dSJonathan Peyton ATOMIC_CMPXCHG(float8, sub, kmp_real64, 64, -, 8r, 7,
9663041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_float8_sub
9677cc577a4SJonathan Peyton 
9687cc577a4SJonathan Peyton // ------------------------------------------------------------------------
9697cc577a4SJonathan Peyton // Entries definition for integer operands
9707cc577a4SJonathan Peyton //     TYPE_ID - operands type and size (fixed4, float4)
9717cc577a4SJonathan Peyton //     OP_ID   - operation identifier (add, sub, mul, ...)
9727cc577a4SJonathan Peyton //     TYPE    - operand type
9737cc577a4SJonathan Peyton //     BITS    - size in bits, used to distinguish low level calls
9747cc577a4SJonathan Peyton //     OP      - operator (used in critical section)
9757cc577a4SJonathan Peyton //     LCK_ID  - lock identifier, used to possibly distinguish lock variable
9767cc577a4SJonathan Peyton //     MASK    - used for alignment check
9777cc577a4SJonathan Peyton 
9787cc577a4SJonathan Peyton //               TYPE_ID,OP_ID,  TYPE,   BITS,OP,LCK_ID,MASK,GOMP_FLAG
9797cc577a4SJonathan Peyton // ------------------------------------------------------------------------
9807cc577a4SJonathan Peyton // Routines for ATOMIC integer operands, other operators
9817cc577a4SJonathan Peyton // ------------------------------------------------------------------------
9827cc577a4SJonathan Peyton //              TYPE_ID,OP_ID, TYPE,          OP, LCK_ID, GOMP_FLAG
9833041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed1, add, kmp_int8, 8, +, 1i, 0,
9843041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed1_add
9853041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed1, andb, kmp_int8, 8, &, 1i, 0,
9863041982dSJonathan Peyton                0) // __kmpc_atomic_fixed1_andb
9873041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed1, div, kmp_int8, 8, /, 1i, 0,
9883041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed1_div
9893041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed1u, div, kmp_uint8, 8, /, 1i, 0,
9903041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed1u_div
9913041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed1, mul, kmp_int8, 8, *, 1i, 0,
9923041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed1_mul
9933041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed1, orb, kmp_int8, 8, |, 1i, 0,
9943041982dSJonathan Peyton                0) // __kmpc_atomic_fixed1_orb
9953041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed1, shl, kmp_int8, 8, <<, 1i, 0,
9963041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed1_shl
9973041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed1, shr, kmp_int8, 8, >>, 1i, 0,
9983041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed1_shr
9993041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed1u, shr, kmp_uint8, 8, >>, 1i, 0,
10003041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed1u_shr
10013041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed1, sub, kmp_int8, 8, -, 1i, 0,
10023041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed1_sub
10033041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed1, xor, kmp_int8, 8, ^, 1i, 0,
10043041982dSJonathan Peyton                0) // __kmpc_atomic_fixed1_xor
10053041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed2, add, kmp_int16, 16, +, 2i, 1,
10063041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed2_add
10073041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed2, andb, kmp_int16, 16, &, 2i, 1,
10083041982dSJonathan Peyton                0) // __kmpc_atomic_fixed2_andb
10093041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed2, div, kmp_int16, 16, /, 2i, 1,
10103041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed2_div
10113041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed2u, div, kmp_uint16, 16, /, 2i, 1,
10123041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed2u_div
10133041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed2, mul, kmp_int16, 16, *, 2i, 1,
10143041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed2_mul
10153041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed2, orb, kmp_int16, 16, |, 2i, 1,
10163041982dSJonathan Peyton                0) // __kmpc_atomic_fixed2_orb
10173041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed2, shl, kmp_int16, 16, <<, 2i, 1,
10183041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed2_shl
10193041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed2, shr, kmp_int16, 16, >>, 2i, 1,
10203041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed2_shr
10213041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed2u, shr, kmp_uint16, 16, >>, 2i, 1,
10223041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed2u_shr
10233041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed2, sub, kmp_int16, 16, -, 2i, 1,
10243041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed2_sub
10253041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed2, xor, kmp_int16, 16, ^, 2i, 1,
10263041982dSJonathan Peyton                0) // __kmpc_atomic_fixed2_xor
10273041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed4, andb, kmp_int32, 32, &, 4i, 3,
10283041982dSJonathan Peyton                0) // __kmpc_atomic_fixed4_andb
10293041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed4, div, kmp_int32, 32, /, 4i, 3,
10303041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed4_div
10313041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed4u, div, kmp_uint32, 32, /, 4i, 3,
10323041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed4u_div
10333041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed4, mul, kmp_int32, 32, *, 4i, 3,
10343041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed4_mul
10353041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed4, orb, kmp_int32, 32, |, 4i, 3,
10363041982dSJonathan Peyton                0) // __kmpc_atomic_fixed4_orb
10373041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed4, shl, kmp_int32, 32, <<, 4i, 3,
10383041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed4_shl
10393041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed4, shr, kmp_int32, 32, >>, 4i, 3,
10403041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed4_shr
10413041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed4u, shr, kmp_uint32, 32, >>, 4i, 3,
10423041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed4u_shr
10433041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed4, xor, kmp_int32, 32, ^, 4i, 3,
10443041982dSJonathan Peyton                0) // __kmpc_atomic_fixed4_xor
10453041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed8, andb, kmp_int64, 64, &, 8i, 7,
10463041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed8_andb
10473041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed8, div, kmp_int64, 64, /, 8i, 7,
10483041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed8_div
10493041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed8u, div, kmp_uint64, 64, /, 8i, 7,
10503041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed8u_div
10513041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed8, mul, kmp_int64, 64, *, 8i, 7,
10523041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed8_mul
10533041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed8, orb, kmp_int64, 64, |, 8i, 7,
10543041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed8_orb
10553041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed8, shl, kmp_int64, 64, <<, 8i, 7,
10563041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed8_shl
10573041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed8, shr, kmp_int64, 64, >>, 8i, 7,
10583041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed8_shr
10593041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed8u, shr, kmp_uint64, 64, >>, 8i, 7,
10603041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed8u_shr
10613041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed8, xor, kmp_int64, 64, ^, 8i, 7,
10623041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed8_xor
10633041982dSJonathan Peyton ATOMIC_CMPXCHG(float4, div, kmp_real32, 32, /, 4r, 3,
10643041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_float4_div
10653041982dSJonathan Peyton ATOMIC_CMPXCHG(float4, mul, kmp_real32, 32, *, 4r, 3,
10663041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_float4_mul
10673041982dSJonathan Peyton ATOMIC_CMPXCHG(float8, div, kmp_real64, 64, /, 8r, 7,
10683041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_float8_div
10693041982dSJonathan Peyton ATOMIC_CMPXCHG(float8, mul, kmp_real64, 64, *, 8r, 7,
10703041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_float8_mul
10717cc577a4SJonathan Peyton //              TYPE_ID,OP_ID, TYPE,          OP, LCK_ID, GOMP_FLAG
10727cc577a4SJonathan Peyton 
10737cc577a4SJonathan Peyton /* ------------------------------------------------------------------------ */
10747cc577a4SJonathan Peyton /* Routines for C/C++ Reduction operators && and ||                         */
10757cc577a4SJonathan Peyton 
10767cc577a4SJonathan Peyton // ------------------------------------------------------------------------
10777cc577a4SJonathan Peyton // Need separate macros for &&, || because there is no combined assignment
10787cc577a4SJonathan Peyton //   TODO: eliminate ATOMIC_CRIT_{L,EQV} macros as not used
10797cc577a4SJonathan Peyton #define ATOMIC_CRIT_L(TYPE_ID, OP_ID, TYPE, OP, LCK_ID, GOMP_FLAG)             \
10807cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
10817cc577a4SJonathan Peyton   OP_GOMP_CRITICAL(= *lhs OP, GOMP_FLAG)                                       \
10827cc577a4SJonathan Peyton   OP_CRITICAL(= *lhs OP, LCK_ID)                                               \
10837cc577a4SJonathan Peyton   }
10847cc577a4SJonathan Peyton 
10857cc577a4SJonathan Peyton #if KMP_ARCH_X86 || KMP_ARCH_X86_64
10867cc577a4SJonathan Peyton 
10877cc577a4SJonathan Peyton // ------------------------------------------------------------------------
10887cc577a4SJonathan Peyton // X86 or X86_64: no alignment problems ===================================
10897cc577a4SJonathan Peyton #define ATOMIC_CMPX_L(TYPE_ID, OP_ID, TYPE, BITS, OP, LCK_ID, MASK, GOMP_FLAG) \
10907cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
10917cc577a4SJonathan Peyton   OP_GOMP_CRITICAL(= *lhs OP, GOMP_FLAG)                                       \
10927cc577a4SJonathan Peyton   OP_CMPXCHG(TYPE, BITS, OP)                                                   \
10937cc577a4SJonathan Peyton   }
10947cc577a4SJonathan Peyton 
10957cc577a4SJonathan Peyton #else
10967cc577a4SJonathan Peyton // ------------------------------------------------------------------------
10977cc577a4SJonathan Peyton // Code for other architectures that don't handle unaligned accesses.
10987cc577a4SJonathan Peyton #define ATOMIC_CMPX_L(TYPE_ID, OP_ID, TYPE, BITS, OP, LCK_ID, MASK, GOMP_FLAG) \
10997cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
11007cc577a4SJonathan Peyton   OP_GOMP_CRITICAL(= *lhs OP, GOMP_FLAG)                                       \
11017cc577a4SJonathan Peyton   if (!((kmp_uintptr_t)lhs & 0x##MASK)) {                                      \
11027cc577a4SJonathan Peyton     OP_CMPXCHG(TYPE, BITS, OP) /* aligned address */                           \
11037cc577a4SJonathan Peyton   } else {                                                                     \
11047cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
11057cc577a4SJonathan Peyton     OP_CRITICAL(= *lhs OP, LCK_ID) /* unaligned - use critical */              \
11067cc577a4SJonathan Peyton   }                                                                            \
11077cc577a4SJonathan Peyton   }
11087cc577a4SJonathan Peyton #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
11097cc577a4SJonathan Peyton 
11103041982dSJonathan Peyton ATOMIC_CMPX_L(fixed1, andl, char, 8, &&, 1i, 0,
11113041982dSJonathan Peyton               KMP_ARCH_X86) // __kmpc_atomic_fixed1_andl
11123041982dSJonathan Peyton ATOMIC_CMPX_L(fixed1, orl, char, 8, ||, 1i, 0,
11133041982dSJonathan Peyton               KMP_ARCH_X86) // __kmpc_atomic_fixed1_orl
11143041982dSJonathan Peyton ATOMIC_CMPX_L(fixed2, andl, short, 16, &&, 2i, 1,
11153041982dSJonathan Peyton               KMP_ARCH_X86) // __kmpc_atomic_fixed2_andl
11163041982dSJonathan Peyton ATOMIC_CMPX_L(fixed2, orl, short, 16, ||, 2i, 1,
11173041982dSJonathan Peyton               KMP_ARCH_X86) // __kmpc_atomic_fixed2_orl
11183041982dSJonathan Peyton ATOMIC_CMPX_L(fixed4, andl, kmp_int32, 32, &&, 4i, 3,
11193041982dSJonathan Peyton               0) // __kmpc_atomic_fixed4_andl
11203041982dSJonathan Peyton ATOMIC_CMPX_L(fixed4, orl, kmp_int32, 32, ||, 4i, 3,
11213041982dSJonathan Peyton               0) // __kmpc_atomic_fixed4_orl
11223041982dSJonathan Peyton ATOMIC_CMPX_L(fixed8, andl, kmp_int64, 64, &&, 8i, 7,
11233041982dSJonathan Peyton               KMP_ARCH_X86) // __kmpc_atomic_fixed8_andl
11243041982dSJonathan Peyton ATOMIC_CMPX_L(fixed8, orl, kmp_int64, 64, ||, 8i, 7,
11253041982dSJonathan Peyton               KMP_ARCH_X86) // __kmpc_atomic_fixed8_orl
11267cc577a4SJonathan Peyton 
11277cc577a4SJonathan Peyton /* ------------------------------------------------------------------------- */
11287cc577a4SJonathan Peyton /* Routines for Fortran operators that matched no one in C:                  */
11297cc577a4SJonathan Peyton /* MAX, MIN, .EQV., .NEQV.                                                   */
11307cc577a4SJonathan Peyton /* Operators .AND., .OR. are covered by __kmpc_atomic_*_{andl,orl}           */
11317cc577a4SJonathan Peyton /* Intrinsics IAND, IOR, IEOR are covered by __kmpc_atomic_*_{andb,orb,xor}  */
11327cc577a4SJonathan Peyton 
11337cc577a4SJonathan Peyton // -------------------------------------------------------------------------
11347cc577a4SJonathan Peyton // MIN and MAX need separate macros
11357cc577a4SJonathan Peyton // OP - operator to check if we need any actions?
11367cc577a4SJonathan Peyton #define MIN_MAX_CRITSECT(OP, LCK_ID)                                           \
11377cc577a4SJonathan Peyton   __kmp_acquire_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
11387cc577a4SJonathan Peyton                                                                                \
11397cc577a4SJonathan Peyton   if (*lhs OP rhs) { /* still need actions? */                                 \
11407cc577a4SJonathan Peyton     *lhs = rhs;                                                                \
11417cc577a4SJonathan Peyton   }                                                                            \
11427cc577a4SJonathan Peyton   __kmp_release_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);
11437cc577a4SJonathan Peyton 
11447cc577a4SJonathan Peyton // -------------------------------------------------------------------------
11457cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
11467cc577a4SJonathan Peyton #define GOMP_MIN_MAX_CRITSECT(OP, FLAG)                                        \
11477cc577a4SJonathan Peyton   if ((FLAG) && (__kmp_atomic_mode == 2)) {                                    \
11487cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
11497cc577a4SJonathan Peyton     MIN_MAX_CRITSECT(OP, 0);                                                   \
11507cc577a4SJonathan Peyton     return;                                                                    \
11517cc577a4SJonathan Peyton   }
11527cc577a4SJonathan Peyton #else
11537cc577a4SJonathan Peyton #define GOMP_MIN_MAX_CRITSECT(OP, FLAG)
11547cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
11557cc577a4SJonathan Peyton 
11567cc577a4SJonathan Peyton // -------------------------------------------------------------------------
11577cc577a4SJonathan Peyton #define MIN_MAX_CMPXCHG(TYPE, BITS, OP)                                        \
11587cc577a4SJonathan Peyton   {                                                                            \
11597cc577a4SJonathan Peyton     TYPE KMP_ATOMIC_VOLATILE temp_val;                                         \
11607cc577a4SJonathan Peyton     TYPE old_value;                                                            \
11617cc577a4SJonathan Peyton     temp_val = *lhs;                                                           \
11627cc577a4SJonathan Peyton     old_value = temp_val;                                                      \
11637cc577a4SJonathan Peyton     while (old_value OP rhs && /* still need actions? */                       \
11643041982dSJonathan Peyton            !KMP_COMPARE_AND_STORE_ACQ##BITS(                                   \
11653041982dSJonathan Peyton                (kmp_int##BITS *)lhs,                                           \
11667cc577a4SJonathan Peyton                *VOLATILE_CAST(kmp_int##BITS *) & old_value,                    \
11673041982dSJonathan Peyton                *VOLATILE_CAST(kmp_int##BITS *) & rhs)) {                       \
11687cc577a4SJonathan Peyton       temp_val = *lhs;                                                         \
11697cc577a4SJonathan Peyton       old_value = temp_val;                                                    \
11707cc577a4SJonathan Peyton     }                                                                          \
11717cc577a4SJonathan Peyton   }
11727cc577a4SJonathan Peyton 
11737cc577a4SJonathan Peyton // -------------------------------------------------------------------------
11747cc577a4SJonathan Peyton // 1-byte, 2-byte operands - use critical section
11757cc577a4SJonathan Peyton #define MIN_MAX_CRITICAL(TYPE_ID, OP_ID, TYPE, OP, LCK_ID, GOMP_FLAG)          \
11767cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
11777cc577a4SJonathan Peyton   if (*lhs OP rhs) { /* need actions? */                                       \
11787cc577a4SJonathan Peyton     GOMP_MIN_MAX_CRITSECT(OP, GOMP_FLAG)                                       \
11797cc577a4SJonathan Peyton     MIN_MAX_CRITSECT(OP, LCK_ID)                                               \
11807cc577a4SJonathan Peyton   }                                                                            \
11817cc577a4SJonathan Peyton   }
11827cc577a4SJonathan Peyton 
11837cc577a4SJonathan Peyton #if KMP_ARCH_X86 || KMP_ARCH_X86_64
11847cc577a4SJonathan Peyton 
11857cc577a4SJonathan Peyton // -------------------------------------------------------------------------
11867cc577a4SJonathan Peyton // X86 or X86_64: no alignment problems ====================================
11873041982dSJonathan Peyton #define MIN_MAX_COMPXCHG(TYPE_ID, OP_ID, TYPE, BITS, OP, LCK_ID, MASK,         \
11883041982dSJonathan Peyton                          GOMP_FLAG)                                            \
11897cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
11907cc577a4SJonathan Peyton   if (*lhs OP rhs) {                                                           \
11917cc577a4SJonathan Peyton     GOMP_MIN_MAX_CRITSECT(OP, GOMP_FLAG)                                       \
11927cc577a4SJonathan Peyton     MIN_MAX_CMPXCHG(TYPE, BITS, OP)                                            \
11937cc577a4SJonathan Peyton   }                                                                            \
11947cc577a4SJonathan Peyton   }
11957cc577a4SJonathan Peyton 
11967cc577a4SJonathan Peyton #else
11977cc577a4SJonathan Peyton // -------------------------------------------------------------------------
11987cc577a4SJonathan Peyton // Code for other architectures that don't handle unaligned accesses.
11993041982dSJonathan Peyton #define MIN_MAX_COMPXCHG(TYPE_ID, OP_ID, TYPE, BITS, OP, LCK_ID, MASK,         \
12003041982dSJonathan Peyton                          GOMP_FLAG)                                            \
12017cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
12027cc577a4SJonathan Peyton   if (*lhs OP rhs) {                                                           \
12037cc577a4SJonathan Peyton     GOMP_MIN_MAX_CRITSECT(OP, GOMP_FLAG)                                       \
12047cc577a4SJonathan Peyton     if (!((kmp_uintptr_t)lhs & 0x##MASK)) {                                    \
12057cc577a4SJonathan Peyton       MIN_MAX_CMPXCHG(TYPE, BITS, OP) /* aligned address */                    \
12067cc577a4SJonathan Peyton     } else {                                                                   \
12077cc577a4SJonathan Peyton       KMP_CHECK_GTID;                                                          \
12087cc577a4SJonathan Peyton       MIN_MAX_CRITSECT(OP, LCK_ID) /* unaligned address */                     \
12097cc577a4SJonathan Peyton     }                                                                          \
12107cc577a4SJonathan Peyton   }                                                                            \
12117cc577a4SJonathan Peyton   }
12127cc577a4SJonathan Peyton #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
12137cc577a4SJonathan Peyton 
12143041982dSJonathan Peyton MIN_MAX_COMPXCHG(fixed1, max, char, 8, <, 1i, 0,
12153041982dSJonathan Peyton                  KMP_ARCH_X86) // __kmpc_atomic_fixed1_max
12163041982dSJonathan Peyton MIN_MAX_COMPXCHG(fixed1, min, char, 8, >, 1i, 0,
12173041982dSJonathan Peyton                  KMP_ARCH_X86) // __kmpc_atomic_fixed1_min
12183041982dSJonathan Peyton MIN_MAX_COMPXCHG(fixed2, max, short, 16, <, 2i, 1,
12193041982dSJonathan Peyton                  KMP_ARCH_X86) // __kmpc_atomic_fixed2_max
12203041982dSJonathan Peyton MIN_MAX_COMPXCHG(fixed2, min, short, 16, >, 2i, 1,
12213041982dSJonathan Peyton                  KMP_ARCH_X86) // __kmpc_atomic_fixed2_min
12223041982dSJonathan Peyton MIN_MAX_COMPXCHG(fixed4, max, kmp_int32, 32, <, 4i, 3,
12233041982dSJonathan Peyton                  0) // __kmpc_atomic_fixed4_max
12243041982dSJonathan Peyton MIN_MAX_COMPXCHG(fixed4, min, kmp_int32, 32, >, 4i, 3,
12253041982dSJonathan Peyton                  0) // __kmpc_atomic_fixed4_min
12263041982dSJonathan Peyton MIN_MAX_COMPXCHG(fixed8, max, kmp_int64, 64, <, 8i, 7,
12273041982dSJonathan Peyton                  KMP_ARCH_X86) // __kmpc_atomic_fixed8_max
12283041982dSJonathan Peyton MIN_MAX_COMPXCHG(fixed8, min, kmp_int64, 64, >, 8i, 7,
12293041982dSJonathan Peyton                  KMP_ARCH_X86) // __kmpc_atomic_fixed8_min
12303041982dSJonathan Peyton MIN_MAX_COMPXCHG(float4, max, kmp_real32, 32, <, 4r, 3,
12313041982dSJonathan Peyton                  KMP_ARCH_X86) // __kmpc_atomic_float4_max
12323041982dSJonathan Peyton MIN_MAX_COMPXCHG(float4, min, kmp_real32, 32, >, 4r, 3,
12333041982dSJonathan Peyton                  KMP_ARCH_X86) // __kmpc_atomic_float4_min
12343041982dSJonathan Peyton MIN_MAX_COMPXCHG(float8, max, kmp_real64, 64, <, 8r, 7,
12353041982dSJonathan Peyton                  KMP_ARCH_X86) // __kmpc_atomic_float8_max
12363041982dSJonathan Peyton MIN_MAX_COMPXCHG(float8, min, kmp_real64, 64, >, 8r, 7,
12373041982dSJonathan Peyton                  KMP_ARCH_X86) // __kmpc_atomic_float8_min
1238c1988dbfSMalhar Jajoo #if KMP_ARCH_X86 || KMP_ARCH_X86_64
1239621d7a75SAndreyChurbanov MIN_MAX_CRITICAL(float10, max, long double, <, 10r,
1240621d7a75SAndreyChurbanov                  1) // __kmpc_atomic_float10_max
1241621d7a75SAndreyChurbanov MIN_MAX_CRITICAL(float10, min, long double, >, 10r,
1242621d7a75SAndreyChurbanov                  1) // __kmpc_atomic_float10_min
1243c1988dbfSMalhar Jajoo #endif // KMP_ARCH_X86 || KMP_ARCH_X86_64
12447cc577a4SJonathan Peyton #if KMP_HAVE_QUAD
12453041982dSJonathan Peyton MIN_MAX_CRITICAL(float16, max, QUAD_LEGACY, <, 16r,
12463041982dSJonathan Peyton                  1) // __kmpc_atomic_float16_max
12473041982dSJonathan Peyton MIN_MAX_CRITICAL(float16, min, QUAD_LEGACY, >, 16r,
12483041982dSJonathan Peyton                  1) // __kmpc_atomic_float16_min
12497cc577a4SJonathan Peyton #if (KMP_ARCH_X86)
12503041982dSJonathan Peyton MIN_MAX_CRITICAL(float16, max_a16, Quad_a16_t, <, 16r,
12513041982dSJonathan Peyton                  1) // __kmpc_atomic_float16_max_a16
12523041982dSJonathan Peyton MIN_MAX_CRITICAL(float16, min_a16, Quad_a16_t, >, 16r,
12533041982dSJonathan Peyton                  1) // __kmpc_atomic_float16_min_a16
1254e4b4f994SJonathan Peyton #endif // (KMP_ARCH_X86)
1255e4b4f994SJonathan Peyton #endif // KMP_HAVE_QUAD
12567cc577a4SJonathan Peyton // ------------------------------------------------------------------------
12577cc577a4SJonathan Peyton // Need separate macros for .EQV. because of the need of complement (~)
12587cc577a4SJonathan Peyton // OP ignored for critical sections, ^=~ used instead
12597cc577a4SJonathan Peyton #define ATOMIC_CRIT_EQV(TYPE_ID, OP_ID, TYPE, OP, LCK_ID, GOMP_FLAG)           \
12607cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
126144a11c34SHansang Bae   OP_GOMP_CRITICAL(^= (TYPE) ~, GOMP_FLAG) /* send assignment */               \
126244a11c34SHansang Bae   OP_CRITICAL(^= (TYPE) ~, LCK_ID) /* send assignment and complement */        \
12637cc577a4SJonathan Peyton   }
12647cc577a4SJonathan Peyton 
12657cc577a4SJonathan Peyton // ------------------------------------------------------------------------
12667cc577a4SJonathan Peyton #if KMP_ARCH_X86 || KMP_ARCH_X86_64
12677cc577a4SJonathan Peyton // ------------------------------------------------------------------------
12687cc577a4SJonathan Peyton // X86 or X86_64: no alignment problems ===================================
12693041982dSJonathan Peyton #define ATOMIC_CMPX_EQV(TYPE_ID, OP_ID, TYPE, BITS, OP, LCK_ID, MASK,          \
12703041982dSJonathan Peyton                         GOMP_FLAG)                                             \
12717cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
127244a11c34SHansang Bae   OP_GOMP_CRITICAL(^= (TYPE) ~, GOMP_FLAG) /* send assignment */               \
12737cc577a4SJonathan Peyton   OP_CMPXCHG(TYPE, BITS, OP)                                                   \
12747cc577a4SJonathan Peyton   }
12757cc577a4SJonathan Peyton // ------------------------------------------------------------------------
12767cc577a4SJonathan Peyton #else
12777cc577a4SJonathan Peyton // ------------------------------------------------------------------------
12787cc577a4SJonathan Peyton // Code for other architectures that don't handle unaligned accesses.
12793041982dSJonathan Peyton #define ATOMIC_CMPX_EQV(TYPE_ID, OP_ID, TYPE, BITS, OP, LCK_ID, MASK,          \
12803041982dSJonathan Peyton                         GOMP_FLAG)                                             \
12817cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
128244a11c34SHansang Bae   OP_GOMP_CRITICAL(^= (TYPE) ~, GOMP_FLAG)                                     \
12837cc577a4SJonathan Peyton   if (!((kmp_uintptr_t)lhs & 0x##MASK)) {                                      \
12847cc577a4SJonathan Peyton     OP_CMPXCHG(TYPE, BITS, OP) /* aligned address */                           \
12857cc577a4SJonathan Peyton   } else {                                                                     \
12867cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
128744a11c34SHansang Bae     OP_CRITICAL(^= (TYPE) ~, LCK_ID) /* unaligned address - use critical */    \
12887cc577a4SJonathan Peyton   }                                                                            \
12897cc577a4SJonathan Peyton   }
12907cc577a4SJonathan Peyton #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
12917cc577a4SJonathan Peyton 
12923041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed1, neqv, kmp_int8, 8, ^, 1i, 0,
12933041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed1_neqv
12943041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed2, neqv, kmp_int16, 16, ^, 2i, 1,
12953041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed2_neqv
12963041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed4, neqv, kmp_int32, 32, ^, 4i, 3,
12973041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed4_neqv
12983041982dSJonathan Peyton ATOMIC_CMPXCHG(fixed8, neqv, kmp_int64, 64, ^, 8i, 7,
12993041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed8_neqv
13003041982dSJonathan Peyton ATOMIC_CMPX_EQV(fixed1, eqv, kmp_int8, 8, ^~, 1i, 0,
13013041982dSJonathan Peyton                 KMP_ARCH_X86) // __kmpc_atomic_fixed1_eqv
13023041982dSJonathan Peyton ATOMIC_CMPX_EQV(fixed2, eqv, kmp_int16, 16, ^~, 2i, 1,
13033041982dSJonathan Peyton                 KMP_ARCH_X86) // __kmpc_atomic_fixed2_eqv
13043041982dSJonathan Peyton ATOMIC_CMPX_EQV(fixed4, eqv, kmp_int32, 32, ^~, 4i, 3,
13053041982dSJonathan Peyton                 KMP_ARCH_X86) // __kmpc_atomic_fixed4_eqv
13063041982dSJonathan Peyton ATOMIC_CMPX_EQV(fixed8, eqv, kmp_int64, 64, ^~, 8i, 7,
13073041982dSJonathan Peyton                 KMP_ARCH_X86) // __kmpc_atomic_fixed8_eqv
13087cc577a4SJonathan Peyton 
13097cc577a4SJonathan Peyton // ------------------------------------------------------------------------
13103041982dSJonathan Peyton // Routines for Extended types: long double, _Quad, complex flavours (use
13113041982dSJonathan Peyton // critical section)
13127cc577a4SJonathan Peyton //     TYPE_ID, OP_ID, TYPE - detailed above
13137cc577a4SJonathan Peyton //     OP      - operator
13147cc577a4SJonathan Peyton //     LCK_ID  - lock identifier, used to possibly distinguish lock variable
13157cc577a4SJonathan Peyton #define ATOMIC_CRITICAL(TYPE_ID, OP_ID, TYPE, OP, LCK_ID, GOMP_FLAG)           \
13167cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
131744a11c34SHansang Bae   OP_UPDATE_GOMP_CRITICAL(TYPE, OP, GOMP_FLAG) /* send assignment */           \
131844a11c34SHansang Bae   OP_UPDATE_CRITICAL(TYPE, OP, LCK_ID) /* send assignment */                   \
13197cc577a4SJonathan Peyton   }
13207cc577a4SJonathan Peyton 
13217cc577a4SJonathan Peyton /* ------------------------------------------------------------------------- */
1322c1988dbfSMalhar Jajoo #if KMP_ARCH_X86 || KMP_ARCH_X86_64
13237cc577a4SJonathan Peyton // routines for long double type
13243041982dSJonathan Peyton ATOMIC_CRITICAL(float10, add, long double, +, 10r,
13253041982dSJonathan Peyton                 1) // __kmpc_atomic_float10_add
13263041982dSJonathan Peyton ATOMIC_CRITICAL(float10, sub, long double, -, 10r,
13273041982dSJonathan Peyton                 1) // __kmpc_atomic_float10_sub
13283041982dSJonathan Peyton ATOMIC_CRITICAL(float10, mul, long double, *, 10r,
13293041982dSJonathan Peyton                 1) // __kmpc_atomic_float10_mul
13303041982dSJonathan Peyton ATOMIC_CRITICAL(float10, div, long double, /, 10r,
13313041982dSJonathan Peyton                 1) // __kmpc_atomic_float10_div
1332c1988dbfSMalhar Jajoo #endif // KMP_ARCH_X86 || KMP_ARCH_X86_64
13337cc577a4SJonathan Peyton #if KMP_HAVE_QUAD
13347cc577a4SJonathan Peyton // routines for _Quad type
13353041982dSJonathan Peyton ATOMIC_CRITICAL(float16, add, QUAD_LEGACY, +, 16r,
13363041982dSJonathan Peyton                 1) // __kmpc_atomic_float16_add
13373041982dSJonathan Peyton ATOMIC_CRITICAL(float16, sub, QUAD_LEGACY, -, 16r,
13383041982dSJonathan Peyton                 1) // __kmpc_atomic_float16_sub
13393041982dSJonathan Peyton ATOMIC_CRITICAL(float16, mul, QUAD_LEGACY, *, 16r,
13403041982dSJonathan Peyton                 1) // __kmpc_atomic_float16_mul
13413041982dSJonathan Peyton ATOMIC_CRITICAL(float16, div, QUAD_LEGACY, /, 16r,
13423041982dSJonathan Peyton                 1) // __kmpc_atomic_float16_div
13437cc577a4SJonathan Peyton #if (KMP_ARCH_X86)
13443041982dSJonathan Peyton ATOMIC_CRITICAL(float16, add_a16, Quad_a16_t, +, 16r,
13453041982dSJonathan Peyton                 1) // __kmpc_atomic_float16_add_a16
13463041982dSJonathan Peyton ATOMIC_CRITICAL(float16, sub_a16, Quad_a16_t, -, 16r,
13473041982dSJonathan Peyton                 1) // __kmpc_atomic_float16_sub_a16
13483041982dSJonathan Peyton ATOMIC_CRITICAL(float16, mul_a16, Quad_a16_t, *, 16r,
13493041982dSJonathan Peyton                 1) // __kmpc_atomic_float16_mul_a16
13503041982dSJonathan Peyton ATOMIC_CRITICAL(float16, div_a16, Quad_a16_t, /, 16r,
13513041982dSJonathan Peyton                 1) // __kmpc_atomic_float16_div_a16
1352e4b4f994SJonathan Peyton #endif // (KMP_ARCH_X86)
1353e4b4f994SJonathan Peyton #endif // KMP_HAVE_QUAD
13547cc577a4SJonathan Peyton // routines for complex types
13557cc577a4SJonathan Peyton 
13567cc577a4SJonathan Peyton #if USE_CMPXCHG_FIX
13577cc577a4SJonathan Peyton // workaround for C78287 (complex(kind=4) data type)
13583041982dSJonathan Peyton ATOMIC_CMPXCHG_WORKAROUND(cmplx4, add, kmp_cmplx32, 64, +, 8c, 7,
13593041982dSJonathan Peyton                           1) // __kmpc_atomic_cmplx4_add
13603041982dSJonathan Peyton ATOMIC_CMPXCHG_WORKAROUND(cmplx4, sub, kmp_cmplx32, 64, -, 8c, 7,
13613041982dSJonathan Peyton                           1) // __kmpc_atomic_cmplx4_sub
13623041982dSJonathan Peyton ATOMIC_CMPXCHG_WORKAROUND(cmplx4, mul, kmp_cmplx32, 64, *, 8c, 7,
13633041982dSJonathan Peyton                           1) // __kmpc_atomic_cmplx4_mul
13643041982dSJonathan Peyton ATOMIC_CMPXCHG_WORKAROUND(cmplx4, div, kmp_cmplx32, 64, /, 8c, 7,
13653041982dSJonathan Peyton                           1) // __kmpc_atomic_cmplx4_div
13667cc577a4SJonathan Peyton // end of the workaround for C78287
13677cc577a4SJonathan Peyton #else
13687cc577a4SJonathan Peyton ATOMIC_CRITICAL(cmplx4, add, kmp_cmplx32, +, 8c, 1) // __kmpc_atomic_cmplx4_add
13697cc577a4SJonathan Peyton ATOMIC_CRITICAL(cmplx4, sub, kmp_cmplx32, -, 8c, 1) // __kmpc_atomic_cmplx4_sub
13707cc577a4SJonathan Peyton ATOMIC_CRITICAL(cmplx4, mul, kmp_cmplx32, *, 8c, 1) // __kmpc_atomic_cmplx4_mul
13717cc577a4SJonathan Peyton ATOMIC_CRITICAL(cmplx4, div, kmp_cmplx32, /, 8c, 1) // __kmpc_atomic_cmplx4_div
13727cc577a4SJonathan Peyton #endif // USE_CMPXCHG_FIX
13737cc577a4SJonathan Peyton 
13747cc577a4SJonathan Peyton ATOMIC_CRITICAL(cmplx8, add, kmp_cmplx64, +, 16c, 1) // __kmpc_atomic_cmplx8_add
13757cc577a4SJonathan Peyton ATOMIC_CRITICAL(cmplx8, sub, kmp_cmplx64, -, 16c, 1) // __kmpc_atomic_cmplx8_sub
13767cc577a4SJonathan Peyton ATOMIC_CRITICAL(cmplx8, mul, kmp_cmplx64, *, 16c, 1) // __kmpc_atomic_cmplx8_mul
13777cc577a4SJonathan Peyton ATOMIC_CRITICAL(cmplx8, div, kmp_cmplx64, /, 16c, 1) // __kmpc_atomic_cmplx8_div
1378c1988dbfSMalhar Jajoo #if KMP_ARCH_X86 || KMP_ARCH_X86_64
13793041982dSJonathan Peyton ATOMIC_CRITICAL(cmplx10, add, kmp_cmplx80, +, 20c,
13803041982dSJonathan Peyton                 1) // __kmpc_atomic_cmplx10_add
13813041982dSJonathan Peyton ATOMIC_CRITICAL(cmplx10, sub, kmp_cmplx80, -, 20c,
13823041982dSJonathan Peyton                 1) // __kmpc_atomic_cmplx10_sub
13833041982dSJonathan Peyton ATOMIC_CRITICAL(cmplx10, mul, kmp_cmplx80, *, 20c,
13843041982dSJonathan Peyton                 1) // __kmpc_atomic_cmplx10_mul
13853041982dSJonathan Peyton ATOMIC_CRITICAL(cmplx10, div, kmp_cmplx80, /, 20c,
13863041982dSJonathan Peyton                 1) // __kmpc_atomic_cmplx10_div
1387c1988dbfSMalhar Jajoo #endif // KMP_ARCH_X86 || KMP_ARCH_X86_64
13887cc577a4SJonathan Peyton #if KMP_HAVE_QUAD
13893041982dSJonathan Peyton ATOMIC_CRITICAL(cmplx16, add, CPLX128_LEG, +, 32c,
13903041982dSJonathan Peyton                 1) // __kmpc_atomic_cmplx16_add
13913041982dSJonathan Peyton ATOMIC_CRITICAL(cmplx16, sub, CPLX128_LEG, -, 32c,
13923041982dSJonathan Peyton                 1) // __kmpc_atomic_cmplx16_sub
13933041982dSJonathan Peyton ATOMIC_CRITICAL(cmplx16, mul, CPLX128_LEG, *, 32c,
13943041982dSJonathan Peyton                 1) // __kmpc_atomic_cmplx16_mul
13953041982dSJonathan Peyton ATOMIC_CRITICAL(cmplx16, div, CPLX128_LEG, /, 32c,
13963041982dSJonathan Peyton                 1) // __kmpc_atomic_cmplx16_div
13977cc577a4SJonathan Peyton #if (KMP_ARCH_X86)
13983041982dSJonathan Peyton ATOMIC_CRITICAL(cmplx16, add_a16, kmp_cmplx128_a16_t, +, 32c,
13993041982dSJonathan Peyton                 1) // __kmpc_atomic_cmplx16_add_a16
14003041982dSJonathan Peyton ATOMIC_CRITICAL(cmplx16, sub_a16, kmp_cmplx128_a16_t, -, 32c,
14013041982dSJonathan Peyton                 1) // __kmpc_atomic_cmplx16_sub_a16
14023041982dSJonathan Peyton ATOMIC_CRITICAL(cmplx16, mul_a16, kmp_cmplx128_a16_t, *, 32c,
14033041982dSJonathan Peyton                 1) // __kmpc_atomic_cmplx16_mul_a16
14043041982dSJonathan Peyton ATOMIC_CRITICAL(cmplx16, div_a16, kmp_cmplx128_a16_t, /, 32c,
14053041982dSJonathan Peyton                 1) // __kmpc_atomic_cmplx16_div_a16
1406e4b4f994SJonathan Peyton #endif // (KMP_ARCH_X86)
1407e4b4f994SJonathan Peyton #endif // KMP_HAVE_QUAD
14087cc577a4SJonathan Peyton 
14097cc577a4SJonathan Peyton // OpenMP 4.0: x = expr binop x for non-commutative operations.
14107cc577a4SJonathan Peyton // Supported only on IA-32 architecture and Intel(R) 64
14117cc577a4SJonathan Peyton #if KMP_ARCH_X86 || KMP_ARCH_X86_64
14127cc577a4SJonathan Peyton 
14137cc577a4SJonathan Peyton // ------------------------------------------------------------------------
14147cc577a4SJonathan Peyton // Operation on *lhs, rhs bound by critical section
14157cc577a4SJonathan Peyton //     OP     - operator (it's supposed to contain an assignment)
14167cc577a4SJonathan Peyton //     LCK_ID - lock identifier
14177cc577a4SJonathan Peyton // Note: don't check gtid as it should always be valid
14187cc577a4SJonathan Peyton // 1, 2-byte - expect valid parameter, other - check before this macro
141944a11c34SHansang Bae #define OP_CRITICAL_REV(TYPE, OP, LCK_ID)                                      \
14207cc577a4SJonathan Peyton   __kmp_acquire_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
14217cc577a4SJonathan Peyton                                                                                \
142244a11c34SHansang Bae   (*lhs) = (TYPE)((rhs)OP(*lhs));                                              \
14237cc577a4SJonathan Peyton                                                                                \
14247cc577a4SJonathan Peyton   __kmp_release_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);
14257cc577a4SJonathan Peyton 
14267cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
142744a11c34SHansang Bae #define OP_GOMP_CRITICAL_REV(TYPE, OP, FLAG)                                   \
14287cc577a4SJonathan Peyton   if ((FLAG) && (__kmp_atomic_mode == 2)) {                                    \
14297cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
143044a11c34SHansang Bae     OP_CRITICAL_REV(TYPE, OP, 0);                                              \
14317cc577a4SJonathan Peyton     return;                                                                    \
14327cc577a4SJonathan Peyton   }
143344a11c34SHansang Bae 
14347cc577a4SJonathan Peyton #else
143544a11c34SHansang Bae #define OP_GOMP_CRITICAL_REV(TYPE, OP, FLAG)
14367cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
14377cc577a4SJonathan Peyton 
14387cc577a4SJonathan Peyton // Beginning of a definition (provides name, parameters, gebug trace)
14393041982dSJonathan Peyton //     TYPE_ID - operands type and size (fixed*, fixed*u for signed, unsigned
14403041982dSJonathan Peyton //     fixed)
14417cc577a4SJonathan Peyton //     OP_ID   - operation identifier (add, sub, mul, ...)
14427cc577a4SJonathan Peyton //     TYPE    - operands' type
14437cc577a4SJonathan Peyton #define ATOMIC_BEGIN_REV(TYPE_ID, OP_ID, TYPE, RET_TYPE)                       \
14443041982dSJonathan Peyton   RET_TYPE __kmpc_atomic_##TYPE_ID##_##OP_ID##_rev(ident_t *id_ref, int gtid,  \
14453041982dSJonathan Peyton                                                    TYPE *lhs, TYPE rhs) {      \
14467cc577a4SJonathan Peyton     KMP_DEBUG_ASSERT(__kmp_init_serial);                                       \
14477cc577a4SJonathan Peyton     KA_TRACE(100, ("__kmpc_atomic_" #TYPE_ID "_" #OP_ID "_rev: T#%d\n", gtid));
14487cc577a4SJonathan Peyton 
14497cc577a4SJonathan Peyton // ------------------------------------------------------------------------
14507cc577a4SJonathan Peyton // Operation on *lhs, rhs using "compare_and_store" routine
14517cc577a4SJonathan Peyton //     TYPE    - operands' type
14527cc577a4SJonathan Peyton //     BITS    - size in bits, used to distinguish low level calls
14537cc577a4SJonathan Peyton //     OP      - operator
14547cc577a4SJonathan Peyton // Note: temp_val introduced in order to force the compiler to read
14557cc577a4SJonathan Peyton //       *lhs only once (w/o it the compiler reads *lhs twice)
14567cc577a4SJonathan Peyton #define OP_CMPXCHG_REV(TYPE, BITS, OP)                                         \
14577cc577a4SJonathan Peyton   {                                                                            \
14587cc577a4SJonathan Peyton     TYPE KMP_ATOMIC_VOLATILE temp_val;                                         \
14597cc577a4SJonathan Peyton     TYPE old_value, new_value;                                                 \
14607cc577a4SJonathan Peyton     temp_val = *lhs;                                                           \
14617cc577a4SJonathan Peyton     old_value = temp_val;                                                      \
146244a11c34SHansang Bae     new_value = (TYPE)(rhs OP old_value);                                      \
14633041982dSJonathan Peyton     while (!KMP_COMPARE_AND_STORE_ACQ##BITS(                                   \
14643041982dSJonathan Peyton         (kmp_int##BITS *)lhs, *VOLATILE_CAST(kmp_int##BITS *) & old_value,     \
14653041982dSJonathan Peyton         *VOLATILE_CAST(kmp_int##BITS *) & new_value)) {                        \
14667cc577a4SJonathan Peyton       KMP_DO_PAUSE;                                                            \
14677cc577a4SJonathan Peyton                                                                                \
14687cc577a4SJonathan Peyton       temp_val = *lhs;                                                         \
14697cc577a4SJonathan Peyton       old_value = temp_val;                                                    \
147044a11c34SHansang Bae       new_value = (TYPE)(rhs OP old_value);                                    \
14717cc577a4SJonathan Peyton     }                                                                          \
14727cc577a4SJonathan Peyton   }
14737cc577a4SJonathan Peyton 
14747cc577a4SJonathan Peyton // -------------------------------------------------------------------------
14757cc577a4SJonathan Peyton #define ATOMIC_CMPXCHG_REV(TYPE_ID, OP_ID, TYPE, BITS, OP, LCK_ID, GOMP_FLAG)  \
14767cc577a4SJonathan Peyton   ATOMIC_BEGIN_REV(TYPE_ID, OP_ID, TYPE, void)                                 \
147744a11c34SHansang Bae   OP_GOMP_CRITICAL_REV(TYPE, OP, GOMP_FLAG)                                    \
14787cc577a4SJonathan Peyton   OP_CMPXCHG_REV(TYPE, BITS, OP)                                               \
14797cc577a4SJonathan Peyton   }
14807cc577a4SJonathan Peyton 
14817cc577a4SJonathan Peyton // ------------------------------------------------------------------------
14827cc577a4SJonathan Peyton // Entries definition for integer operands
14837cc577a4SJonathan Peyton //     TYPE_ID - operands type and size (fixed4, float4)
14847cc577a4SJonathan Peyton //     OP_ID   - operation identifier (add, sub, mul, ...)
14857cc577a4SJonathan Peyton //     TYPE    - operand type
14867cc577a4SJonathan Peyton //     BITS    - size in bits, used to distinguish low level calls
14877cc577a4SJonathan Peyton //     OP      - operator (used in critical section)
14887cc577a4SJonathan Peyton //     LCK_ID  - lock identifier, used to possibly distinguish lock variable
14897cc577a4SJonathan Peyton 
14907cc577a4SJonathan Peyton //               TYPE_ID,OP_ID,  TYPE,   BITS,OP,LCK_ID,GOMP_FLAG
14917cc577a4SJonathan Peyton // ------------------------------------------------------------------------
14927cc577a4SJonathan Peyton // Routines for ATOMIC integer operands, other operators
14937cc577a4SJonathan Peyton // ------------------------------------------------------------------------
14947cc577a4SJonathan Peyton //                  TYPE_ID,OP_ID, TYPE,    BITS, OP, LCK_ID, GOMP_FLAG
14953041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed1, div, kmp_int8, 8, /, 1i,
14963041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1_div_rev
14973041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed1u, div, kmp_uint8, 8, /, 1i,
14983041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1u_div_rev
14993041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed1, shl, kmp_int8, 8, <<, 1i,
15003041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1_shl_rev
15013041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed1, shr, kmp_int8, 8, >>, 1i,
15023041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1_shr_rev
15033041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed1u, shr, kmp_uint8, 8, >>, 1i,
15043041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1u_shr_rev
15053041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed1, sub, kmp_int8, 8, -, 1i,
15063041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1_sub_rev
15077cc577a4SJonathan Peyton 
15083041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed2, div, kmp_int16, 16, /, 2i,
15093041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2_div_rev
15103041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed2u, div, kmp_uint16, 16, /, 2i,
15113041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2u_div_rev
15123041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed2, shl, kmp_int16, 16, <<, 2i,
15133041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2_shl_rev
15143041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed2, shr, kmp_int16, 16, >>, 2i,
15153041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2_shr_rev
15163041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed2u, shr, kmp_uint16, 16, >>, 2i,
15173041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2u_shr_rev
15183041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed2, sub, kmp_int16, 16, -, 2i,
15193041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2_sub_rev
15207cc577a4SJonathan Peyton 
15213041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed4, div, kmp_int32, 32, /, 4i,
15223041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed4_div_rev
15233041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed4u, div, kmp_uint32, 32, /, 4i,
15243041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed4u_div_rev
15253041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed4, shl, kmp_int32, 32, <<, 4i,
15263041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed4_shl_rev
15273041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed4, shr, kmp_int32, 32, >>, 4i,
15283041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed4_shr_rev
15293041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed4u, shr, kmp_uint32, 32, >>, 4i,
15303041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed4u_shr_rev
15313041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed4, sub, kmp_int32, 32, -, 4i,
15323041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed4_sub_rev
15337cc577a4SJonathan Peyton 
15343041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed8, div, kmp_int64, 64, /, 8i,
15353041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8_div_rev
15363041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed8u, div, kmp_uint64, 64, /, 8i,
15373041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8u_div_rev
15383041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed8, shl, kmp_int64, 64, <<, 8i,
15393041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8_shl_rev
15403041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed8, shr, kmp_int64, 64, >>, 8i,
15413041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8_shr_rev
15423041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed8u, shr, kmp_uint64, 64, >>, 8i,
15433041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8u_shr_rev
15443041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(fixed8, sub, kmp_int64, 64, -, 8i,
15453041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8_sub_rev
15467cc577a4SJonathan Peyton 
15473041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(float4, div, kmp_real32, 32, /, 4r,
15483041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float4_div_rev
15493041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(float4, sub, kmp_real32, 32, -, 4r,
15503041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float4_sub_rev
15517cc577a4SJonathan Peyton 
15523041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(float8, div, kmp_real64, 64, /, 8r,
15533041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float8_div_rev
15543041982dSJonathan Peyton ATOMIC_CMPXCHG_REV(float8, sub, kmp_real64, 64, -, 8r,
15553041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float8_sub_rev
15567cc577a4SJonathan Peyton //                  TYPE_ID,OP_ID, TYPE,     BITS,OP,LCK_ID, GOMP_FLAG
15577cc577a4SJonathan Peyton 
15587cc577a4SJonathan Peyton // ------------------------------------------------------------------------
15593041982dSJonathan Peyton // Routines for Extended types: long double, _Quad, complex flavours (use
15603041982dSJonathan Peyton // critical section)
15617cc577a4SJonathan Peyton //     TYPE_ID, OP_ID, TYPE - detailed above
15627cc577a4SJonathan Peyton //     OP      - operator
15637cc577a4SJonathan Peyton //     LCK_ID  - lock identifier, used to possibly distinguish lock variable
15647cc577a4SJonathan Peyton #define ATOMIC_CRITICAL_REV(TYPE_ID, OP_ID, TYPE, OP, LCK_ID, GOMP_FLAG)       \
15657cc577a4SJonathan Peyton   ATOMIC_BEGIN_REV(TYPE_ID, OP_ID, TYPE, void)                                 \
156644a11c34SHansang Bae   OP_GOMP_CRITICAL_REV(TYPE, OP, GOMP_FLAG)                                    \
156744a11c34SHansang Bae   OP_CRITICAL_REV(TYPE, OP, LCK_ID)                                            \
15687cc577a4SJonathan Peyton   }
15697cc577a4SJonathan Peyton 
15707cc577a4SJonathan Peyton /* ------------------------------------------------------------------------- */
15717cc577a4SJonathan Peyton // routines for long double type
15723041982dSJonathan Peyton ATOMIC_CRITICAL_REV(float10, sub, long double, -, 10r,
15733041982dSJonathan Peyton                     1) // __kmpc_atomic_float10_sub_rev
15743041982dSJonathan Peyton ATOMIC_CRITICAL_REV(float10, div, long double, /, 10r,
15753041982dSJonathan Peyton                     1) // __kmpc_atomic_float10_div_rev
15767cc577a4SJonathan Peyton #if KMP_HAVE_QUAD
15777cc577a4SJonathan Peyton // routines for _Quad type
15783041982dSJonathan Peyton ATOMIC_CRITICAL_REV(float16, sub, QUAD_LEGACY, -, 16r,
15793041982dSJonathan Peyton                     1) // __kmpc_atomic_float16_sub_rev
15803041982dSJonathan Peyton ATOMIC_CRITICAL_REV(float16, div, QUAD_LEGACY, /, 16r,
15813041982dSJonathan Peyton                     1) // __kmpc_atomic_float16_div_rev
15827cc577a4SJonathan Peyton #if (KMP_ARCH_X86)
15833041982dSJonathan Peyton ATOMIC_CRITICAL_REV(float16, sub_a16, Quad_a16_t, -, 16r,
15843041982dSJonathan Peyton                     1) // __kmpc_atomic_float16_sub_a16_rev
15853041982dSJonathan Peyton ATOMIC_CRITICAL_REV(float16, div_a16, Quad_a16_t, /, 16r,
15863041982dSJonathan Peyton                     1) // __kmpc_atomic_float16_div_a16_rev
1587e4b4f994SJonathan Peyton #endif // KMP_ARCH_X86
1588e4b4f994SJonathan Peyton #endif // KMP_HAVE_QUAD
15897cc577a4SJonathan Peyton 
15907cc577a4SJonathan Peyton // routines for complex types
15913041982dSJonathan Peyton ATOMIC_CRITICAL_REV(cmplx4, sub, kmp_cmplx32, -, 8c,
15923041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx4_sub_rev
15933041982dSJonathan Peyton ATOMIC_CRITICAL_REV(cmplx4, div, kmp_cmplx32, /, 8c,
15943041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx4_div_rev
15953041982dSJonathan Peyton ATOMIC_CRITICAL_REV(cmplx8, sub, kmp_cmplx64, -, 16c,
15963041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx8_sub_rev
15973041982dSJonathan Peyton ATOMIC_CRITICAL_REV(cmplx8, div, kmp_cmplx64, /, 16c,
15983041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx8_div_rev
15993041982dSJonathan Peyton ATOMIC_CRITICAL_REV(cmplx10, sub, kmp_cmplx80, -, 20c,
16003041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx10_sub_rev
16013041982dSJonathan Peyton ATOMIC_CRITICAL_REV(cmplx10, div, kmp_cmplx80, /, 20c,
16023041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx10_div_rev
16037cc577a4SJonathan Peyton #if KMP_HAVE_QUAD
16043041982dSJonathan Peyton ATOMIC_CRITICAL_REV(cmplx16, sub, CPLX128_LEG, -, 32c,
16053041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx16_sub_rev
16063041982dSJonathan Peyton ATOMIC_CRITICAL_REV(cmplx16, div, CPLX128_LEG, /, 32c,
16073041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx16_div_rev
16087cc577a4SJonathan Peyton #if (KMP_ARCH_X86)
16093041982dSJonathan Peyton ATOMIC_CRITICAL_REV(cmplx16, sub_a16, kmp_cmplx128_a16_t, -, 32c,
16103041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx16_sub_a16_rev
16113041982dSJonathan Peyton ATOMIC_CRITICAL_REV(cmplx16, div_a16, kmp_cmplx128_a16_t, /, 32c,
16123041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx16_div_a16_rev
1613e4b4f994SJonathan Peyton #endif // KMP_ARCH_X86
1614e4b4f994SJonathan Peyton #endif // KMP_HAVE_QUAD
16157cc577a4SJonathan Peyton 
16167cc577a4SJonathan Peyton #endif // KMP_ARCH_X86 || KMP_ARCH_X86_64
16177cc577a4SJonathan Peyton // End of OpenMP 4.0: x = expr binop x for non-commutative operations.
16187cc577a4SJonathan Peyton 
16197cc577a4SJonathan Peyton /* ------------------------------------------------------------------------ */
16207cc577a4SJonathan Peyton /* Routines for mixed types of LHS and RHS, when RHS is "larger"            */
16217cc577a4SJonathan Peyton /* Note: in order to reduce the total number of types combinations          */
16227cc577a4SJonathan Peyton /*       it is supposed that compiler converts RHS to longest floating type,*/
16237cc577a4SJonathan Peyton /*       that is _Quad, before call to any of these routines                */
16247cc577a4SJonathan Peyton /* Conversion to _Quad will be done by the compiler during calculation,     */
16257cc577a4SJonathan Peyton /*    conversion back to TYPE - before the assignment, like:                */
16267cc577a4SJonathan Peyton /*    *lhs = (TYPE)( (_Quad)(*lhs) OP rhs )                                 */
16277cc577a4SJonathan Peyton /* Performance penalty expected because of SW emulation use                 */
16287cc577a4SJonathan Peyton /* ------------------------------------------------------------------------ */
16297cc577a4SJonathan Peyton 
16307cc577a4SJonathan Peyton #define ATOMIC_BEGIN_MIX(TYPE_ID, TYPE, OP_ID, RTYPE_ID, RTYPE)                \
16313041982dSJonathan Peyton   void __kmpc_atomic_##TYPE_ID##_##OP_ID##_##RTYPE_ID(                         \
16323041982dSJonathan Peyton       ident_t *id_ref, int gtid, TYPE *lhs, RTYPE rhs) {                       \
16337cc577a4SJonathan Peyton     KMP_DEBUG_ASSERT(__kmp_init_serial);                                       \
16343041982dSJonathan Peyton     KA_TRACE(100,                                                              \
16353041982dSJonathan Peyton              ("__kmpc_atomic_" #TYPE_ID "_" #OP_ID "_" #RTYPE_ID ": T#%d\n",   \
16363041982dSJonathan Peyton               gtid));
16377cc577a4SJonathan Peyton 
16387cc577a4SJonathan Peyton // -------------------------------------------------------------------------
16393041982dSJonathan Peyton #define ATOMIC_CRITICAL_FP(TYPE_ID, TYPE, OP_ID, OP, RTYPE_ID, RTYPE, LCK_ID,  \
16403041982dSJonathan Peyton                            GOMP_FLAG)                                          \
16417cc577a4SJonathan Peyton   ATOMIC_BEGIN_MIX(TYPE_ID, TYPE, OP_ID, RTYPE_ID, RTYPE)                      \
164244a11c34SHansang Bae   OP_UPDATE_GOMP_CRITICAL(TYPE, OP, GOMP_FLAG) /* send assignment */           \
164344a11c34SHansang Bae   OP_UPDATE_CRITICAL(TYPE, OP, LCK_ID) /* send assignment */                   \
16447cc577a4SJonathan Peyton   }
16457cc577a4SJonathan Peyton 
16467cc577a4SJonathan Peyton // -------------------------------------------------------------------------
16477cc577a4SJonathan Peyton #if KMP_ARCH_X86 || KMP_ARCH_X86_64
16487cc577a4SJonathan Peyton // -------------------------------------------------------------------------
16497cc577a4SJonathan Peyton // X86 or X86_64: no alignment problems ====================================
16503041982dSJonathan Peyton #define ATOMIC_CMPXCHG_MIX(TYPE_ID, TYPE, OP_ID, BITS, OP, RTYPE_ID, RTYPE,    \
16513041982dSJonathan Peyton                            LCK_ID, MASK, GOMP_FLAG)                            \
16527cc577a4SJonathan Peyton   ATOMIC_BEGIN_MIX(TYPE_ID, TYPE, OP_ID, RTYPE_ID, RTYPE)                      \
165344a11c34SHansang Bae   OP_UPDATE_GOMP_CRITICAL(TYPE, OP, GOMP_FLAG)                                 \
16547cc577a4SJonathan Peyton   OP_CMPXCHG(TYPE, BITS, OP)                                                   \
16557cc577a4SJonathan Peyton   }
16567cc577a4SJonathan Peyton // -------------------------------------------------------------------------
16577cc577a4SJonathan Peyton #else
16587cc577a4SJonathan Peyton // ------------------------------------------------------------------------
16597cc577a4SJonathan Peyton // Code for other architectures that don't handle unaligned accesses.
16603041982dSJonathan Peyton #define ATOMIC_CMPXCHG_MIX(TYPE_ID, TYPE, OP_ID, BITS, OP, RTYPE_ID, RTYPE,    \
16613041982dSJonathan Peyton                            LCK_ID, MASK, GOMP_FLAG)                            \
16627cc577a4SJonathan Peyton   ATOMIC_BEGIN_MIX(TYPE_ID, TYPE, OP_ID, RTYPE_ID, RTYPE)                      \
166344a11c34SHansang Bae   OP_UPDATE_GOMP_CRITICAL(TYPE, OP, GOMP_FLAG)                                 \
16647cc577a4SJonathan Peyton   if (!((kmp_uintptr_t)lhs & 0x##MASK)) {                                      \
16657cc577a4SJonathan Peyton     OP_CMPXCHG(TYPE, BITS, OP) /* aligned address */                           \
16667cc577a4SJonathan Peyton   } else {                                                                     \
16677cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
166844a11c34SHansang Bae     OP_UPDATE_CRITICAL(TYPE, OP,                                               \
166944a11c34SHansang Bae                        LCK_ID) /* unaligned address - use critical */          \
16707cc577a4SJonathan Peyton   }                                                                            \
16717cc577a4SJonathan Peyton   }
16727cc577a4SJonathan Peyton #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
16737cc577a4SJonathan Peyton 
16747cc577a4SJonathan Peyton // -------------------------------------------------------------------------
16757cc577a4SJonathan Peyton #if KMP_ARCH_X86 || KMP_ARCH_X86_64
16767cc577a4SJonathan Peyton // -------------------------------------------------------------------------
16773041982dSJonathan Peyton #define ATOMIC_CMPXCHG_REV_MIX(TYPE_ID, TYPE, OP_ID, BITS, OP, RTYPE_ID,       \
16783041982dSJonathan Peyton                                RTYPE, LCK_ID, MASK, GOMP_FLAG)                 \
16797cc577a4SJonathan Peyton   ATOMIC_BEGIN_MIX(TYPE_ID, TYPE, OP_ID, RTYPE_ID, RTYPE)                      \
168044a11c34SHansang Bae   OP_GOMP_CRITICAL_REV(TYPE, OP, GOMP_FLAG)                                    \
16817cc577a4SJonathan Peyton   OP_CMPXCHG_REV(TYPE, BITS, OP)                                               \
16827cc577a4SJonathan Peyton   }
16833041982dSJonathan Peyton #define ATOMIC_CRITICAL_REV_FP(TYPE_ID, TYPE, OP_ID, OP, RTYPE_ID, RTYPE,      \
16843041982dSJonathan Peyton                                LCK_ID, GOMP_FLAG)                              \
16857cc577a4SJonathan Peyton   ATOMIC_BEGIN_MIX(TYPE_ID, TYPE, OP_ID, RTYPE_ID, RTYPE)                      \
168644a11c34SHansang Bae   OP_GOMP_CRITICAL_REV(TYPE, OP, GOMP_FLAG)                                    \
168744a11c34SHansang Bae   OP_CRITICAL_REV(TYPE, OP, LCK_ID)                                            \
16887cc577a4SJonathan Peyton   }
16897cc577a4SJonathan Peyton #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
16907cc577a4SJonathan Peyton 
16917cc577a4SJonathan Peyton // RHS=float8
16923041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed1, char, mul, 8, *, float8, kmp_real64, 1i, 0,
16933041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1_mul_float8
16943041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed1, char, div, 8, /, float8, kmp_real64, 1i, 0,
16953041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1_div_float8
16963041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed2, short, mul, 16, *, float8, kmp_real64, 2i, 1,
16973041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2_mul_float8
16983041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed2, short, div, 16, /, float8, kmp_real64, 2i, 1,
16993041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2_div_float8
17003041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed4, kmp_int32, mul, 32, *, float8, kmp_real64, 4i, 3,
17013041982dSJonathan Peyton                    0) // __kmpc_atomic_fixed4_mul_float8
17023041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed4, kmp_int32, div, 32, /, float8, kmp_real64, 4i, 3,
17033041982dSJonathan Peyton                    0) // __kmpc_atomic_fixed4_div_float8
17043041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed8, kmp_int64, mul, 64, *, float8, kmp_real64, 8i, 7,
17053041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8_mul_float8
17063041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed8, kmp_int64, div, 64, /, float8, kmp_real64, 8i, 7,
17073041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8_div_float8
17083041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(float4, kmp_real32, add, 32, +, float8, kmp_real64, 4r, 3,
17093041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float4_add_float8
17103041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(float4, kmp_real32, sub, 32, -, float8, kmp_real64, 4r, 3,
17113041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float4_sub_float8
17123041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(float4, kmp_real32, mul, 32, *, float8, kmp_real64, 4r, 3,
17133041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float4_mul_float8
17143041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(float4, kmp_real32, div, 32, /, float8, kmp_real64, 4r, 3,
17153041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float4_div_float8
17167cc577a4SJonathan Peyton 
17173041982dSJonathan Peyton // RHS=float16 (deprecated, to be removed when we are sure the compiler does not
17183041982dSJonathan Peyton // use them)
17197cc577a4SJonathan Peyton #if KMP_HAVE_QUAD
17203041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed1, char, add, 8, +, fp, _Quad, 1i, 0,
17213041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1_add_fp
17223041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed1u, uchar, add, 8, +, fp, _Quad, 1i, 0,
17233041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1u_add_fp
17243041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed1, char, sub, 8, -, fp, _Quad, 1i, 0,
17253041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1_sub_fp
17263041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed1u, uchar, sub, 8, -, fp, _Quad, 1i, 0,
17273041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1u_sub_fp
17283041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed1, char, mul, 8, *, fp, _Quad, 1i, 0,
17293041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1_mul_fp
17303041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed1u, uchar, mul, 8, *, fp, _Quad, 1i, 0,
17313041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1u_mul_fp
17323041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed1, char, div, 8, /, fp, _Quad, 1i, 0,
17333041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1_div_fp
17343041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed1u, uchar, div, 8, /, fp, _Quad, 1i, 0,
17353041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1u_div_fp
17367cc577a4SJonathan Peyton 
17373041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed2, short, add, 16, +, fp, _Quad, 2i, 1,
17383041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2_add_fp
17393041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed2u, ushort, add, 16, +, fp, _Quad, 2i, 1,
17403041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2u_add_fp
17413041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed2, short, sub, 16, -, fp, _Quad, 2i, 1,
17423041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2_sub_fp
17433041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed2u, ushort, sub, 16, -, fp, _Quad, 2i, 1,
17443041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2u_sub_fp
17453041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed2, short, mul, 16, *, fp, _Quad, 2i, 1,
17463041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2_mul_fp
17473041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed2u, ushort, mul, 16, *, fp, _Quad, 2i, 1,
17483041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2u_mul_fp
17493041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed2, short, div, 16, /, fp, _Quad, 2i, 1,
17503041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2_div_fp
17513041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed2u, ushort, div, 16, /, fp, _Quad, 2i, 1,
17523041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2u_div_fp
17537cc577a4SJonathan Peyton 
17543041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed4, kmp_int32, add, 32, +, fp, _Quad, 4i, 3,
17553041982dSJonathan Peyton                    0) // __kmpc_atomic_fixed4_add_fp
17563041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed4u, kmp_uint32, add, 32, +, fp, _Quad, 4i, 3,
17573041982dSJonathan Peyton                    0) // __kmpc_atomic_fixed4u_add_fp
17583041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed4, kmp_int32, sub, 32, -, fp, _Quad, 4i, 3,
17593041982dSJonathan Peyton                    0) // __kmpc_atomic_fixed4_sub_fp
17603041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed4u, kmp_uint32, sub, 32, -, fp, _Quad, 4i, 3,
17613041982dSJonathan Peyton                    0) // __kmpc_atomic_fixed4u_sub_fp
17623041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed4, kmp_int32, mul, 32, *, fp, _Quad, 4i, 3,
17633041982dSJonathan Peyton                    0) // __kmpc_atomic_fixed4_mul_fp
17643041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed4u, kmp_uint32, mul, 32, *, fp, _Quad, 4i, 3,
17653041982dSJonathan Peyton                    0) // __kmpc_atomic_fixed4u_mul_fp
17663041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed4, kmp_int32, div, 32, /, fp, _Quad, 4i, 3,
17673041982dSJonathan Peyton                    0) // __kmpc_atomic_fixed4_div_fp
17683041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed4u, kmp_uint32, div, 32, /, fp, _Quad, 4i, 3,
17693041982dSJonathan Peyton                    0) // __kmpc_atomic_fixed4u_div_fp
17707cc577a4SJonathan Peyton 
17713041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed8, kmp_int64, add, 64, +, fp, _Quad, 8i, 7,
17723041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8_add_fp
17733041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed8u, kmp_uint64, add, 64, +, fp, _Quad, 8i, 7,
17743041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8u_add_fp
17753041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed8, kmp_int64, sub, 64, -, fp, _Quad, 8i, 7,
17763041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8_sub_fp
17773041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed8u, kmp_uint64, sub, 64, -, fp, _Quad, 8i, 7,
17783041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8u_sub_fp
17793041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed8, kmp_int64, mul, 64, *, fp, _Quad, 8i, 7,
17803041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8_mul_fp
17813041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed8u, kmp_uint64, mul, 64, *, fp, _Quad, 8i, 7,
17823041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8u_mul_fp
17833041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed8, kmp_int64, div, 64, /, fp, _Quad, 8i, 7,
17843041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8_div_fp
17853041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(fixed8u, kmp_uint64, div, 64, /, fp, _Quad, 8i, 7,
17863041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8u_div_fp
17877cc577a4SJonathan Peyton 
17883041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(float4, kmp_real32, add, 32, +, fp, _Quad, 4r, 3,
17893041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float4_add_fp
17903041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(float4, kmp_real32, sub, 32, -, fp, _Quad, 4r, 3,
17913041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float4_sub_fp
17923041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(float4, kmp_real32, mul, 32, *, fp, _Quad, 4r, 3,
17933041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float4_mul_fp
17943041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(float4, kmp_real32, div, 32, /, fp, _Quad, 4r, 3,
17953041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float4_div_fp
17967cc577a4SJonathan Peyton 
17973041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(float8, kmp_real64, add, 64, +, fp, _Quad, 8r, 7,
17983041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float8_add_fp
17993041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(float8, kmp_real64, sub, 64, -, fp, _Quad, 8r, 7,
18003041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float8_sub_fp
18013041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(float8, kmp_real64, mul, 64, *, fp, _Quad, 8r, 7,
18023041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float8_mul_fp
18033041982dSJonathan Peyton ATOMIC_CMPXCHG_MIX(float8, kmp_real64, div, 64, /, fp, _Quad, 8r, 7,
18043041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float8_div_fp
18057cc577a4SJonathan Peyton 
1806c1988dbfSMalhar Jajoo #if KMP_ARCH_X86 || KMP_ARCH_X86_64
18073041982dSJonathan Peyton ATOMIC_CRITICAL_FP(float10, long double, add, +, fp, _Quad, 10r,
18083041982dSJonathan Peyton                    1) // __kmpc_atomic_float10_add_fp
18093041982dSJonathan Peyton ATOMIC_CRITICAL_FP(float10, long double, sub, -, fp, _Quad, 10r,
18103041982dSJonathan Peyton                    1) // __kmpc_atomic_float10_sub_fp
18113041982dSJonathan Peyton ATOMIC_CRITICAL_FP(float10, long double, mul, *, fp, _Quad, 10r,
18123041982dSJonathan Peyton                    1) // __kmpc_atomic_float10_mul_fp
18133041982dSJonathan Peyton ATOMIC_CRITICAL_FP(float10, long double, div, /, fp, _Quad, 10r,
18143041982dSJonathan Peyton                    1) // __kmpc_atomic_float10_div_fp
18157cc577a4SJonathan Peyton 
18167cc577a4SJonathan Peyton // Reverse operations
18173041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(fixed1, char, sub_rev, 8, -, fp, _Quad, 1i, 0,
18183041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed1_sub_rev_fp
18193041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(fixed1u, uchar, sub_rev, 8, -, fp, _Quad, 1i, 0,
18203041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed1u_sub_rev_fp
18213041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(fixed1, char, div_rev, 8, /, fp, _Quad, 1i, 0,
18223041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed1_div_rev_fp
18233041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(fixed1u, uchar, div_rev, 8, /, fp, _Quad, 1i, 0,
18243041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed1u_div_rev_fp
18257cc577a4SJonathan Peyton 
18263041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(fixed2, short, sub_rev, 16, -, fp, _Quad, 2i, 1,
18273041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed2_sub_rev_fp
18283041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(fixed2u, ushort, sub_rev, 16, -, fp, _Quad, 2i, 1,
18293041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed2u_sub_rev_fp
18303041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(fixed2, short, div_rev, 16, /, fp, _Quad, 2i, 1,
18313041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed2_div_rev_fp
18323041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(fixed2u, ushort, div_rev, 16, /, fp, _Quad, 2i, 1,
18333041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed2u_div_rev_fp
18347cc577a4SJonathan Peyton 
18353041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(fixed4, kmp_int32, sub_rev, 32, -, fp, _Quad, 4i, 3,
18363041982dSJonathan Peyton                        0) // __kmpc_atomic_fixed4_sub_rev_fp
18373041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(fixed4u, kmp_uint32, sub_rev, 32, -, fp, _Quad, 4i, 3,
18383041982dSJonathan Peyton                        0) // __kmpc_atomic_fixed4u_sub_rev_fp
18393041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(fixed4, kmp_int32, div_rev, 32, /, fp, _Quad, 4i, 3,
18403041982dSJonathan Peyton                        0) // __kmpc_atomic_fixed4_div_rev_fp
18413041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(fixed4u, kmp_uint32, div_rev, 32, /, fp, _Quad, 4i, 3,
18423041982dSJonathan Peyton                        0) // __kmpc_atomic_fixed4u_div_rev_fp
18437cc577a4SJonathan Peyton 
18443041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(fixed8, kmp_int64, sub_rev, 64, -, fp, _Quad, 8i, 7,
18453041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed8_sub_rev_fp
18463041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(fixed8u, kmp_uint64, sub_rev, 64, -, fp, _Quad, 8i, 7,
18473041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed8u_sub_rev_fp
18483041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(fixed8, kmp_int64, div_rev, 64, /, fp, _Quad, 8i, 7,
18493041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed8_div_rev_fp
18503041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(fixed8u, kmp_uint64, div_rev, 64, /, fp, _Quad, 8i, 7,
18513041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed8u_div_rev_fp
18527cc577a4SJonathan Peyton 
18533041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(float4, kmp_real32, sub_rev, 32, -, fp, _Quad, 4r, 3,
18543041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_float4_sub_rev_fp
18553041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(float4, kmp_real32, div_rev, 32, /, fp, _Quad, 4r, 3,
18563041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_float4_div_rev_fp
18577cc577a4SJonathan Peyton 
18583041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(float8, kmp_real64, sub_rev, 64, -, fp, _Quad, 8r, 7,
18593041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_float8_sub_rev_fp
18603041982dSJonathan Peyton ATOMIC_CMPXCHG_REV_MIX(float8, kmp_real64, div_rev, 64, /, fp, _Quad, 8r, 7,
18613041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_float8_div_rev_fp
18627cc577a4SJonathan Peyton 
18633041982dSJonathan Peyton ATOMIC_CRITICAL_REV_FP(float10, long double, sub_rev, -, fp, _Quad, 10r,
18643041982dSJonathan Peyton                        1) // __kmpc_atomic_float10_sub_rev_fp
18653041982dSJonathan Peyton ATOMIC_CRITICAL_REV_FP(float10, long double, div_rev, /, fp, _Quad, 10r,
18663041982dSJonathan Peyton                        1) // __kmpc_atomic_float10_div_rev_fp
18677cc577a4SJonathan Peyton #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
18687cc577a4SJonathan Peyton 
1869e4b4f994SJonathan Peyton #endif // KMP_HAVE_QUAD
18707cc577a4SJonathan Peyton 
18717cc577a4SJonathan Peyton #if KMP_ARCH_X86 || KMP_ARCH_X86_64
18727cc577a4SJonathan Peyton // ------------------------------------------------------------------------
18737cc577a4SJonathan Peyton // X86 or X86_64: no alignment problems ====================================
18747cc577a4SJonathan Peyton #if USE_CMPXCHG_FIX
18757cc577a4SJonathan Peyton // workaround for C78287 (complex(kind=4) data type)
18763041982dSJonathan Peyton #define ATOMIC_CMPXCHG_CMPLX(TYPE_ID, TYPE, OP_ID, BITS, OP, RTYPE_ID, RTYPE,  \
18773041982dSJonathan Peyton                              LCK_ID, MASK, GOMP_FLAG)                          \
18787cc577a4SJonathan Peyton   ATOMIC_BEGIN_MIX(TYPE_ID, TYPE, OP_ID, RTYPE_ID, RTYPE)                      \
187944a11c34SHansang Bae   OP_UPDATE_GOMP_CRITICAL(TYPE, OP, GOMP_FLAG)                                 \
18807cc577a4SJonathan Peyton   OP_CMPXCHG_WORKAROUND(TYPE, BITS, OP)                                        \
18817cc577a4SJonathan Peyton   }
18827cc577a4SJonathan Peyton // end of the second part of the workaround for C78287
18837cc577a4SJonathan Peyton #else
18843041982dSJonathan Peyton #define ATOMIC_CMPXCHG_CMPLX(TYPE_ID, TYPE, OP_ID, BITS, OP, RTYPE_ID, RTYPE,  \
18853041982dSJonathan Peyton                              LCK_ID, MASK, GOMP_FLAG)                          \
18867cc577a4SJonathan Peyton   ATOMIC_BEGIN_MIX(TYPE_ID, TYPE, OP_ID, RTYPE_ID, RTYPE)                      \
188744a11c34SHansang Bae   OP_UPDATE_GOMP_CRITICAL(TYPE, OP, GOMP_FLAG)                                 \
18887cc577a4SJonathan Peyton   OP_CMPXCHG(TYPE, BITS, OP)                                                   \
18897cc577a4SJonathan Peyton   }
18907cc577a4SJonathan Peyton #endif // USE_CMPXCHG_FIX
18917cc577a4SJonathan Peyton #else
18927cc577a4SJonathan Peyton // ------------------------------------------------------------------------
18937cc577a4SJonathan Peyton // Code for other architectures that don't handle unaligned accesses.
18943041982dSJonathan Peyton #define ATOMIC_CMPXCHG_CMPLX(TYPE_ID, TYPE, OP_ID, BITS, OP, RTYPE_ID, RTYPE,  \
18953041982dSJonathan Peyton                              LCK_ID, MASK, GOMP_FLAG)                          \
18967cc577a4SJonathan Peyton   ATOMIC_BEGIN_MIX(TYPE_ID, TYPE, OP_ID, RTYPE_ID, RTYPE)                      \
189744a11c34SHansang Bae   OP_UPDATE_GOMP_CRITICAL(TYPE, OP, GOMP_FLAG)                                 \
18987cc577a4SJonathan Peyton   if (!((kmp_uintptr_t)lhs & 0x##MASK)) {                                      \
18997cc577a4SJonathan Peyton     OP_CMPXCHG(TYPE, BITS, OP) /* aligned address */                           \
19007cc577a4SJonathan Peyton   } else {                                                                     \
19017cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
190244a11c34SHansang Bae     OP_UPDATE_CRITICAL(TYPE, OP,                                               \
190344a11c34SHansang Bae                        LCK_ID) /* unaligned address - use critical */          \
19047cc577a4SJonathan Peyton   }                                                                            \
19057cc577a4SJonathan Peyton   }
19067cc577a4SJonathan Peyton #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
19077cc577a4SJonathan Peyton 
19083041982dSJonathan Peyton ATOMIC_CMPXCHG_CMPLX(cmplx4, kmp_cmplx32, add, 64, +, cmplx8, kmp_cmplx64, 8c,
19093041982dSJonathan Peyton                      7, KMP_ARCH_X86) // __kmpc_atomic_cmplx4_add_cmplx8
19103041982dSJonathan Peyton ATOMIC_CMPXCHG_CMPLX(cmplx4, kmp_cmplx32, sub, 64, -, cmplx8, kmp_cmplx64, 8c,
19113041982dSJonathan Peyton                      7, KMP_ARCH_X86) // __kmpc_atomic_cmplx4_sub_cmplx8
19123041982dSJonathan Peyton ATOMIC_CMPXCHG_CMPLX(cmplx4, kmp_cmplx32, mul, 64, *, cmplx8, kmp_cmplx64, 8c,
19133041982dSJonathan Peyton                      7, KMP_ARCH_X86) // __kmpc_atomic_cmplx4_mul_cmplx8
19143041982dSJonathan Peyton ATOMIC_CMPXCHG_CMPLX(cmplx4, kmp_cmplx32, div, 64, /, cmplx8, kmp_cmplx64, 8c,
19153041982dSJonathan Peyton                      7, KMP_ARCH_X86) // __kmpc_atomic_cmplx4_div_cmplx8
19167cc577a4SJonathan Peyton 
19177cc577a4SJonathan Peyton // READ, WRITE, CAPTURE are supported only on IA-32 architecture and Intel(R) 64
19187cc577a4SJonathan Peyton #if KMP_ARCH_X86 || KMP_ARCH_X86_64
19197cc577a4SJonathan Peyton 
19207cc577a4SJonathan Peyton // ------------------------------------------------------------------------
19217cc577a4SJonathan Peyton // Atomic READ routines
19227cc577a4SJonathan Peyton 
19237cc577a4SJonathan Peyton // ------------------------------------------------------------------------
19247cc577a4SJonathan Peyton // Beginning of a definition (provides name, parameters, gebug trace)
19253041982dSJonathan Peyton //     TYPE_ID - operands type and size (fixed*, fixed*u for signed, unsigned
19263041982dSJonathan Peyton //     fixed)
19277cc577a4SJonathan Peyton //     OP_ID   - operation identifier (add, sub, mul, ...)
19287cc577a4SJonathan Peyton //     TYPE    - operands' type
19297cc577a4SJonathan Peyton #define ATOMIC_BEGIN_READ(TYPE_ID, OP_ID, TYPE, RET_TYPE)                      \
19303041982dSJonathan Peyton   RET_TYPE __kmpc_atomic_##TYPE_ID##_##OP_ID(ident_t *id_ref, int gtid,        \
19313041982dSJonathan Peyton                                              TYPE *loc) {                      \
19327cc577a4SJonathan Peyton     KMP_DEBUG_ASSERT(__kmp_init_serial);                                       \
19337cc577a4SJonathan Peyton     KA_TRACE(100, ("__kmpc_atomic_" #TYPE_ID "_" #OP_ID ": T#%d\n", gtid));
19347cc577a4SJonathan Peyton 
19357cc577a4SJonathan Peyton // ------------------------------------------------------------------------
19367cc577a4SJonathan Peyton // Operation on *lhs, rhs using "compare_and_store_ret" routine
19377cc577a4SJonathan Peyton //     TYPE    - operands' type
19387cc577a4SJonathan Peyton //     BITS    - size in bits, used to distinguish low level calls
19397cc577a4SJonathan Peyton //     OP      - operator
19407cc577a4SJonathan Peyton // Note: temp_val introduced in order to force the compiler to read
19417cc577a4SJonathan Peyton //       *lhs only once (w/o it the compiler reads *lhs twice)
19427cc577a4SJonathan Peyton // TODO: check if it is still necessary
19437cc577a4SJonathan Peyton // Return old value regardless of the result of "compare & swap# operation
19447cc577a4SJonathan Peyton #define OP_CMPXCHG_READ(TYPE, BITS, OP)                                        \
19457cc577a4SJonathan Peyton   {                                                                            \
19467cc577a4SJonathan Peyton     TYPE KMP_ATOMIC_VOLATILE temp_val;                                         \
19477cc577a4SJonathan Peyton     union f_i_union {                                                          \
19487cc577a4SJonathan Peyton       TYPE f_val;                                                              \
19497cc577a4SJonathan Peyton       kmp_int##BITS i_val;                                                     \
19507cc577a4SJonathan Peyton     };                                                                         \
19517cc577a4SJonathan Peyton     union f_i_union old_value;                                                 \
19527cc577a4SJonathan Peyton     temp_val = *loc;                                                           \
19537cc577a4SJonathan Peyton     old_value.f_val = temp_val;                                                \
19543041982dSJonathan Peyton     old_value.i_val = KMP_COMPARE_AND_STORE_RET##BITS(                         \
19553041982dSJonathan Peyton         (kmp_int##BITS *)loc,                                                  \
19567cc577a4SJonathan Peyton         *VOLATILE_CAST(kmp_int##BITS *) & old_value.i_val,                     \
19577cc577a4SJonathan Peyton         *VOLATILE_CAST(kmp_int##BITS *) & old_value.i_val);                    \
19587cc577a4SJonathan Peyton     new_value = old_value.f_val;                                               \
19597cc577a4SJonathan Peyton     return new_value;                                                          \
19607cc577a4SJonathan Peyton   }
19617cc577a4SJonathan Peyton 
19627cc577a4SJonathan Peyton // -------------------------------------------------------------------------
19637cc577a4SJonathan Peyton // Operation on *lhs, rhs bound by critical section
19647cc577a4SJonathan Peyton //     OP     - operator (it's supposed to contain an assignment)
19657cc577a4SJonathan Peyton //     LCK_ID - lock identifier
19667cc577a4SJonathan Peyton // Note: don't check gtid as it should always be valid
19677cc577a4SJonathan Peyton // 1, 2-byte - expect valid parameter, other - check before this macro
19687cc577a4SJonathan Peyton #define OP_CRITICAL_READ(OP, LCK_ID)                                           \
19697cc577a4SJonathan Peyton   __kmp_acquire_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
19707cc577a4SJonathan Peyton                                                                                \
19717cc577a4SJonathan Peyton   new_value = (*loc);                                                          \
19727cc577a4SJonathan Peyton                                                                                \
19737cc577a4SJonathan Peyton   __kmp_release_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);
19747cc577a4SJonathan Peyton 
19757cc577a4SJonathan Peyton // -------------------------------------------------------------------------
19767cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
19777cc577a4SJonathan Peyton #define OP_GOMP_CRITICAL_READ(OP, FLAG)                                        \
19787cc577a4SJonathan Peyton   if ((FLAG) && (__kmp_atomic_mode == 2)) {                                    \
19797cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
19807cc577a4SJonathan Peyton     OP_CRITICAL_READ(OP, 0);                                                   \
19817cc577a4SJonathan Peyton     return new_value;                                                          \
19827cc577a4SJonathan Peyton   }
19837cc577a4SJonathan Peyton #else
19847cc577a4SJonathan Peyton #define OP_GOMP_CRITICAL_READ(OP, FLAG)
19857cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
19867cc577a4SJonathan Peyton 
19877cc577a4SJonathan Peyton // -------------------------------------------------------------------------
19887cc577a4SJonathan Peyton #define ATOMIC_FIXED_READ(TYPE_ID, OP_ID, TYPE, BITS, OP, GOMP_FLAG)           \
19897cc577a4SJonathan Peyton   ATOMIC_BEGIN_READ(TYPE_ID, OP_ID, TYPE, TYPE)                                \
19907cc577a4SJonathan Peyton   TYPE new_value;                                                              \
19917cc577a4SJonathan Peyton   OP_GOMP_CRITICAL_READ(OP## =, GOMP_FLAG)                                     \
19927cc577a4SJonathan Peyton   new_value = KMP_TEST_THEN_ADD##BITS(loc, OP 0);                              \
19937cc577a4SJonathan Peyton   return new_value;                                                            \
19947cc577a4SJonathan Peyton   }
19957cc577a4SJonathan Peyton // -------------------------------------------------------------------------
19967cc577a4SJonathan Peyton #define ATOMIC_CMPXCHG_READ(TYPE_ID, OP_ID, TYPE, BITS, OP, GOMP_FLAG)         \
19977cc577a4SJonathan Peyton   ATOMIC_BEGIN_READ(TYPE_ID, OP_ID, TYPE, TYPE)                                \
19987cc577a4SJonathan Peyton   TYPE new_value;                                                              \
19997cc577a4SJonathan Peyton   OP_GOMP_CRITICAL_READ(OP## =, GOMP_FLAG)                                     \
20007cc577a4SJonathan Peyton   OP_CMPXCHG_READ(TYPE, BITS, OP)                                              \
20017cc577a4SJonathan Peyton   }
20027cc577a4SJonathan Peyton // ------------------------------------------------------------------------
20033041982dSJonathan Peyton // Routines for Extended types: long double, _Quad, complex flavours (use
20043041982dSJonathan Peyton // critical section)
20057cc577a4SJonathan Peyton //     TYPE_ID, OP_ID, TYPE - detailed above
20067cc577a4SJonathan Peyton //     OP      - operator
20077cc577a4SJonathan Peyton //     LCK_ID  - lock identifier, used to possibly distinguish lock variable
20087cc577a4SJonathan Peyton #define ATOMIC_CRITICAL_READ(TYPE_ID, OP_ID, TYPE, OP, LCK_ID, GOMP_FLAG)      \
20097cc577a4SJonathan Peyton   ATOMIC_BEGIN_READ(TYPE_ID, OP_ID, TYPE, TYPE)                                \
20107cc577a4SJonathan Peyton   TYPE new_value;                                                              \
20117cc577a4SJonathan Peyton   OP_GOMP_CRITICAL_READ(OP## =, GOMP_FLAG) /* send assignment */               \
20127cc577a4SJonathan Peyton   OP_CRITICAL_READ(OP, LCK_ID) /* send assignment */                           \
20137cc577a4SJonathan Peyton   return new_value;                                                            \
20147cc577a4SJonathan Peyton   }
20157cc577a4SJonathan Peyton 
20167cc577a4SJonathan Peyton // ------------------------------------------------------------------------
20173041982dSJonathan Peyton // Fix for cmplx4 read (CQ220361) on Windows* OS. Regular routine with return
20183041982dSJonathan Peyton // value doesn't work.
20197cc577a4SJonathan Peyton // Let's return the read value through the additional parameter.
20207cc577a4SJonathan Peyton #if (KMP_OS_WINDOWS)
20217cc577a4SJonathan Peyton 
20227cc577a4SJonathan Peyton #define OP_CRITICAL_READ_WRK(OP, LCK_ID)                                       \
20237cc577a4SJonathan Peyton   __kmp_acquire_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
20247cc577a4SJonathan Peyton                                                                                \
20257cc577a4SJonathan Peyton   (*out) = (*loc);                                                             \
20267cc577a4SJonathan Peyton                                                                                \
20277cc577a4SJonathan Peyton   __kmp_release_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);
20287cc577a4SJonathan Peyton // ------------------------------------------------------------------------
20297cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
20307cc577a4SJonathan Peyton #define OP_GOMP_CRITICAL_READ_WRK(OP, FLAG)                                    \
20317cc577a4SJonathan Peyton   if ((FLAG) && (__kmp_atomic_mode == 2)) {                                    \
20327cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
20337cc577a4SJonathan Peyton     OP_CRITICAL_READ_WRK(OP, 0);                                               \
20347cc577a4SJonathan Peyton   }
20357cc577a4SJonathan Peyton #else
20367cc577a4SJonathan Peyton #define OP_GOMP_CRITICAL_READ_WRK(OP, FLAG)
20377cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
20387cc577a4SJonathan Peyton // ------------------------------------------------------------------------
20397cc577a4SJonathan Peyton #define ATOMIC_BEGIN_READ_WRK(TYPE_ID, OP_ID, TYPE)                            \
20403041982dSJonathan Peyton   void __kmpc_atomic_##TYPE_ID##_##OP_ID(TYPE *out, ident_t *id_ref, int gtid, \
20413041982dSJonathan Peyton                                          TYPE *loc) {                          \
20427cc577a4SJonathan Peyton     KMP_DEBUG_ASSERT(__kmp_init_serial);                                       \
20437cc577a4SJonathan Peyton     KA_TRACE(100, ("__kmpc_atomic_" #TYPE_ID "_" #OP_ID ": T#%d\n", gtid));
20447cc577a4SJonathan Peyton 
20457cc577a4SJonathan Peyton // ------------------------------------------------------------------------
20467cc577a4SJonathan Peyton #define ATOMIC_CRITICAL_READ_WRK(TYPE_ID, OP_ID, TYPE, OP, LCK_ID, GOMP_FLAG)  \
20477cc577a4SJonathan Peyton   ATOMIC_BEGIN_READ_WRK(TYPE_ID, OP_ID, TYPE)                                  \
20487cc577a4SJonathan Peyton   OP_GOMP_CRITICAL_READ_WRK(OP## =, GOMP_FLAG) /* send assignment */           \
20497cc577a4SJonathan Peyton   OP_CRITICAL_READ_WRK(OP, LCK_ID) /* send assignment */                       \
20507cc577a4SJonathan Peyton   }
20517cc577a4SJonathan Peyton 
20527cc577a4SJonathan Peyton #endif // KMP_OS_WINDOWS
20537cc577a4SJonathan Peyton 
20547cc577a4SJonathan Peyton // ------------------------------------------------------------------------
20557cc577a4SJonathan Peyton //                  TYPE_ID,OP_ID, TYPE,      OP, GOMP_FLAG
20567cc577a4SJonathan Peyton ATOMIC_FIXED_READ(fixed4, rd, kmp_int32, 32, +, 0) // __kmpc_atomic_fixed4_rd
20573041982dSJonathan Peyton ATOMIC_FIXED_READ(fixed8, rd, kmp_int64, 64, +,
20583041982dSJonathan Peyton                   KMP_ARCH_X86) // __kmpc_atomic_fixed8_rd
20593041982dSJonathan Peyton ATOMIC_CMPXCHG_READ(float4, rd, kmp_real32, 32, +,
20603041982dSJonathan Peyton                     KMP_ARCH_X86) // __kmpc_atomic_float4_rd
20613041982dSJonathan Peyton ATOMIC_CMPXCHG_READ(float8, rd, kmp_real64, 64, +,
20623041982dSJonathan Peyton                     KMP_ARCH_X86) // __kmpc_atomic_float8_rd
20637cc577a4SJonathan Peyton 
20647cc577a4SJonathan Peyton // !!! TODO: Remove lock operations for "char" since it can't be non-atomic
20653041982dSJonathan Peyton ATOMIC_CMPXCHG_READ(fixed1, rd, kmp_int8, 8, +,
20663041982dSJonathan Peyton                     KMP_ARCH_X86) // __kmpc_atomic_fixed1_rd
20673041982dSJonathan Peyton ATOMIC_CMPXCHG_READ(fixed2, rd, kmp_int16, 16, +,
20683041982dSJonathan Peyton                     KMP_ARCH_X86) // __kmpc_atomic_fixed2_rd
20697cc577a4SJonathan Peyton 
20703041982dSJonathan Peyton ATOMIC_CRITICAL_READ(float10, rd, long double, +, 10r,
20713041982dSJonathan Peyton                      1) // __kmpc_atomic_float10_rd
20727cc577a4SJonathan Peyton #if KMP_HAVE_QUAD
20733041982dSJonathan Peyton ATOMIC_CRITICAL_READ(float16, rd, QUAD_LEGACY, +, 16r,
20743041982dSJonathan Peyton                      1) // __kmpc_atomic_float16_rd
20757cc577a4SJonathan Peyton #endif // KMP_HAVE_QUAD
20767cc577a4SJonathan Peyton 
20777cc577a4SJonathan Peyton // Fix for CQ220361 on Windows* OS
20787cc577a4SJonathan Peyton #if (KMP_OS_WINDOWS)
20793041982dSJonathan Peyton ATOMIC_CRITICAL_READ_WRK(cmplx4, rd, kmp_cmplx32, +, 8c,
20803041982dSJonathan Peyton                          1) // __kmpc_atomic_cmplx4_rd
20817cc577a4SJonathan Peyton #else
20823041982dSJonathan Peyton ATOMIC_CRITICAL_READ(cmplx4, rd, kmp_cmplx32, +, 8c,
20833041982dSJonathan Peyton                      1) // __kmpc_atomic_cmplx4_rd
2084e4b4f994SJonathan Peyton #endif // (KMP_OS_WINDOWS)
20853041982dSJonathan Peyton ATOMIC_CRITICAL_READ(cmplx8, rd, kmp_cmplx64, +, 16c,
20863041982dSJonathan Peyton                      1) // __kmpc_atomic_cmplx8_rd
20873041982dSJonathan Peyton ATOMIC_CRITICAL_READ(cmplx10, rd, kmp_cmplx80, +, 20c,
20883041982dSJonathan Peyton                      1) // __kmpc_atomic_cmplx10_rd
20897cc577a4SJonathan Peyton #if KMP_HAVE_QUAD
20903041982dSJonathan Peyton ATOMIC_CRITICAL_READ(cmplx16, rd, CPLX128_LEG, +, 32c,
20913041982dSJonathan Peyton                      1) // __kmpc_atomic_cmplx16_rd
20927cc577a4SJonathan Peyton #if (KMP_ARCH_X86)
20933041982dSJonathan Peyton ATOMIC_CRITICAL_READ(float16, a16_rd, Quad_a16_t, +, 16r,
20943041982dSJonathan Peyton                      1) // __kmpc_atomic_float16_a16_rd
20953041982dSJonathan Peyton ATOMIC_CRITICAL_READ(cmplx16, a16_rd, kmp_cmplx128_a16_t, +, 32c,
20963041982dSJonathan Peyton                      1) // __kmpc_atomic_cmplx16_a16_rd
2097e4b4f994SJonathan Peyton #endif // (KMP_ARCH_X86)
2098e4b4f994SJonathan Peyton #endif // KMP_HAVE_QUAD
20997cc577a4SJonathan Peyton 
21007cc577a4SJonathan Peyton // ------------------------------------------------------------------------
21017cc577a4SJonathan Peyton // Atomic WRITE routines
21027cc577a4SJonathan Peyton 
21037cc577a4SJonathan Peyton #define ATOMIC_XCHG_WR(TYPE_ID, OP_ID, TYPE, BITS, OP, GOMP_FLAG)              \
21047cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
21057cc577a4SJonathan Peyton   OP_GOMP_CRITICAL(OP, GOMP_FLAG)                                              \
21067cc577a4SJonathan Peyton   KMP_XCHG_FIXED##BITS(lhs, rhs);                                              \
21077cc577a4SJonathan Peyton   }
21087cc577a4SJonathan Peyton // ------------------------------------------------------------------------
21097cc577a4SJonathan Peyton #define ATOMIC_XCHG_FLOAT_WR(TYPE_ID, OP_ID, TYPE, BITS, OP, GOMP_FLAG)        \
21107cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
21117cc577a4SJonathan Peyton   OP_GOMP_CRITICAL(OP, GOMP_FLAG)                                              \
21127cc577a4SJonathan Peyton   KMP_XCHG_REAL##BITS(lhs, rhs);                                               \
21137cc577a4SJonathan Peyton   }
21147cc577a4SJonathan Peyton 
21157cc577a4SJonathan Peyton // ------------------------------------------------------------------------
21167cc577a4SJonathan Peyton // Operation on *lhs, rhs using "compare_and_store" routine
21177cc577a4SJonathan Peyton //     TYPE    - operands' type
21187cc577a4SJonathan Peyton //     BITS    - size in bits, used to distinguish low level calls
21197cc577a4SJonathan Peyton //     OP      - operator
21207cc577a4SJonathan Peyton // Note: temp_val introduced in order to force the compiler to read
21217cc577a4SJonathan Peyton //       *lhs only once (w/o it the compiler reads *lhs twice)
21227cc577a4SJonathan Peyton #define OP_CMPXCHG_WR(TYPE, BITS, OP)                                          \
21237cc577a4SJonathan Peyton   {                                                                            \
21247cc577a4SJonathan Peyton     TYPE KMP_ATOMIC_VOLATILE temp_val;                                         \
21257cc577a4SJonathan Peyton     TYPE old_value, new_value;                                                 \
21267cc577a4SJonathan Peyton     temp_val = *lhs;                                                           \
21277cc577a4SJonathan Peyton     old_value = temp_val;                                                      \
21287cc577a4SJonathan Peyton     new_value = rhs;                                                           \
21293041982dSJonathan Peyton     while (!KMP_COMPARE_AND_STORE_ACQ##BITS(                                   \
21303041982dSJonathan Peyton         (kmp_int##BITS *)lhs, *VOLATILE_CAST(kmp_int##BITS *) & old_value,     \
21313041982dSJonathan Peyton         *VOLATILE_CAST(kmp_int##BITS *) & new_value)) {                        \
21327cc577a4SJonathan Peyton       temp_val = *lhs;                                                         \
21337cc577a4SJonathan Peyton       old_value = temp_val;                                                    \
21347cc577a4SJonathan Peyton       new_value = rhs;                                                         \
21357cc577a4SJonathan Peyton     }                                                                          \
21367cc577a4SJonathan Peyton   }
21377cc577a4SJonathan Peyton 
21387cc577a4SJonathan Peyton // -------------------------------------------------------------------------
21397cc577a4SJonathan Peyton #define ATOMIC_CMPXCHG_WR(TYPE_ID, OP_ID, TYPE, BITS, OP, GOMP_FLAG)           \
21407cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
21417cc577a4SJonathan Peyton   OP_GOMP_CRITICAL(OP, GOMP_FLAG)                                              \
21427cc577a4SJonathan Peyton   OP_CMPXCHG_WR(TYPE, BITS, OP)                                                \
21437cc577a4SJonathan Peyton   }
21447cc577a4SJonathan Peyton 
21457cc577a4SJonathan Peyton // ------------------------------------------------------------------------
21463041982dSJonathan Peyton // Routines for Extended types: long double, _Quad, complex flavours (use
21473041982dSJonathan Peyton // critical section)
21487cc577a4SJonathan Peyton //     TYPE_ID, OP_ID, TYPE - detailed above
21497cc577a4SJonathan Peyton //     OP      - operator
21507cc577a4SJonathan Peyton //     LCK_ID  - lock identifier, used to possibly distinguish lock variable
21517cc577a4SJonathan Peyton #define ATOMIC_CRITICAL_WR(TYPE_ID, OP_ID, TYPE, OP, LCK_ID, GOMP_FLAG)        \
21527cc577a4SJonathan Peyton   ATOMIC_BEGIN(TYPE_ID, OP_ID, TYPE, void)                                     \
21537cc577a4SJonathan Peyton   OP_GOMP_CRITICAL(OP, GOMP_FLAG) /* send assignment */                        \
21547cc577a4SJonathan Peyton   OP_CRITICAL(OP, LCK_ID) /* send assignment */                                \
21557cc577a4SJonathan Peyton   }
21567cc577a4SJonathan Peyton // -------------------------------------------------------------------------
21577cc577a4SJonathan Peyton 
21583041982dSJonathan Peyton ATOMIC_XCHG_WR(fixed1, wr, kmp_int8, 8, =,
21593041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed1_wr
21603041982dSJonathan Peyton ATOMIC_XCHG_WR(fixed2, wr, kmp_int16, 16, =,
21613041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed2_wr
21623041982dSJonathan Peyton ATOMIC_XCHG_WR(fixed4, wr, kmp_int32, 32, =,
21633041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed4_wr
21647cc577a4SJonathan Peyton #if (KMP_ARCH_X86)
21653041982dSJonathan Peyton ATOMIC_CMPXCHG_WR(fixed8, wr, kmp_int64, 64, =,
21663041982dSJonathan Peyton                   KMP_ARCH_X86) // __kmpc_atomic_fixed8_wr
21677cc577a4SJonathan Peyton #else
21683041982dSJonathan Peyton ATOMIC_XCHG_WR(fixed8, wr, kmp_int64, 64, =,
21693041982dSJonathan Peyton                KMP_ARCH_X86) // __kmpc_atomic_fixed8_wr
2170e4b4f994SJonathan Peyton #endif // (KMP_ARCH_X86)
21717cc577a4SJonathan Peyton 
21723041982dSJonathan Peyton ATOMIC_XCHG_FLOAT_WR(float4, wr, kmp_real32, 32, =,
21733041982dSJonathan Peyton                      KMP_ARCH_X86) // __kmpc_atomic_float4_wr
21747cc577a4SJonathan Peyton #if (KMP_ARCH_X86)
21753041982dSJonathan Peyton ATOMIC_CMPXCHG_WR(float8, wr, kmp_real64, 64, =,
21763041982dSJonathan Peyton                   KMP_ARCH_X86) // __kmpc_atomic_float8_wr
21777cc577a4SJonathan Peyton #else
21783041982dSJonathan Peyton ATOMIC_XCHG_FLOAT_WR(float8, wr, kmp_real64, 64, =,
21793041982dSJonathan Peyton                      KMP_ARCH_X86) // __kmpc_atomic_float8_wr
2180e4b4f994SJonathan Peyton #endif // (KMP_ARCH_X86)
21817cc577a4SJonathan Peyton 
21823041982dSJonathan Peyton ATOMIC_CRITICAL_WR(float10, wr, long double, =, 10r,
21833041982dSJonathan Peyton                    1) // __kmpc_atomic_float10_wr
21847cc577a4SJonathan Peyton #if KMP_HAVE_QUAD
21853041982dSJonathan Peyton ATOMIC_CRITICAL_WR(float16, wr, QUAD_LEGACY, =, 16r,
21863041982dSJonathan Peyton                    1) // __kmpc_atomic_float16_wr
2187e4b4f994SJonathan Peyton #endif // KMP_HAVE_QUAD
21887cc577a4SJonathan Peyton ATOMIC_CRITICAL_WR(cmplx4, wr, kmp_cmplx32, =, 8c, 1) // __kmpc_atomic_cmplx4_wr
21893041982dSJonathan Peyton ATOMIC_CRITICAL_WR(cmplx8, wr, kmp_cmplx64, =, 16c,
21903041982dSJonathan Peyton                    1) // __kmpc_atomic_cmplx8_wr
21913041982dSJonathan Peyton ATOMIC_CRITICAL_WR(cmplx10, wr, kmp_cmplx80, =, 20c,
21923041982dSJonathan Peyton                    1) // __kmpc_atomic_cmplx10_wr
21937cc577a4SJonathan Peyton #if KMP_HAVE_QUAD
21943041982dSJonathan Peyton ATOMIC_CRITICAL_WR(cmplx16, wr, CPLX128_LEG, =, 32c,
21953041982dSJonathan Peyton                    1) // __kmpc_atomic_cmplx16_wr
21967cc577a4SJonathan Peyton #if (KMP_ARCH_X86)
21973041982dSJonathan Peyton ATOMIC_CRITICAL_WR(float16, a16_wr, Quad_a16_t, =, 16r,
21983041982dSJonathan Peyton                    1) // __kmpc_atomic_float16_a16_wr
21993041982dSJonathan Peyton ATOMIC_CRITICAL_WR(cmplx16, a16_wr, kmp_cmplx128_a16_t, =, 32c,
22003041982dSJonathan Peyton                    1) // __kmpc_atomic_cmplx16_a16_wr
2201e4b4f994SJonathan Peyton #endif // (KMP_ARCH_X86)
2202e4b4f994SJonathan Peyton #endif // KMP_HAVE_QUAD
22037cc577a4SJonathan Peyton 
22047cc577a4SJonathan Peyton // ------------------------------------------------------------------------
22057cc577a4SJonathan Peyton // Atomic CAPTURE routines
22067cc577a4SJonathan Peyton 
22077cc577a4SJonathan Peyton // Beginning of a definition (provides name, parameters, gebug trace)
22083041982dSJonathan Peyton //     TYPE_ID - operands type and size (fixed*, fixed*u for signed, unsigned
22093041982dSJonathan Peyton //     fixed)
22107cc577a4SJonathan Peyton //     OP_ID   - operation identifier (add, sub, mul, ...)
22117cc577a4SJonathan Peyton //     TYPE    - operands' type
22127cc577a4SJonathan Peyton #define ATOMIC_BEGIN_CPT(TYPE_ID, OP_ID, TYPE, RET_TYPE)                       \
22133041982dSJonathan Peyton   RET_TYPE __kmpc_atomic_##TYPE_ID##_##OP_ID(ident_t *id_ref, int gtid,        \
22143041982dSJonathan Peyton                                              TYPE *lhs, TYPE rhs, int flag) {  \
22157cc577a4SJonathan Peyton     KMP_DEBUG_ASSERT(__kmp_init_serial);                                       \
22167cc577a4SJonathan Peyton     KA_TRACE(100, ("__kmpc_atomic_" #TYPE_ID "_" #OP_ID ": T#%d\n", gtid));
22177cc577a4SJonathan Peyton 
22187cc577a4SJonathan Peyton // -------------------------------------------------------------------------
22197cc577a4SJonathan Peyton // Operation on *lhs, rhs bound by critical section
22207cc577a4SJonathan Peyton //     OP     - operator (it's supposed to contain an assignment)
22217cc577a4SJonathan Peyton //     LCK_ID - lock identifier
22227cc577a4SJonathan Peyton // Note: don't check gtid as it should always be valid
22237cc577a4SJonathan Peyton // 1, 2-byte - expect valid parameter, other - check before this macro
22247cc577a4SJonathan Peyton #define OP_CRITICAL_CPT(OP, LCK_ID)                                            \
22257cc577a4SJonathan Peyton   __kmp_acquire_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
22267cc577a4SJonathan Peyton                                                                                \
22277cc577a4SJonathan Peyton   if (flag) {                                                                  \
22287cc577a4SJonathan Peyton     (*lhs) OP rhs;                                                             \
22297cc577a4SJonathan Peyton     new_value = (*lhs);                                                        \
22307cc577a4SJonathan Peyton   } else {                                                                     \
22317cc577a4SJonathan Peyton     new_value = (*lhs);                                                        \
22327cc577a4SJonathan Peyton     (*lhs) OP rhs;                                                             \
22337cc577a4SJonathan Peyton   }                                                                            \
22347cc577a4SJonathan Peyton                                                                                \
22357cc577a4SJonathan Peyton   __kmp_release_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
22367cc577a4SJonathan Peyton   return new_value;
22377cc577a4SJonathan Peyton 
223844a11c34SHansang Bae #define OP_UPDATE_CRITICAL_CPT(TYPE, OP, LCK_ID)                               \
223944a11c34SHansang Bae   __kmp_acquire_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
224044a11c34SHansang Bae                                                                                \
224144a11c34SHansang Bae   if (flag) {                                                                  \
224244a11c34SHansang Bae     (*lhs) = (TYPE)((*lhs)OP rhs);                                             \
224344a11c34SHansang Bae     new_value = (*lhs);                                                        \
224444a11c34SHansang Bae   } else {                                                                     \
224544a11c34SHansang Bae     new_value = (*lhs);                                                        \
224644a11c34SHansang Bae     (*lhs) = (TYPE)((*lhs)OP rhs);                                             \
224744a11c34SHansang Bae   }                                                                            \
224844a11c34SHansang Bae                                                                                \
224944a11c34SHansang Bae   __kmp_release_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
225044a11c34SHansang Bae   return new_value;
225144a11c34SHansang Bae 
22527cc577a4SJonathan Peyton // ------------------------------------------------------------------------
22537cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
225444a11c34SHansang Bae #define OP_GOMP_CRITICAL_CPT(TYPE, OP, FLAG)                                   \
22557cc577a4SJonathan Peyton   if ((FLAG) && (__kmp_atomic_mode == 2)) {                                    \
22567cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
225744a11c34SHansang Bae     OP_UPDATE_CRITICAL_CPT(TYPE, OP, 0);                                       \
22587cc577a4SJonathan Peyton   }
22597cc577a4SJonathan Peyton #else
226044a11c34SHansang Bae #define OP_GOMP_CRITICAL_CPT(TYPE, OP, FLAG)
22617cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
22627cc577a4SJonathan Peyton 
22637cc577a4SJonathan Peyton // ------------------------------------------------------------------------
22647cc577a4SJonathan Peyton // Operation on *lhs, rhs using "compare_and_store" routine
22657cc577a4SJonathan Peyton //     TYPE    - operands' type
22667cc577a4SJonathan Peyton //     BITS    - size in bits, used to distinguish low level calls
22677cc577a4SJonathan Peyton //     OP      - operator
22687cc577a4SJonathan Peyton // Note: temp_val introduced in order to force the compiler to read
22697cc577a4SJonathan Peyton //       *lhs only once (w/o it the compiler reads *lhs twice)
22707cc577a4SJonathan Peyton #define OP_CMPXCHG_CPT(TYPE, BITS, OP)                                         \
22717cc577a4SJonathan Peyton   {                                                                            \
22727cc577a4SJonathan Peyton     TYPE KMP_ATOMIC_VOLATILE temp_val;                                         \
22737cc577a4SJonathan Peyton     TYPE old_value, new_value;                                                 \
22747cc577a4SJonathan Peyton     temp_val = *lhs;                                                           \
22757cc577a4SJonathan Peyton     old_value = temp_val;                                                      \
227644a11c34SHansang Bae     new_value = (TYPE)(old_value OP rhs);                                      \
22773041982dSJonathan Peyton     while (!KMP_COMPARE_AND_STORE_ACQ##BITS(                                   \
22783041982dSJonathan Peyton         (kmp_int##BITS *)lhs, *VOLATILE_CAST(kmp_int##BITS *) & old_value,     \
22793041982dSJonathan Peyton         *VOLATILE_CAST(kmp_int##BITS *) & new_value)) {                        \
22807cc577a4SJonathan Peyton       temp_val = *lhs;                                                         \
22817cc577a4SJonathan Peyton       old_value = temp_val;                                                    \
228244a11c34SHansang Bae       new_value = (TYPE)(old_value OP rhs);                                    \
22837cc577a4SJonathan Peyton     }                                                                          \
22847cc577a4SJonathan Peyton     if (flag) {                                                                \
22857cc577a4SJonathan Peyton       return new_value;                                                        \
22867cc577a4SJonathan Peyton     } else                                                                     \
22877cc577a4SJonathan Peyton       return old_value;                                                        \
22887cc577a4SJonathan Peyton   }
22897cc577a4SJonathan Peyton 
22907cc577a4SJonathan Peyton // -------------------------------------------------------------------------
22917cc577a4SJonathan Peyton #define ATOMIC_CMPXCHG_CPT(TYPE_ID, OP_ID, TYPE, BITS, OP, GOMP_FLAG)          \
22927cc577a4SJonathan Peyton   ATOMIC_BEGIN_CPT(TYPE_ID, OP_ID, TYPE, TYPE)                                 \
22937cc577a4SJonathan Peyton   TYPE new_value;                                                              \
2294b3d84790SMartin Storsjö   (void)new_value;                                                             \
229544a11c34SHansang Bae   OP_GOMP_CRITICAL_CPT(TYPE, OP, GOMP_FLAG)                                    \
22967cc577a4SJonathan Peyton   OP_CMPXCHG_CPT(TYPE, BITS, OP)                                               \
22977cc577a4SJonathan Peyton   }
22987cc577a4SJonathan Peyton 
22997cc577a4SJonathan Peyton // -------------------------------------------------------------------------
23007cc577a4SJonathan Peyton #define ATOMIC_FIXED_ADD_CPT(TYPE_ID, OP_ID, TYPE, BITS, OP, GOMP_FLAG)        \
23017cc577a4SJonathan Peyton   ATOMIC_BEGIN_CPT(TYPE_ID, OP_ID, TYPE, TYPE)                                 \
23027cc577a4SJonathan Peyton   TYPE old_value, new_value;                                                   \
2303b3d84790SMartin Storsjö   (void)new_value;                                                             \
230444a11c34SHansang Bae   OP_GOMP_CRITICAL_CPT(TYPE, OP, GOMP_FLAG)                                    \
23057cc577a4SJonathan Peyton   /* OP used as a sign for subtraction: (lhs-rhs) --> (lhs+-rhs) */            \
23067cc577a4SJonathan Peyton   old_value = KMP_TEST_THEN_ADD##BITS(lhs, OP rhs);                            \
23077cc577a4SJonathan Peyton   if (flag) {                                                                  \
23087cc577a4SJonathan Peyton     return old_value OP rhs;                                                   \
23097cc577a4SJonathan Peyton   } else                                                                       \
23107cc577a4SJonathan Peyton     return old_value;                                                          \
23117cc577a4SJonathan Peyton   }
23127cc577a4SJonathan Peyton // -------------------------------------------------------------------------
23137cc577a4SJonathan Peyton 
23143041982dSJonathan Peyton ATOMIC_FIXED_ADD_CPT(fixed4, add_cpt, kmp_int32, 32, +,
23153041982dSJonathan Peyton                      0) // __kmpc_atomic_fixed4_add_cpt
23163041982dSJonathan Peyton ATOMIC_FIXED_ADD_CPT(fixed4, sub_cpt, kmp_int32, 32, -,
23173041982dSJonathan Peyton                      0) // __kmpc_atomic_fixed4_sub_cpt
23183041982dSJonathan Peyton ATOMIC_FIXED_ADD_CPT(fixed8, add_cpt, kmp_int64, 64, +,
23193041982dSJonathan Peyton                      KMP_ARCH_X86) // __kmpc_atomic_fixed8_add_cpt
23203041982dSJonathan Peyton ATOMIC_FIXED_ADD_CPT(fixed8, sub_cpt, kmp_int64, 64, -,
23213041982dSJonathan Peyton                      KMP_ARCH_X86) // __kmpc_atomic_fixed8_sub_cpt
23227cc577a4SJonathan Peyton 
23233041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(float4, add_cpt, kmp_real32, 32, +,
23243041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float4_add_cpt
23253041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(float4, sub_cpt, kmp_real32, 32, -,
23263041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float4_sub_cpt
23273041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(float8, add_cpt, kmp_real64, 64, +,
23283041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float8_add_cpt
23293041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(float8, sub_cpt, kmp_real64, 64, -,
23303041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float8_sub_cpt
23317cc577a4SJonathan Peyton 
23327cc577a4SJonathan Peyton // ------------------------------------------------------------------------
23337cc577a4SJonathan Peyton // Entries definition for integer operands
23347cc577a4SJonathan Peyton //     TYPE_ID - operands type and size (fixed4, float4)
23357cc577a4SJonathan Peyton //     OP_ID   - operation identifier (add, sub, mul, ...)
23367cc577a4SJonathan Peyton //     TYPE    - operand type
23377cc577a4SJonathan Peyton //     BITS    - size in bits, used to distinguish low level calls
23387cc577a4SJonathan Peyton //     OP      - operator (used in critical section)
23397cc577a4SJonathan Peyton //               TYPE_ID,OP_ID,  TYPE,   BITS,OP,GOMP_FLAG
23407cc577a4SJonathan Peyton // ------------------------------------------------------------------------
23417cc577a4SJonathan Peyton // Routines for ATOMIC integer operands, other operators
23427cc577a4SJonathan Peyton // ------------------------------------------------------------------------
23437cc577a4SJonathan Peyton //              TYPE_ID,OP_ID, TYPE,          OP,  GOMP_FLAG
23443041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed1, add_cpt, kmp_int8, 8, +,
23453041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1_add_cpt
23463041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed1, andb_cpt, kmp_int8, 8, &,
23473041982dSJonathan Peyton                    0) // __kmpc_atomic_fixed1_andb_cpt
23483041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed1, div_cpt, kmp_int8, 8, /,
23493041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1_div_cpt
23503041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed1u, div_cpt, kmp_uint8, 8, /,
23513041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1u_div_cpt
23523041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed1, mul_cpt, kmp_int8, 8, *,
23533041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1_mul_cpt
23543041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed1, orb_cpt, kmp_int8, 8, |,
23553041982dSJonathan Peyton                    0) // __kmpc_atomic_fixed1_orb_cpt
23563041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed1, shl_cpt, kmp_int8, 8, <<,
23573041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1_shl_cpt
23583041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed1, shr_cpt, kmp_int8, 8, >>,
23593041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1_shr_cpt
23603041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed1u, shr_cpt, kmp_uint8, 8, >>,
23613041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1u_shr_cpt
23623041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed1, sub_cpt, kmp_int8, 8, -,
23633041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1_sub_cpt
23643041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed1, xor_cpt, kmp_int8, 8, ^,
23653041982dSJonathan Peyton                    0) // __kmpc_atomic_fixed1_xor_cpt
23663041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed2, add_cpt, kmp_int16, 16, +,
23673041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2_add_cpt
23683041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed2, andb_cpt, kmp_int16, 16, &,
23693041982dSJonathan Peyton                    0) // __kmpc_atomic_fixed2_andb_cpt
23703041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed2, div_cpt, kmp_int16, 16, /,
23713041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2_div_cpt
23723041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed2u, div_cpt, kmp_uint16, 16, /,
23733041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2u_div_cpt
23743041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed2, mul_cpt, kmp_int16, 16, *,
23753041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2_mul_cpt
23763041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed2, orb_cpt, kmp_int16, 16, |,
23773041982dSJonathan Peyton                    0) // __kmpc_atomic_fixed2_orb_cpt
23783041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed2, shl_cpt, kmp_int16, 16, <<,
23793041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2_shl_cpt
23803041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed2, shr_cpt, kmp_int16, 16, >>,
23813041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2_shr_cpt
23823041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed2u, shr_cpt, kmp_uint16, 16, >>,
23833041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2u_shr_cpt
23843041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed2, sub_cpt, kmp_int16, 16, -,
23853041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2_sub_cpt
23863041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed2, xor_cpt, kmp_int16, 16, ^,
23873041982dSJonathan Peyton                    0) // __kmpc_atomic_fixed2_xor_cpt
23883041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed4, andb_cpt, kmp_int32, 32, &,
23893041982dSJonathan Peyton                    0) // __kmpc_atomic_fixed4_andb_cpt
23903041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed4, div_cpt, kmp_int32, 32, /,
23913041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed4_div_cpt
23923041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed4u, div_cpt, kmp_uint32, 32, /,
23933041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed4u_div_cpt
23943041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed4, mul_cpt, kmp_int32, 32, *,
23953041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed4_mul_cpt
23963041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed4, orb_cpt, kmp_int32, 32, |,
23973041982dSJonathan Peyton                    0) // __kmpc_atomic_fixed4_orb_cpt
23983041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed4, shl_cpt, kmp_int32, 32, <<,
23993041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed4_shl_cpt
24003041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed4, shr_cpt, kmp_int32, 32, >>,
24013041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed4_shr_cpt
24023041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed4u, shr_cpt, kmp_uint32, 32, >>,
24033041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed4u_shr_cpt
24043041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed4, xor_cpt, kmp_int32, 32, ^,
24053041982dSJonathan Peyton                    0) // __kmpc_atomic_fixed4_xor_cpt
24063041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed8, andb_cpt, kmp_int64, 64, &,
24073041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8_andb_cpt
24083041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed8, div_cpt, kmp_int64, 64, /,
24093041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8_div_cpt
24103041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed8u, div_cpt, kmp_uint64, 64, /,
24113041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8u_div_cpt
24123041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed8, mul_cpt, kmp_int64, 64, *,
24133041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8_mul_cpt
24143041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed8, orb_cpt, kmp_int64, 64, |,
24153041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8_orb_cpt
24163041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed8, shl_cpt, kmp_int64, 64, <<,
24173041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8_shl_cpt
24183041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed8, shr_cpt, kmp_int64, 64, >>,
24193041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8_shr_cpt
24203041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed8u, shr_cpt, kmp_uint64, 64, >>,
24213041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8u_shr_cpt
24223041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed8, xor_cpt, kmp_int64, 64, ^,
24233041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8_xor_cpt
24243041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(float4, div_cpt, kmp_real32, 32, /,
24253041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float4_div_cpt
24263041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(float4, mul_cpt, kmp_real32, 32, *,
24273041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float4_mul_cpt
24283041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(float8, div_cpt, kmp_real64, 64, /,
24293041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float8_div_cpt
24303041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(float8, mul_cpt, kmp_real64, 64, *,
24313041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float8_mul_cpt
24327cc577a4SJonathan Peyton //              TYPE_ID,OP_ID, TYPE,          OP,  GOMP_FLAG
24337cc577a4SJonathan Peyton 
24347cc577a4SJonathan Peyton // CAPTURE routines for mixed types RHS=float16
24357cc577a4SJonathan Peyton #if KMP_HAVE_QUAD
24367cc577a4SJonathan Peyton 
24377cc577a4SJonathan Peyton // Beginning of a definition (provides name, parameters, gebug trace)
24383041982dSJonathan Peyton //     TYPE_ID - operands type and size (fixed*, fixed*u for signed, unsigned
24393041982dSJonathan Peyton //     fixed)
24407cc577a4SJonathan Peyton //     OP_ID   - operation identifier (add, sub, mul, ...)
24417cc577a4SJonathan Peyton //     TYPE    - operands' type
24427cc577a4SJonathan Peyton #define ATOMIC_BEGIN_CPT_MIX(TYPE_ID, OP_ID, TYPE, RTYPE_ID, RTYPE)            \
24433041982dSJonathan Peyton   TYPE __kmpc_atomic_##TYPE_ID##_##OP_ID##_##RTYPE_ID(                         \
24443041982dSJonathan Peyton       ident_t *id_ref, int gtid, TYPE *lhs, RTYPE rhs, int flag) {             \
24457cc577a4SJonathan Peyton     KMP_DEBUG_ASSERT(__kmp_init_serial);                                       \
24463041982dSJonathan Peyton     KA_TRACE(100,                                                              \
24473041982dSJonathan Peyton              ("__kmpc_atomic_" #TYPE_ID "_" #OP_ID "_" #RTYPE_ID ": T#%d\n",   \
24483041982dSJonathan Peyton               gtid));
24497cc577a4SJonathan Peyton 
24507cc577a4SJonathan Peyton // -------------------------------------------------------------------------
24513041982dSJonathan Peyton #define ATOMIC_CMPXCHG_CPT_MIX(TYPE_ID, TYPE, OP_ID, BITS, OP, RTYPE_ID,       \
24523041982dSJonathan Peyton                                RTYPE, LCK_ID, MASK, GOMP_FLAG)                 \
24537cc577a4SJonathan Peyton   ATOMIC_BEGIN_CPT_MIX(TYPE_ID, OP_ID, TYPE, RTYPE_ID, RTYPE)                  \
24547cc577a4SJonathan Peyton   TYPE new_value;                                                              \
2455*1234011bSJonathan Peyton   (void)new_value;                                                             \
245644a11c34SHansang Bae   OP_GOMP_CRITICAL_CPT(TYPE, OP, GOMP_FLAG)                                    \
24577cc577a4SJonathan Peyton   OP_CMPXCHG_CPT(TYPE, BITS, OP)                                               \
24587cc577a4SJonathan Peyton   }
24597cc577a4SJonathan Peyton 
24607cc577a4SJonathan Peyton // -------------------------------------------------------------------------
24613041982dSJonathan Peyton #define ATOMIC_CRITICAL_CPT_MIX(TYPE_ID, TYPE, OP_ID, OP, RTYPE_ID, RTYPE,     \
24623041982dSJonathan Peyton                                 LCK_ID, GOMP_FLAG)                             \
24637cc577a4SJonathan Peyton   ATOMIC_BEGIN_CPT_MIX(TYPE_ID, OP_ID, TYPE, RTYPE_ID, RTYPE)                  \
24647cc577a4SJonathan Peyton   TYPE new_value;                                                              \
2465*1234011bSJonathan Peyton   (void)new_value;                                                             \
246644a11c34SHansang Bae   OP_GOMP_CRITICAL_CPT(TYPE, OP, GOMP_FLAG) /* send assignment */              \
246744a11c34SHansang Bae   OP_UPDATE_CRITICAL_CPT(TYPE, OP, LCK_ID) /* send assignment */               \
24687cc577a4SJonathan Peyton   }
24697cc577a4SJonathan Peyton 
24703041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed1, char, add_cpt, 8, +, fp, _Quad, 1i, 0,
24713041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed1_add_cpt_fp
24723041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed1u, uchar, add_cpt, 8, +, fp, _Quad, 1i, 0,
24733041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed1u_add_cpt_fp
24743041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed1, char, sub_cpt, 8, -, fp, _Quad, 1i, 0,
24753041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed1_sub_cpt_fp
24763041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed1u, uchar, sub_cpt, 8, -, fp, _Quad, 1i, 0,
24773041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed1u_sub_cpt_fp
24783041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed1, char, mul_cpt, 8, *, fp, _Quad, 1i, 0,
24793041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed1_mul_cpt_fp
24803041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed1u, uchar, mul_cpt, 8, *, fp, _Quad, 1i, 0,
24813041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed1u_mul_cpt_fp
24823041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed1, char, div_cpt, 8, /, fp, _Quad, 1i, 0,
24833041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed1_div_cpt_fp
24843041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed1u, uchar, div_cpt, 8, /, fp, _Quad, 1i, 0,
24853041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed1u_div_cpt_fp
24867cc577a4SJonathan Peyton 
24873041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed2, short, add_cpt, 16, +, fp, _Quad, 2i, 1,
24883041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed2_add_cpt_fp
24893041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed2u, ushort, add_cpt, 16, +, fp, _Quad, 2i, 1,
24903041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed2u_add_cpt_fp
24913041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed2, short, sub_cpt, 16, -, fp, _Quad, 2i, 1,
24923041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed2_sub_cpt_fp
24933041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed2u, ushort, sub_cpt, 16, -, fp, _Quad, 2i, 1,
24943041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed2u_sub_cpt_fp
24953041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed2, short, mul_cpt, 16, *, fp, _Quad, 2i, 1,
24963041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed2_mul_cpt_fp
24973041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed2u, ushort, mul_cpt, 16, *, fp, _Quad, 2i, 1,
24983041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed2u_mul_cpt_fp
24993041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed2, short, div_cpt, 16, /, fp, _Quad, 2i, 1,
25003041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed2_div_cpt_fp
25013041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed2u, ushort, div_cpt, 16, /, fp, _Quad, 2i, 1,
25023041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed2u_div_cpt_fp
25037cc577a4SJonathan Peyton 
25043041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed4, kmp_int32, add_cpt, 32, +, fp, _Quad, 4i, 3,
25053041982dSJonathan Peyton                        0) // __kmpc_atomic_fixed4_add_cpt_fp
25063041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed4u, kmp_uint32, add_cpt, 32, +, fp, _Quad, 4i, 3,
25073041982dSJonathan Peyton                        0) // __kmpc_atomic_fixed4u_add_cpt_fp
25083041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed4, kmp_int32, sub_cpt, 32, -, fp, _Quad, 4i, 3,
25093041982dSJonathan Peyton                        0) // __kmpc_atomic_fixed4_sub_cpt_fp
25103041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed4u, kmp_uint32, sub_cpt, 32, -, fp, _Quad, 4i, 3,
25113041982dSJonathan Peyton                        0) // __kmpc_atomic_fixed4u_sub_cpt_fp
25123041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed4, kmp_int32, mul_cpt, 32, *, fp, _Quad, 4i, 3,
25133041982dSJonathan Peyton                        0) // __kmpc_atomic_fixed4_mul_cpt_fp
25143041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed4u, kmp_uint32, mul_cpt, 32, *, fp, _Quad, 4i, 3,
25153041982dSJonathan Peyton                        0) // __kmpc_atomic_fixed4u_mul_cpt_fp
25163041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed4, kmp_int32, div_cpt, 32, /, fp, _Quad, 4i, 3,
25173041982dSJonathan Peyton                        0) // __kmpc_atomic_fixed4_div_cpt_fp
25183041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed4u, kmp_uint32, div_cpt, 32, /, fp, _Quad, 4i, 3,
25193041982dSJonathan Peyton                        0) // __kmpc_atomic_fixed4u_div_cpt_fp
25207cc577a4SJonathan Peyton 
25213041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed8, kmp_int64, add_cpt, 64, +, fp, _Quad, 8i, 7,
25223041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed8_add_cpt_fp
25233041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed8u, kmp_uint64, add_cpt, 64, +, fp, _Quad, 8i, 7,
25243041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed8u_add_cpt_fp
25253041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed8, kmp_int64, sub_cpt, 64, -, fp, _Quad, 8i, 7,
25263041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed8_sub_cpt_fp
25273041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed8u, kmp_uint64, sub_cpt, 64, -, fp, _Quad, 8i, 7,
25283041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed8u_sub_cpt_fp
25293041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed8, kmp_int64, mul_cpt, 64, *, fp, _Quad, 8i, 7,
25303041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed8_mul_cpt_fp
25313041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed8u, kmp_uint64, mul_cpt, 64, *, fp, _Quad, 8i, 7,
25323041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed8u_mul_cpt_fp
25333041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed8, kmp_int64, div_cpt, 64, /, fp, _Quad, 8i, 7,
25343041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed8_div_cpt_fp
25353041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(fixed8u, kmp_uint64, div_cpt, 64, /, fp, _Quad, 8i, 7,
25363041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed8u_div_cpt_fp
25377cc577a4SJonathan Peyton 
25383041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(float4, kmp_real32, add_cpt, 32, +, fp, _Quad, 4r, 3,
25393041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_float4_add_cpt_fp
25403041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(float4, kmp_real32, sub_cpt, 32, -, fp, _Quad, 4r, 3,
25413041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_float4_sub_cpt_fp
25423041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(float4, kmp_real32, mul_cpt, 32, *, fp, _Quad, 4r, 3,
25433041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_float4_mul_cpt_fp
25443041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(float4, kmp_real32, div_cpt, 32, /, fp, _Quad, 4r, 3,
25453041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_float4_div_cpt_fp
25467cc577a4SJonathan Peyton 
25473041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(float8, kmp_real64, add_cpt, 64, +, fp, _Quad, 8r, 7,
25483041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_float8_add_cpt_fp
25493041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(float8, kmp_real64, sub_cpt, 64, -, fp, _Quad, 8r, 7,
25503041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_float8_sub_cpt_fp
25513041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(float8, kmp_real64, mul_cpt, 64, *, fp, _Quad, 8r, 7,
25523041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_float8_mul_cpt_fp
25533041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_MIX(float8, kmp_real64, div_cpt, 64, /, fp, _Quad, 8r, 7,
25543041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_float8_div_cpt_fp
25557cc577a4SJonathan Peyton 
25563041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_MIX(float10, long double, add_cpt, +, fp, _Quad, 10r,
25573041982dSJonathan Peyton                         1) // __kmpc_atomic_float10_add_cpt_fp
25583041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_MIX(float10, long double, sub_cpt, -, fp, _Quad, 10r,
25593041982dSJonathan Peyton                         1) // __kmpc_atomic_float10_sub_cpt_fp
25603041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_MIX(float10, long double, mul_cpt, *, fp, _Quad, 10r,
25613041982dSJonathan Peyton                         1) // __kmpc_atomic_float10_mul_cpt_fp
25623041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_MIX(float10, long double, div_cpt, /, fp, _Quad, 10r,
25633041982dSJonathan Peyton                         1) // __kmpc_atomic_float10_div_cpt_fp
25647cc577a4SJonathan Peyton 
25657cc577a4SJonathan Peyton #endif // KMP_HAVE_QUAD
25667cc577a4SJonathan Peyton 
25677cc577a4SJonathan Peyton // ------------------------------------------------------------------------
25687cc577a4SJonathan Peyton // Routines for C/C++ Reduction operators && and ||
25697cc577a4SJonathan Peyton 
25707cc577a4SJonathan Peyton // -------------------------------------------------------------------------
25717cc577a4SJonathan Peyton // Operation on *lhs, rhs bound by critical section
25727cc577a4SJonathan Peyton //     OP     - operator (it's supposed to contain an assignment)
25737cc577a4SJonathan Peyton //     LCK_ID - lock identifier
25747cc577a4SJonathan Peyton // Note: don't check gtid as it should always be valid
25757cc577a4SJonathan Peyton // 1, 2-byte - expect valid parameter, other - check before this macro
25767cc577a4SJonathan Peyton #define OP_CRITICAL_L_CPT(OP, LCK_ID)                                          \
25777cc577a4SJonathan Peyton   __kmp_acquire_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
25787cc577a4SJonathan Peyton                                                                                \
25797cc577a4SJonathan Peyton   if (flag) {                                                                  \
25807cc577a4SJonathan Peyton     new_value OP rhs;                                                          \
25812d911f7cSHansang Bae     (*lhs) = new_value;                                                        \
25822d911f7cSHansang Bae   } else {                                                                     \
25837cc577a4SJonathan Peyton     new_value = (*lhs);                                                        \
25842d911f7cSHansang Bae     (*lhs) OP rhs;                                                             \
25852d911f7cSHansang Bae   }                                                                            \
25867cc577a4SJonathan Peyton                                                                                \
25877cc577a4SJonathan Peyton   __kmp_release_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);
25887cc577a4SJonathan Peyton 
25897cc577a4SJonathan Peyton // ------------------------------------------------------------------------
25907cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
25917cc577a4SJonathan Peyton #define OP_GOMP_CRITICAL_L_CPT(OP, FLAG)                                       \
25927cc577a4SJonathan Peyton   if ((FLAG) && (__kmp_atomic_mode == 2)) {                                    \
25937cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
25947cc577a4SJonathan Peyton     OP_CRITICAL_L_CPT(OP, 0);                                                  \
25957cc577a4SJonathan Peyton     return new_value;                                                          \
25967cc577a4SJonathan Peyton   }
25977cc577a4SJonathan Peyton #else
25987cc577a4SJonathan Peyton #define OP_GOMP_CRITICAL_L_CPT(OP, FLAG)
25997cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
26007cc577a4SJonathan Peyton 
26017cc577a4SJonathan Peyton // ------------------------------------------------------------------------
26027cc577a4SJonathan Peyton // Need separate macros for &&, || because there is no combined assignment
26037cc577a4SJonathan Peyton #define ATOMIC_CMPX_L_CPT(TYPE_ID, OP_ID, TYPE, BITS, OP, GOMP_FLAG)           \
26047cc577a4SJonathan Peyton   ATOMIC_BEGIN_CPT(TYPE_ID, OP_ID, TYPE, TYPE)                                 \
26057cc577a4SJonathan Peyton   TYPE new_value;                                                              \
2606b3d84790SMartin Storsjö   (void)new_value;                                                             \
26077cc577a4SJonathan Peyton   OP_GOMP_CRITICAL_L_CPT(= *lhs OP, GOMP_FLAG)                                 \
26087cc577a4SJonathan Peyton   OP_CMPXCHG_CPT(TYPE, BITS, OP)                                               \
26097cc577a4SJonathan Peyton   }
26107cc577a4SJonathan Peyton 
26113041982dSJonathan Peyton ATOMIC_CMPX_L_CPT(fixed1, andl_cpt, char, 8, &&,
26123041982dSJonathan Peyton                   KMP_ARCH_X86) // __kmpc_atomic_fixed1_andl_cpt
26133041982dSJonathan Peyton ATOMIC_CMPX_L_CPT(fixed1, orl_cpt, char, 8, ||,
26143041982dSJonathan Peyton                   KMP_ARCH_X86) // __kmpc_atomic_fixed1_orl_cpt
26153041982dSJonathan Peyton ATOMIC_CMPX_L_CPT(fixed2, andl_cpt, short, 16, &&,
26163041982dSJonathan Peyton                   KMP_ARCH_X86) // __kmpc_atomic_fixed2_andl_cpt
26173041982dSJonathan Peyton ATOMIC_CMPX_L_CPT(fixed2, orl_cpt, short, 16, ||,
26183041982dSJonathan Peyton                   KMP_ARCH_X86) // __kmpc_atomic_fixed2_orl_cpt
26193041982dSJonathan Peyton ATOMIC_CMPX_L_CPT(fixed4, andl_cpt, kmp_int32, 32, &&,
26203041982dSJonathan Peyton                   0) // __kmpc_atomic_fixed4_andl_cpt
26213041982dSJonathan Peyton ATOMIC_CMPX_L_CPT(fixed4, orl_cpt, kmp_int32, 32, ||,
26223041982dSJonathan Peyton                   0) // __kmpc_atomic_fixed4_orl_cpt
26233041982dSJonathan Peyton ATOMIC_CMPX_L_CPT(fixed8, andl_cpt, kmp_int64, 64, &&,
26243041982dSJonathan Peyton                   KMP_ARCH_X86) // __kmpc_atomic_fixed8_andl_cpt
26253041982dSJonathan Peyton ATOMIC_CMPX_L_CPT(fixed8, orl_cpt, kmp_int64, 64, ||,
26263041982dSJonathan Peyton                   KMP_ARCH_X86) // __kmpc_atomic_fixed8_orl_cpt
26277cc577a4SJonathan Peyton 
26287cc577a4SJonathan Peyton // -------------------------------------------------------------------------
26297cc577a4SJonathan Peyton // Routines for Fortran operators that matched no one in C:
26307cc577a4SJonathan Peyton // MAX, MIN, .EQV., .NEQV.
26317cc577a4SJonathan Peyton // Operators .AND., .OR. are covered by __kmpc_atomic_*_{andl,orl}_cpt
26327cc577a4SJonathan Peyton // Intrinsics IAND, IOR, IEOR are covered by __kmpc_atomic_*_{andb,orb,xor}_cpt
26337cc577a4SJonathan Peyton 
26347cc577a4SJonathan Peyton // -------------------------------------------------------------------------
26357cc577a4SJonathan Peyton // MIN and MAX need separate macros
26367cc577a4SJonathan Peyton // OP - operator to check if we need any actions?
26377cc577a4SJonathan Peyton #define MIN_MAX_CRITSECT_CPT(OP, LCK_ID)                                       \
26387cc577a4SJonathan Peyton   __kmp_acquire_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
26397cc577a4SJonathan Peyton                                                                                \
26407cc577a4SJonathan Peyton   if (*lhs OP rhs) { /* still need actions? */                                 \
26417cc577a4SJonathan Peyton     old_value = *lhs;                                                          \
26427cc577a4SJonathan Peyton     *lhs = rhs;                                                                \
26437cc577a4SJonathan Peyton     if (flag)                                                                  \
26447cc577a4SJonathan Peyton       new_value = rhs;                                                         \
26457cc577a4SJonathan Peyton     else                                                                       \
26467cc577a4SJonathan Peyton       new_value = old_value;                                                   \
26471ca74617SJonathan Peyton   } else {                                                                     \
26481ca74617SJonathan Peyton     new_value = *lhs;                                                          \
26497cc577a4SJonathan Peyton   }                                                                            \
26507cc577a4SJonathan Peyton   __kmp_release_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
26513041982dSJonathan Peyton   return new_value;
26527cc577a4SJonathan Peyton 
26537cc577a4SJonathan Peyton // -------------------------------------------------------------------------
26547cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
26557cc577a4SJonathan Peyton #define GOMP_MIN_MAX_CRITSECT_CPT(OP, FLAG)                                    \
26567cc577a4SJonathan Peyton   if ((FLAG) && (__kmp_atomic_mode == 2)) {                                    \
26577cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
26587cc577a4SJonathan Peyton     MIN_MAX_CRITSECT_CPT(OP, 0);                                               \
26597cc577a4SJonathan Peyton   }
26607cc577a4SJonathan Peyton #else
26617cc577a4SJonathan Peyton #define GOMP_MIN_MAX_CRITSECT_CPT(OP, FLAG)
26627cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
26637cc577a4SJonathan Peyton 
26647cc577a4SJonathan Peyton // -------------------------------------------------------------------------
26657cc577a4SJonathan Peyton #define MIN_MAX_CMPXCHG_CPT(TYPE, BITS, OP)                                    \
26667cc577a4SJonathan Peyton   {                                                                            \
26677cc577a4SJonathan Peyton     TYPE KMP_ATOMIC_VOLATILE temp_val;                                         \
26687cc577a4SJonathan Peyton     /*TYPE old_value; */                                                       \
26697cc577a4SJonathan Peyton     temp_val = *lhs;                                                           \
26707cc577a4SJonathan Peyton     old_value = temp_val;                                                      \
26717cc577a4SJonathan Peyton     while (old_value OP rhs && /* still need actions? */                       \
26723041982dSJonathan Peyton            !KMP_COMPARE_AND_STORE_ACQ##BITS(                                   \
26733041982dSJonathan Peyton                (kmp_int##BITS *)lhs,                                           \
26747cc577a4SJonathan Peyton                *VOLATILE_CAST(kmp_int##BITS *) & old_value,                    \
26753041982dSJonathan Peyton                *VOLATILE_CAST(kmp_int##BITS *) & rhs)) {                       \
26767cc577a4SJonathan Peyton       temp_val = *lhs;                                                         \
26777cc577a4SJonathan Peyton       old_value = temp_val;                                                    \
26787cc577a4SJonathan Peyton     }                                                                          \
26797cc577a4SJonathan Peyton     if (flag)                                                                  \
26807cc577a4SJonathan Peyton       return rhs;                                                              \
26817cc577a4SJonathan Peyton     else                                                                       \
26827cc577a4SJonathan Peyton       return old_value;                                                        \
26837cc577a4SJonathan Peyton   }
26847cc577a4SJonathan Peyton 
26857cc577a4SJonathan Peyton // -------------------------------------------------------------------------
26867cc577a4SJonathan Peyton // 1-byte, 2-byte operands - use critical section
26877cc577a4SJonathan Peyton #define MIN_MAX_CRITICAL_CPT(TYPE_ID, OP_ID, TYPE, OP, LCK_ID, GOMP_FLAG)      \
26887cc577a4SJonathan Peyton   ATOMIC_BEGIN_CPT(TYPE_ID, OP_ID, TYPE, TYPE)                                 \
26897cc577a4SJonathan Peyton   TYPE new_value, old_value;                                                   \
26907cc577a4SJonathan Peyton   if (*lhs OP rhs) { /* need actions? */                                       \
26917cc577a4SJonathan Peyton     GOMP_MIN_MAX_CRITSECT_CPT(OP, GOMP_FLAG)                                   \
26927cc577a4SJonathan Peyton     MIN_MAX_CRITSECT_CPT(OP, LCK_ID)                                           \
26937cc577a4SJonathan Peyton   }                                                                            \
26947cc577a4SJonathan Peyton   return *lhs;                                                                 \
26957cc577a4SJonathan Peyton   }
26967cc577a4SJonathan Peyton 
26977cc577a4SJonathan Peyton #define MIN_MAX_COMPXCHG_CPT(TYPE_ID, OP_ID, TYPE, BITS, OP, GOMP_FLAG)        \
26987cc577a4SJonathan Peyton   ATOMIC_BEGIN_CPT(TYPE_ID, OP_ID, TYPE, TYPE)                                 \
26997cc577a4SJonathan Peyton   TYPE new_value, old_value;                                                   \
2700b3d84790SMartin Storsjö   (void)new_value;                                                             \
27017cc577a4SJonathan Peyton   if (*lhs OP rhs) {                                                           \
27027cc577a4SJonathan Peyton     GOMP_MIN_MAX_CRITSECT_CPT(OP, GOMP_FLAG)                                   \
27037cc577a4SJonathan Peyton     MIN_MAX_CMPXCHG_CPT(TYPE, BITS, OP)                                        \
27047cc577a4SJonathan Peyton   }                                                                            \
27057cc577a4SJonathan Peyton   return *lhs;                                                                 \
27067cc577a4SJonathan Peyton   }
27077cc577a4SJonathan Peyton 
27083041982dSJonathan Peyton MIN_MAX_COMPXCHG_CPT(fixed1, max_cpt, char, 8, <,
27093041982dSJonathan Peyton                      KMP_ARCH_X86) // __kmpc_atomic_fixed1_max_cpt
27103041982dSJonathan Peyton MIN_MAX_COMPXCHG_CPT(fixed1, min_cpt, char, 8, >,
27113041982dSJonathan Peyton                      KMP_ARCH_X86) // __kmpc_atomic_fixed1_min_cpt
27123041982dSJonathan Peyton MIN_MAX_COMPXCHG_CPT(fixed2, max_cpt, short, 16, <,
27133041982dSJonathan Peyton                      KMP_ARCH_X86) // __kmpc_atomic_fixed2_max_cpt
27143041982dSJonathan Peyton MIN_MAX_COMPXCHG_CPT(fixed2, min_cpt, short, 16, >,
27153041982dSJonathan Peyton                      KMP_ARCH_X86) // __kmpc_atomic_fixed2_min_cpt
27163041982dSJonathan Peyton MIN_MAX_COMPXCHG_CPT(fixed4, max_cpt, kmp_int32, 32, <,
27173041982dSJonathan Peyton                      0) // __kmpc_atomic_fixed4_max_cpt
27183041982dSJonathan Peyton MIN_MAX_COMPXCHG_CPT(fixed4, min_cpt, kmp_int32, 32, >,
27193041982dSJonathan Peyton                      0) // __kmpc_atomic_fixed4_min_cpt
27203041982dSJonathan Peyton MIN_MAX_COMPXCHG_CPT(fixed8, max_cpt, kmp_int64, 64, <,
27213041982dSJonathan Peyton                      KMP_ARCH_X86) // __kmpc_atomic_fixed8_max_cpt
27223041982dSJonathan Peyton MIN_MAX_COMPXCHG_CPT(fixed8, min_cpt, kmp_int64, 64, >,
27233041982dSJonathan Peyton                      KMP_ARCH_X86) // __kmpc_atomic_fixed8_min_cpt
27243041982dSJonathan Peyton MIN_MAX_COMPXCHG_CPT(float4, max_cpt, kmp_real32, 32, <,
27253041982dSJonathan Peyton                      KMP_ARCH_X86) // __kmpc_atomic_float4_max_cpt
27263041982dSJonathan Peyton MIN_MAX_COMPXCHG_CPT(float4, min_cpt, kmp_real32, 32, >,
27273041982dSJonathan Peyton                      KMP_ARCH_X86) // __kmpc_atomic_float4_min_cpt
27283041982dSJonathan Peyton MIN_MAX_COMPXCHG_CPT(float8, max_cpt, kmp_real64, 64, <,
27293041982dSJonathan Peyton                      KMP_ARCH_X86) // __kmpc_atomic_float8_max_cpt
27303041982dSJonathan Peyton MIN_MAX_COMPXCHG_CPT(float8, min_cpt, kmp_real64, 64, >,
27313041982dSJonathan Peyton                      KMP_ARCH_X86) // __kmpc_atomic_float8_min_cpt
2732621d7a75SAndreyChurbanov MIN_MAX_CRITICAL_CPT(float10, max_cpt, long double, <, 10r,
2733621d7a75SAndreyChurbanov                      1) // __kmpc_atomic_float10_max_cpt
2734621d7a75SAndreyChurbanov MIN_MAX_CRITICAL_CPT(float10, min_cpt, long double, >, 10r,
2735621d7a75SAndreyChurbanov                      1) // __kmpc_atomic_float10_min_cpt
27367cc577a4SJonathan Peyton #if KMP_HAVE_QUAD
27373041982dSJonathan Peyton MIN_MAX_CRITICAL_CPT(float16, max_cpt, QUAD_LEGACY, <, 16r,
27383041982dSJonathan Peyton                      1) // __kmpc_atomic_float16_max_cpt
27393041982dSJonathan Peyton MIN_MAX_CRITICAL_CPT(float16, min_cpt, QUAD_LEGACY, >, 16r,
27403041982dSJonathan Peyton                      1) // __kmpc_atomic_float16_min_cpt
27417cc577a4SJonathan Peyton #if (KMP_ARCH_X86)
27423041982dSJonathan Peyton MIN_MAX_CRITICAL_CPT(float16, max_a16_cpt, Quad_a16_t, <, 16r,
27433041982dSJonathan Peyton                      1) // __kmpc_atomic_float16_max_a16_cpt
27443041982dSJonathan Peyton MIN_MAX_CRITICAL_CPT(float16, min_a16_cpt, Quad_a16_t, >, 16r,
27453041982dSJonathan Peyton                      1) // __kmpc_atomic_float16_mix_a16_cpt
2746e4b4f994SJonathan Peyton #endif // (KMP_ARCH_X86)
2747e4b4f994SJonathan Peyton #endif // KMP_HAVE_QUAD
27487cc577a4SJonathan Peyton 
27497cc577a4SJonathan Peyton // ------------------------------------------------------------------------
27507cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
27517cc577a4SJonathan Peyton #define OP_GOMP_CRITICAL_EQV_CPT(OP, FLAG)                                     \
27527cc577a4SJonathan Peyton   if ((FLAG) && (__kmp_atomic_mode == 2)) {                                    \
27537cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
27547cc577a4SJonathan Peyton     OP_CRITICAL_CPT(OP, 0);                                                    \
27557cc577a4SJonathan Peyton   }
27567cc577a4SJonathan Peyton #else
27577cc577a4SJonathan Peyton #define OP_GOMP_CRITICAL_EQV_CPT(OP, FLAG)
27587cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
27597cc577a4SJonathan Peyton // ------------------------------------------------------------------------
27607cc577a4SJonathan Peyton #define ATOMIC_CMPX_EQV_CPT(TYPE_ID, OP_ID, TYPE, BITS, OP, GOMP_FLAG)         \
27617cc577a4SJonathan Peyton   ATOMIC_BEGIN_CPT(TYPE_ID, OP_ID, TYPE, TYPE)                                 \
27627cc577a4SJonathan Peyton   TYPE new_value;                                                              \
2763b3d84790SMartin Storsjö   (void)new_value;                                                             \
276444a11c34SHansang Bae   OP_GOMP_CRITICAL_EQV_CPT(^= (TYPE) ~, GOMP_FLAG) /* send assignment */       \
27657cc577a4SJonathan Peyton   OP_CMPXCHG_CPT(TYPE, BITS, OP)                                               \
27667cc577a4SJonathan Peyton   }
27677cc577a4SJonathan Peyton 
27687cc577a4SJonathan Peyton // ------------------------------------------------------------------------
27697cc577a4SJonathan Peyton 
27703041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed1, neqv_cpt, kmp_int8, 8, ^,
27713041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed1_neqv_cpt
27723041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed2, neqv_cpt, kmp_int16, 16, ^,
27733041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed2_neqv_cpt
27743041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed4, neqv_cpt, kmp_int32, 32, ^,
27753041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed4_neqv_cpt
27763041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT(fixed8, neqv_cpt, kmp_int64, 64, ^,
27773041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8_neqv_cpt
27783041982dSJonathan Peyton ATOMIC_CMPX_EQV_CPT(fixed1, eqv_cpt, kmp_int8, 8, ^~,
27793041982dSJonathan Peyton                     KMP_ARCH_X86) // __kmpc_atomic_fixed1_eqv_cpt
27803041982dSJonathan Peyton ATOMIC_CMPX_EQV_CPT(fixed2, eqv_cpt, kmp_int16, 16, ^~,
27813041982dSJonathan Peyton                     KMP_ARCH_X86) // __kmpc_atomic_fixed2_eqv_cpt
27823041982dSJonathan Peyton ATOMIC_CMPX_EQV_CPT(fixed4, eqv_cpt, kmp_int32, 32, ^~,
27833041982dSJonathan Peyton                     KMP_ARCH_X86) // __kmpc_atomic_fixed4_eqv_cpt
27843041982dSJonathan Peyton ATOMIC_CMPX_EQV_CPT(fixed8, eqv_cpt, kmp_int64, 64, ^~,
27853041982dSJonathan Peyton                     KMP_ARCH_X86) // __kmpc_atomic_fixed8_eqv_cpt
27867cc577a4SJonathan Peyton 
27877cc577a4SJonathan Peyton // ------------------------------------------------------------------------
27883041982dSJonathan Peyton // Routines for Extended types: long double, _Quad, complex flavours (use
27893041982dSJonathan Peyton // critical section)
27907cc577a4SJonathan Peyton //     TYPE_ID, OP_ID, TYPE - detailed above
27917cc577a4SJonathan Peyton //     OP      - operator
27927cc577a4SJonathan Peyton //     LCK_ID  - lock identifier, used to possibly distinguish lock variable
27937cc577a4SJonathan Peyton #define ATOMIC_CRITICAL_CPT(TYPE_ID, OP_ID, TYPE, OP, LCK_ID, GOMP_FLAG)       \
27947cc577a4SJonathan Peyton   ATOMIC_BEGIN_CPT(TYPE_ID, OP_ID, TYPE, TYPE)                                 \
27957cc577a4SJonathan Peyton   TYPE new_value;                                                              \
279644a11c34SHansang Bae   OP_GOMP_CRITICAL_CPT(TYPE, OP, GOMP_FLAG) /* send assignment */              \
279744a11c34SHansang Bae   OP_UPDATE_CRITICAL_CPT(TYPE, OP, LCK_ID) /* send assignment */               \
27987cc577a4SJonathan Peyton   }
27997cc577a4SJonathan Peyton 
28007cc577a4SJonathan Peyton // ------------------------------------------------------------------------
28017cc577a4SJonathan Peyton // Workaround for cmplx4. Regular routines with return value don't work
28027cc577a4SJonathan Peyton // on Win_32e. Let's return captured values through the additional parameter.
28037cc577a4SJonathan Peyton #define OP_CRITICAL_CPT_WRK(OP, LCK_ID)                                        \
28047cc577a4SJonathan Peyton   __kmp_acquire_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
28057cc577a4SJonathan Peyton                                                                                \
28067cc577a4SJonathan Peyton   if (flag) {                                                                  \
28077cc577a4SJonathan Peyton     (*lhs) OP rhs;                                                             \
28087cc577a4SJonathan Peyton     (*out) = (*lhs);                                                           \
28097cc577a4SJonathan Peyton   } else {                                                                     \
28107cc577a4SJonathan Peyton     (*out) = (*lhs);                                                           \
28117cc577a4SJonathan Peyton     (*lhs) OP rhs;                                                             \
28127cc577a4SJonathan Peyton   }                                                                            \
28137cc577a4SJonathan Peyton                                                                                \
28147cc577a4SJonathan Peyton   __kmp_release_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
28157cc577a4SJonathan Peyton   return;
28167cc577a4SJonathan Peyton // ------------------------------------------------------------------------
28177cc577a4SJonathan Peyton 
28187cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
28197cc577a4SJonathan Peyton #define OP_GOMP_CRITICAL_CPT_WRK(OP, FLAG)                                     \
28207cc577a4SJonathan Peyton   if ((FLAG) && (__kmp_atomic_mode == 2)) {                                    \
28217cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
28227cc577a4SJonathan Peyton     OP_CRITICAL_CPT_WRK(OP## =, 0);                                            \
28237cc577a4SJonathan Peyton   }
28247cc577a4SJonathan Peyton #else
28257cc577a4SJonathan Peyton #define OP_GOMP_CRITICAL_CPT_WRK(OP, FLAG)
28267cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
28277cc577a4SJonathan Peyton // ------------------------------------------------------------------------
28287cc577a4SJonathan Peyton 
28297cc577a4SJonathan Peyton #define ATOMIC_BEGIN_WRK(TYPE_ID, OP_ID, TYPE)                                 \
28303041982dSJonathan Peyton   void __kmpc_atomic_##TYPE_ID##_##OP_ID(ident_t *id_ref, int gtid, TYPE *lhs, \
28313041982dSJonathan Peyton                                          TYPE rhs, TYPE *out, int flag) {      \
28327cc577a4SJonathan Peyton     KMP_DEBUG_ASSERT(__kmp_init_serial);                                       \
28337cc577a4SJonathan Peyton     KA_TRACE(100, ("__kmpc_atomic_" #TYPE_ID "_" #OP_ID ": T#%d\n", gtid));
28347cc577a4SJonathan Peyton // ------------------------------------------------------------------------
28357cc577a4SJonathan Peyton 
28367cc577a4SJonathan Peyton #define ATOMIC_CRITICAL_CPT_WRK(TYPE_ID, OP_ID, TYPE, OP, LCK_ID, GOMP_FLAG)   \
28377cc577a4SJonathan Peyton   ATOMIC_BEGIN_WRK(TYPE_ID, OP_ID, TYPE)                                       \
28387cc577a4SJonathan Peyton   OP_GOMP_CRITICAL_CPT_WRK(OP, GOMP_FLAG)                                      \
28397cc577a4SJonathan Peyton   OP_CRITICAL_CPT_WRK(OP## =, LCK_ID)                                          \
28407cc577a4SJonathan Peyton   }
28417cc577a4SJonathan Peyton // The end of workaround for cmplx4
28427cc577a4SJonathan Peyton 
28437cc577a4SJonathan Peyton /* ------------------------------------------------------------------------- */
28447cc577a4SJonathan Peyton // routines for long double type
28453041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(float10, add_cpt, long double, +, 10r,
28463041982dSJonathan Peyton                     1) // __kmpc_atomic_float10_add_cpt
28473041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(float10, sub_cpt, long double, -, 10r,
28483041982dSJonathan Peyton                     1) // __kmpc_atomic_float10_sub_cpt
28493041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(float10, mul_cpt, long double, *, 10r,
28503041982dSJonathan Peyton                     1) // __kmpc_atomic_float10_mul_cpt
28513041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(float10, div_cpt, long double, /, 10r,
28523041982dSJonathan Peyton                     1) // __kmpc_atomic_float10_div_cpt
28537cc577a4SJonathan Peyton #if KMP_HAVE_QUAD
28547cc577a4SJonathan Peyton // routines for _Quad type
28553041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(float16, add_cpt, QUAD_LEGACY, +, 16r,
28563041982dSJonathan Peyton                     1) // __kmpc_atomic_float16_add_cpt
28573041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(float16, sub_cpt, QUAD_LEGACY, -, 16r,
28583041982dSJonathan Peyton                     1) // __kmpc_atomic_float16_sub_cpt
28593041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(float16, mul_cpt, QUAD_LEGACY, *, 16r,
28603041982dSJonathan Peyton                     1) // __kmpc_atomic_float16_mul_cpt
28613041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(float16, div_cpt, QUAD_LEGACY, /, 16r,
28623041982dSJonathan Peyton                     1) // __kmpc_atomic_float16_div_cpt
28637cc577a4SJonathan Peyton #if (KMP_ARCH_X86)
28643041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(float16, add_a16_cpt, Quad_a16_t, +, 16r,
28653041982dSJonathan Peyton                     1) // __kmpc_atomic_float16_add_a16_cpt
28663041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(float16, sub_a16_cpt, Quad_a16_t, -, 16r,
28673041982dSJonathan Peyton                     1) // __kmpc_atomic_float16_sub_a16_cpt
28683041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(float16, mul_a16_cpt, Quad_a16_t, *, 16r,
28693041982dSJonathan Peyton                     1) // __kmpc_atomic_float16_mul_a16_cpt
28703041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(float16, div_a16_cpt, Quad_a16_t, /, 16r,
28713041982dSJonathan Peyton                     1) // __kmpc_atomic_float16_div_a16_cpt
2872e4b4f994SJonathan Peyton #endif // (KMP_ARCH_X86)
2873e4b4f994SJonathan Peyton #endif // KMP_HAVE_QUAD
28747cc577a4SJonathan Peyton 
28757cc577a4SJonathan Peyton // routines for complex types
28767cc577a4SJonathan Peyton 
28777cc577a4SJonathan Peyton // cmplx4 routines to return void
28783041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_WRK(cmplx4, add_cpt, kmp_cmplx32, +, 8c,
28793041982dSJonathan Peyton                         1) // __kmpc_atomic_cmplx4_add_cpt
28803041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_WRK(cmplx4, sub_cpt, kmp_cmplx32, -, 8c,
28813041982dSJonathan Peyton                         1) // __kmpc_atomic_cmplx4_sub_cpt
28823041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_WRK(cmplx4, mul_cpt, kmp_cmplx32, *, 8c,
28833041982dSJonathan Peyton                         1) // __kmpc_atomic_cmplx4_mul_cpt
28843041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_WRK(cmplx4, div_cpt, kmp_cmplx32, /, 8c,
28853041982dSJonathan Peyton                         1) // __kmpc_atomic_cmplx4_div_cpt
28867cc577a4SJonathan Peyton 
28873041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(cmplx8, add_cpt, kmp_cmplx64, +, 16c,
28883041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx8_add_cpt
28893041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(cmplx8, sub_cpt, kmp_cmplx64, -, 16c,
28903041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx8_sub_cpt
28913041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(cmplx8, mul_cpt, kmp_cmplx64, *, 16c,
28923041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx8_mul_cpt
28933041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(cmplx8, div_cpt, kmp_cmplx64, /, 16c,
28943041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx8_div_cpt
28953041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(cmplx10, add_cpt, kmp_cmplx80, +, 20c,
28963041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx10_add_cpt
28973041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(cmplx10, sub_cpt, kmp_cmplx80, -, 20c,
28983041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx10_sub_cpt
28993041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(cmplx10, mul_cpt, kmp_cmplx80, *, 20c,
29003041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx10_mul_cpt
29013041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(cmplx10, div_cpt, kmp_cmplx80, /, 20c,
29023041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx10_div_cpt
29037cc577a4SJonathan Peyton #if KMP_HAVE_QUAD
29043041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(cmplx16, add_cpt, CPLX128_LEG, +, 32c,
29053041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx16_add_cpt
29063041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(cmplx16, sub_cpt, CPLX128_LEG, -, 32c,
29073041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx16_sub_cpt
29083041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(cmplx16, mul_cpt, CPLX128_LEG, *, 32c,
29093041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx16_mul_cpt
29103041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(cmplx16, div_cpt, CPLX128_LEG, /, 32c,
29113041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx16_div_cpt
29127cc577a4SJonathan Peyton #if (KMP_ARCH_X86)
29133041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(cmplx16, add_a16_cpt, kmp_cmplx128_a16_t, +, 32c,
29143041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx16_add_a16_cpt
29153041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(cmplx16, sub_a16_cpt, kmp_cmplx128_a16_t, -, 32c,
29163041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx16_sub_a16_cpt
29173041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(cmplx16, mul_a16_cpt, kmp_cmplx128_a16_t, *, 32c,
29183041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx16_mul_a16_cpt
29193041982dSJonathan Peyton ATOMIC_CRITICAL_CPT(cmplx16, div_a16_cpt, kmp_cmplx128_a16_t, /, 32c,
29203041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx16_div_a16_cpt
2921e4b4f994SJonathan Peyton #endif // (KMP_ARCH_X86)
2922e4b4f994SJonathan Peyton #endif // KMP_HAVE_QUAD
29237cc577a4SJonathan Peyton 
29243041982dSJonathan Peyton // OpenMP 4.0: v = x = expr binop x; { v = x; x = expr binop x; } { x = expr
29253041982dSJonathan Peyton // binop x; v = x; }  for non-commutative operations.
29267cc577a4SJonathan Peyton // Supported only on IA-32 architecture and Intel(R) 64
29277cc577a4SJonathan Peyton 
29287cc577a4SJonathan Peyton // -------------------------------------------------------------------------
29297cc577a4SJonathan Peyton // Operation on *lhs, rhs bound by critical section
29307cc577a4SJonathan Peyton //     OP     - operator (it's supposed to contain an assignment)
29317cc577a4SJonathan Peyton //     LCK_ID - lock identifier
29327cc577a4SJonathan Peyton // Note: don't check gtid as it should always be valid
29337cc577a4SJonathan Peyton // 1, 2-byte - expect valid parameter, other - check before this macro
293444a11c34SHansang Bae #define OP_CRITICAL_CPT_REV(TYPE, OP, LCK_ID)                                  \
29357cc577a4SJonathan Peyton   __kmp_acquire_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
29367cc577a4SJonathan Peyton                                                                                \
29377cc577a4SJonathan Peyton   if (flag) {                                                                  \
29387cc577a4SJonathan Peyton     /*temp_val = (*lhs);*/                                                     \
293944a11c34SHansang Bae     (*lhs) = (TYPE)((rhs)OP(*lhs));                                            \
29407cc577a4SJonathan Peyton     new_value = (*lhs);                                                        \
29417cc577a4SJonathan Peyton   } else {                                                                     \
29427cc577a4SJonathan Peyton     new_value = (*lhs);                                                        \
294344a11c34SHansang Bae     (*lhs) = (TYPE)((rhs)OP(*lhs));                                            \
29447cc577a4SJonathan Peyton   }                                                                            \
29457cc577a4SJonathan Peyton   __kmp_release_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
29467cc577a4SJonathan Peyton   return new_value;
29477cc577a4SJonathan Peyton 
29487cc577a4SJonathan Peyton // ------------------------------------------------------------------------
29497cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
295044a11c34SHansang Bae #define OP_GOMP_CRITICAL_CPT_REV(TYPE, OP, FLAG)                               \
29517cc577a4SJonathan Peyton   if ((FLAG) && (__kmp_atomic_mode == 2)) {                                    \
29527cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
295344a11c34SHansang Bae     OP_CRITICAL_CPT_REV(TYPE, OP, 0);                                          \
29547cc577a4SJonathan Peyton   }
29557cc577a4SJonathan Peyton #else
295644a11c34SHansang Bae #define OP_GOMP_CRITICAL_CPT_REV(TYPE, OP, FLAG)
29577cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
29587cc577a4SJonathan Peyton 
29597cc577a4SJonathan Peyton // ------------------------------------------------------------------------
29607cc577a4SJonathan Peyton // Operation on *lhs, rhs using "compare_and_store" routine
29617cc577a4SJonathan Peyton //     TYPE    - operands' type
29627cc577a4SJonathan Peyton //     BITS    - size in bits, used to distinguish low level calls
29637cc577a4SJonathan Peyton //     OP      - operator
29647cc577a4SJonathan Peyton // Note: temp_val introduced in order to force the compiler to read
29657cc577a4SJonathan Peyton //       *lhs only once (w/o it the compiler reads *lhs twice)
29667cc577a4SJonathan Peyton #define OP_CMPXCHG_CPT_REV(TYPE, BITS, OP)                                     \
29677cc577a4SJonathan Peyton   {                                                                            \
29687cc577a4SJonathan Peyton     TYPE KMP_ATOMIC_VOLATILE temp_val;                                         \
29697cc577a4SJonathan Peyton     TYPE old_value, new_value;                                                 \
29707cc577a4SJonathan Peyton     temp_val = *lhs;                                                           \
29717cc577a4SJonathan Peyton     old_value = temp_val;                                                      \
297244a11c34SHansang Bae     new_value = (TYPE)(rhs OP old_value);                                      \
29733041982dSJonathan Peyton     while (!KMP_COMPARE_AND_STORE_ACQ##BITS(                                   \
29743041982dSJonathan Peyton         (kmp_int##BITS *)lhs, *VOLATILE_CAST(kmp_int##BITS *) & old_value,     \
29753041982dSJonathan Peyton         *VOLATILE_CAST(kmp_int##BITS *) & new_value)) {                        \
29767cc577a4SJonathan Peyton       temp_val = *lhs;                                                         \
29777cc577a4SJonathan Peyton       old_value = temp_val;                                                    \
297844a11c34SHansang Bae       new_value = (TYPE)(rhs OP old_value);                                    \
29797cc577a4SJonathan Peyton     }                                                                          \
29807cc577a4SJonathan Peyton     if (flag) {                                                                \
29817cc577a4SJonathan Peyton       return new_value;                                                        \
29827cc577a4SJonathan Peyton     } else                                                                     \
29837cc577a4SJonathan Peyton       return old_value;                                                        \
29847cc577a4SJonathan Peyton   }
29857cc577a4SJonathan Peyton 
29867cc577a4SJonathan Peyton // -------------------------------------------------------------------------
29877cc577a4SJonathan Peyton #define ATOMIC_CMPXCHG_CPT_REV(TYPE_ID, OP_ID, TYPE, BITS, OP, GOMP_FLAG)      \
29887cc577a4SJonathan Peyton   ATOMIC_BEGIN_CPT(TYPE_ID, OP_ID, TYPE, TYPE)                                 \
29897cc577a4SJonathan Peyton   TYPE new_value;                                                              \
2990b3d84790SMartin Storsjö   (void)new_value;                                                             \
299144a11c34SHansang Bae   OP_GOMP_CRITICAL_CPT_REV(TYPE, OP, GOMP_FLAG)                                \
29927cc577a4SJonathan Peyton   OP_CMPXCHG_CPT_REV(TYPE, BITS, OP)                                           \
29937cc577a4SJonathan Peyton   }
29947cc577a4SJonathan Peyton 
29953041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed1, div_cpt_rev, kmp_int8, 8, /,
29963041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed1_div_cpt_rev
29973041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed1u, div_cpt_rev, kmp_uint8, 8, /,
29983041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed1u_div_cpt_rev
29993041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed1, shl_cpt_rev, kmp_int8, 8, <<,
30003041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed1_shl_cpt_rev
30013041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed1, shr_cpt_rev, kmp_int8, 8, >>,
30023041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed1_shr_cpt_rev
30033041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed1u, shr_cpt_rev, kmp_uint8, 8, >>,
30043041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed1u_shr_cpt_rev
30053041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed1, sub_cpt_rev, kmp_int8, 8, -,
30063041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed1_sub_cpt_rev
30073041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed2, div_cpt_rev, kmp_int16, 16, /,
30083041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed2_div_cpt_rev
30093041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed2u, div_cpt_rev, kmp_uint16, 16, /,
30103041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed2u_div_cpt_rev
30113041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed2, shl_cpt_rev, kmp_int16, 16, <<,
30123041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed2_shl_cpt_rev
30133041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed2, shr_cpt_rev, kmp_int16, 16, >>,
30143041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed2_shr_cpt_rev
30153041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed2u, shr_cpt_rev, kmp_uint16, 16, >>,
30163041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed2u_shr_cpt_rev
30173041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed2, sub_cpt_rev, kmp_int16, 16, -,
30183041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed2_sub_cpt_rev
30193041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed4, div_cpt_rev, kmp_int32, 32, /,
30203041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed4_div_cpt_rev
30213041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed4u, div_cpt_rev, kmp_uint32, 32, /,
30223041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed4u_div_cpt_rev
30233041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed4, shl_cpt_rev, kmp_int32, 32, <<,
30243041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed4_shl_cpt_rev
30253041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed4, shr_cpt_rev, kmp_int32, 32, >>,
30263041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed4_shr_cpt_rev
30273041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed4u, shr_cpt_rev, kmp_uint32, 32, >>,
30283041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed4u_shr_cpt_rev
30293041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed4, sub_cpt_rev, kmp_int32, 32, -,
30303041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed4_sub_cpt_rev
30313041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed8, div_cpt_rev, kmp_int64, 64, /,
30323041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed8_div_cpt_rev
30333041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed8u, div_cpt_rev, kmp_uint64, 64, /,
30343041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed8u_div_cpt_rev
30353041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed8, shl_cpt_rev, kmp_int64, 64, <<,
30363041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed8_shl_cpt_rev
30373041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed8, shr_cpt_rev, kmp_int64, 64, >>,
30383041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed8_shr_cpt_rev
30393041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed8u, shr_cpt_rev, kmp_uint64, 64, >>,
30403041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed8u_shr_cpt_rev
30413041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(fixed8, sub_cpt_rev, kmp_int64, 64, -,
30423041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_fixed8_sub_cpt_rev
30433041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(float4, div_cpt_rev, kmp_real32, 32, /,
30443041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_float4_div_cpt_rev
30453041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(float4, sub_cpt_rev, kmp_real32, 32, -,
30463041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_float4_sub_cpt_rev
30473041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(float8, div_cpt_rev, kmp_real64, 64, /,
30483041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_float8_div_cpt_rev
30493041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV(float8, sub_cpt_rev, kmp_real64, 64, -,
30503041982dSJonathan Peyton                        KMP_ARCH_X86) // __kmpc_atomic_float8_sub_cpt_rev
30517cc577a4SJonathan Peyton //              TYPE_ID,OP_ID, TYPE,          OP,  GOMP_FLAG
30527cc577a4SJonathan Peyton 
30537cc577a4SJonathan Peyton // ------------------------------------------------------------------------
30543041982dSJonathan Peyton // Routines for Extended types: long double, _Quad, complex flavours (use
30553041982dSJonathan Peyton // critical section)
30567cc577a4SJonathan Peyton //     TYPE_ID, OP_ID, TYPE - detailed above
30577cc577a4SJonathan Peyton //     OP      - operator
30587cc577a4SJonathan Peyton //     LCK_ID  - lock identifier, used to possibly distinguish lock variable
30597cc577a4SJonathan Peyton #define ATOMIC_CRITICAL_CPT_REV(TYPE_ID, OP_ID, TYPE, OP, LCK_ID, GOMP_FLAG)   \
30607cc577a4SJonathan Peyton   ATOMIC_BEGIN_CPT(TYPE_ID, OP_ID, TYPE, TYPE)                                 \
30617cc577a4SJonathan Peyton   TYPE new_value;                                                              \
30627cc577a4SJonathan Peyton   /*printf("__kmp_atomic_mode = %d\n", __kmp_atomic_mode);*/                   \
306344a11c34SHansang Bae   OP_GOMP_CRITICAL_CPT_REV(TYPE, OP, GOMP_FLAG)                                \
306444a11c34SHansang Bae   OP_CRITICAL_CPT_REV(TYPE, OP, LCK_ID)                                        \
30657cc577a4SJonathan Peyton   }
30667cc577a4SJonathan Peyton 
30677cc577a4SJonathan Peyton /* ------------------------------------------------------------------------- */
30687cc577a4SJonathan Peyton // routines for long double type
30693041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_REV(float10, sub_cpt_rev, long double, -, 10r,
30703041982dSJonathan Peyton                         1) // __kmpc_atomic_float10_sub_cpt_rev
30713041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_REV(float10, div_cpt_rev, long double, /, 10r,
30723041982dSJonathan Peyton                         1) // __kmpc_atomic_float10_div_cpt_rev
30737cc577a4SJonathan Peyton #if KMP_HAVE_QUAD
30747cc577a4SJonathan Peyton // routines for _Quad type
30753041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_REV(float16, sub_cpt_rev, QUAD_LEGACY, -, 16r,
30763041982dSJonathan Peyton                         1) // __kmpc_atomic_float16_sub_cpt_rev
30773041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_REV(float16, div_cpt_rev, QUAD_LEGACY, /, 16r,
30783041982dSJonathan Peyton                         1) // __kmpc_atomic_float16_div_cpt_rev
30797cc577a4SJonathan Peyton #if (KMP_ARCH_X86)
30803041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_REV(float16, sub_a16_cpt_rev, Quad_a16_t, -, 16r,
30813041982dSJonathan Peyton                         1) // __kmpc_atomic_float16_sub_a16_cpt_rev
30823041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_REV(float16, div_a16_cpt_rev, Quad_a16_t, /, 16r,
30833041982dSJonathan Peyton                         1) // __kmpc_atomic_float16_div_a16_cpt_rev
3084e4b4f994SJonathan Peyton #endif // (KMP_ARCH_X86)
3085e4b4f994SJonathan Peyton #endif // KMP_HAVE_QUAD
30867cc577a4SJonathan Peyton 
30877cc577a4SJonathan Peyton // routines for complex types
30887cc577a4SJonathan Peyton 
30897cc577a4SJonathan Peyton // ------------------------------------------------------------------------
30907cc577a4SJonathan Peyton // Workaround for cmplx4. Regular routines with return value don't work
30917cc577a4SJonathan Peyton // on Win_32e. Let's return captured values through the additional parameter.
30927cc577a4SJonathan Peyton #define OP_CRITICAL_CPT_REV_WRK(OP, LCK_ID)                                    \
30937cc577a4SJonathan Peyton   __kmp_acquire_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
30947cc577a4SJonathan Peyton                                                                                \
30957cc577a4SJonathan Peyton   if (flag) {                                                                  \
30967cc577a4SJonathan Peyton     (*lhs) = (rhs)OP(*lhs);                                                    \
30977cc577a4SJonathan Peyton     (*out) = (*lhs);                                                           \
30987cc577a4SJonathan Peyton   } else {                                                                     \
30997cc577a4SJonathan Peyton     (*out) = (*lhs);                                                           \
31007cc577a4SJonathan Peyton     (*lhs) = (rhs)OP(*lhs);                                                    \
31017cc577a4SJonathan Peyton   }                                                                            \
31027cc577a4SJonathan Peyton                                                                                \
31037cc577a4SJonathan Peyton   __kmp_release_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
31047cc577a4SJonathan Peyton   return;
31057cc577a4SJonathan Peyton // ------------------------------------------------------------------------
31067cc577a4SJonathan Peyton 
31077cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
31087cc577a4SJonathan Peyton #define OP_GOMP_CRITICAL_CPT_REV_WRK(OP, FLAG)                                 \
31097cc577a4SJonathan Peyton   if ((FLAG) && (__kmp_atomic_mode == 2)) {                                    \
31107cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
31117cc577a4SJonathan Peyton     OP_CRITICAL_CPT_REV_WRK(OP, 0);                                            \
31127cc577a4SJonathan Peyton   }
31137cc577a4SJonathan Peyton #else
31147cc577a4SJonathan Peyton #define OP_GOMP_CRITICAL_CPT_REV_WRK(OP, FLAG)
31157cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
31167cc577a4SJonathan Peyton // ------------------------------------------------------------------------
31177cc577a4SJonathan Peyton 
31183041982dSJonathan Peyton #define ATOMIC_CRITICAL_CPT_REV_WRK(TYPE_ID, OP_ID, TYPE, OP, LCK_ID,          \
31193041982dSJonathan Peyton                                     GOMP_FLAG)                                 \
31207cc577a4SJonathan Peyton   ATOMIC_BEGIN_WRK(TYPE_ID, OP_ID, TYPE)                                       \
31217cc577a4SJonathan Peyton   OP_GOMP_CRITICAL_CPT_REV_WRK(OP, GOMP_FLAG)                                  \
31227cc577a4SJonathan Peyton   OP_CRITICAL_CPT_REV_WRK(OP, LCK_ID)                                          \
31237cc577a4SJonathan Peyton   }
31247cc577a4SJonathan Peyton // The end of workaround for cmplx4
31257cc577a4SJonathan Peyton 
31267cc577a4SJonathan Peyton // !!! TODO: check if we need to return void for cmplx4 routines
31277cc577a4SJonathan Peyton // cmplx4 routines to return void
31283041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_REV_WRK(cmplx4, sub_cpt_rev, kmp_cmplx32, -, 8c,
31293041982dSJonathan Peyton                             1) // __kmpc_atomic_cmplx4_sub_cpt_rev
31303041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_REV_WRK(cmplx4, div_cpt_rev, kmp_cmplx32, /, 8c,
31313041982dSJonathan Peyton                             1) // __kmpc_atomic_cmplx4_div_cpt_rev
31327cc577a4SJonathan Peyton 
31333041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_REV(cmplx8, sub_cpt_rev, kmp_cmplx64, -, 16c,
31343041982dSJonathan Peyton                         1) // __kmpc_atomic_cmplx8_sub_cpt_rev
31353041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_REV(cmplx8, div_cpt_rev, kmp_cmplx64, /, 16c,
31363041982dSJonathan Peyton                         1) // __kmpc_atomic_cmplx8_div_cpt_rev
31373041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_REV(cmplx10, sub_cpt_rev, kmp_cmplx80, -, 20c,
31383041982dSJonathan Peyton                         1) // __kmpc_atomic_cmplx10_sub_cpt_rev
31393041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_REV(cmplx10, div_cpt_rev, kmp_cmplx80, /, 20c,
31403041982dSJonathan Peyton                         1) // __kmpc_atomic_cmplx10_div_cpt_rev
31417cc577a4SJonathan Peyton #if KMP_HAVE_QUAD
31423041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_REV(cmplx16, sub_cpt_rev, CPLX128_LEG, -, 32c,
31433041982dSJonathan Peyton                         1) // __kmpc_atomic_cmplx16_sub_cpt_rev
31443041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_REV(cmplx16, div_cpt_rev, CPLX128_LEG, /, 32c,
31453041982dSJonathan Peyton                         1) // __kmpc_atomic_cmplx16_div_cpt_rev
31467cc577a4SJonathan Peyton #if (KMP_ARCH_X86)
31473041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_REV(cmplx16, sub_a16_cpt_rev, kmp_cmplx128_a16_t, -, 32c,
31483041982dSJonathan Peyton                         1) // __kmpc_atomic_cmplx16_sub_a16_cpt_rev
31493041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_REV(cmplx16, div_a16_cpt_rev, kmp_cmplx128_a16_t, /, 32c,
31503041982dSJonathan Peyton                         1) // __kmpc_atomic_cmplx16_div_a16_cpt_rev
3151e4b4f994SJonathan Peyton #endif // (KMP_ARCH_X86)
3152e4b4f994SJonathan Peyton #endif // KMP_HAVE_QUAD
31537cc577a4SJonathan Peyton 
31547cc577a4SJonathan Peyton // Capture reverse for mixed type: RHS=float16
31557cc577a4SJonathan Peyton #if KMP_HAVE_QUAD
31567cc577a4SJonathan Peyton 
31577cc577a4SJonathan Peyton // Beginning of a definition (provides name, parameters, gebug trace)
31583041982dSJonathan Peyton //     TYPE_ID - operands type and size (fixed*, fixed*u for signed, unsigned
31593041982dSJonathan Peyton //     fixed)
31607cc577a4SJonathan Peyton //     OP_ID   - operation identifier (add, sub, mul, ...)
31617cc577a4SJonathan Peyton //     TYPE    - operands' type
31627cc577a4SJonathan Peyton // -------------------------------------------------------------------------
31633041982dSJonathan Peyton #define ATOMIC_CMPXCHG_CPT_REV_MIX(TYPE_ID, TYPE, OP_ID, BITS, OP, RTYPE_ID,   \
31643041982dSJonathan Peyton                                    RTYPE, LCK_ID, MASK, GOMP_FLAG)             \
31657cc577a4SJonathan Peyton   ATOMIC_BEGIN_CPT_MIX(TYPE_ID, OP_ID, TYPE, RTYPE_ID, RTYPE)                  \
31667cc577a4SJonathan Peyton   TYPE new_value;                                                              \
3167*1234011bSJonathan Peyton   (void)new_value;                                                             \
316844a11c34SHansang Bae   OP_GOMP_CRITICAL_CPT_REV(TYPE, OP, GOMP_FLAG)                                \
31697cc577a4SJonathan Peyton   OP_CMPXCHG_CPT_REV(TYPE, BITS, OP)                                           \
31707cc577a4SJonathan Peyton   }
31717cc577a4SJonathan Peyton 
31727cc577a4SJonathan Peyton // -------------------------------------------------------------------------
31733041982dSJonathan Peyton #define ATOMIC_CRITICAL_CPT_REV_MIX(TYPE_ID, TYPE, OP_ID, OP, RTYPE_ID, RTYPE, \
31743041982dSJonathan Peyton                                     LCK_ID, GOMP_FLAG)                         \
31757cc577a4SJonathan Peyton   ATOMIC_BEGIN_CPT_MIX(TYPE_ID, OP_ID, TYPE, RTYPE_ID, RTYPE)                  \
31767cc577a4SJonathan Peyton   TYPE new_value;                                                              \
3177*1234011bSJonathan Peyton   (void)new_value;                                                             \
317844a11c34SHansang Bae   OP_GOMP_CRITICAL_CPT_REV(TYPE, OP, GOMP_FLAG) /* send assignment */          \
317944a11c34SHansang Bae   OP_CRITICAL_CPT_REV(TYPE, OP, LCK_ID) /* send assignment */                  \
31807cc577a4SJonathan Peyton   }
31817cc577a4SJonathan Peyton 
31823041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(fixed1, char, sub_cpt_rev, 8, -, fp, _Quad, 1i, 0,
31833041982dSJonathan Peyton                            KMP_ARCH_X86) // __kmpc_atomic_fixed1_sub_cpt_rev_fp
31843041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(fixed1u, uchar, sub_cpt_rev, 8, -, fp, _Quad, 1i, 0,
31853041982dSJonathan Peyton                            KMP_ARCH_X86) // __kmpc_atomic_fixed1u_sub_cpt_rev_fp
31863041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(fixed1, char, div_cpt_rev, 8, /, fp, _Quad, 1i, 0,
31873041982dSJonathan Peyton                            KMP_ARCH_X86) // __kmpc_atomic_fixed1_div_cpt_rev_fp
31883041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(fixed1u, uchar, div_cpt_rev, 8, /, fp, _Quad, 1i, 0,
31893041982dSJonathan Peyton                            KMP_ARCH_X86) // __kmpc_atomic_fixed1u_div_cpt_rev_fp
31907cc577a4SJonathan Peyton 
31913041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(fixed2, short, sub_cpt_rev, 16, -, fp, _Quad, 2i, 1,
31923041982dSJonathan Peyton                            KMP_ARCH_X86) // __kmpc_atomic_fixed2_sub_cpt_rev_fp
31933041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(fixed2u, ushort, sub_cpt_rev, 16, -, fp, _Quad, 2i,
31943041982dSJonathan Peyton                            1,
31953041982dSJonathan Peyton                            KMP_ARCH_X86) // __kmpc_atomic_fixed2u_sub_cpt_rev_fp
31963041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(fixed2, short, div_cpt_rev, 16, /, fp, _Quad, 2i, 1,
31973041982dSJonathan Peyton                            KMP_ARCH_X86) // __kmpc_atomic_fixed2_div_cpt_rev_fp
31983041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(fixed2u, ushort, div_cpt_rev, 16, /, fp, _Quad, 2i,
31993041982dSJonathan Peyton                            1,
32003041982dSJonathan Peyton                            KMP_ARCH_X86) // __kmpc_atomic_fixed2u_div_cpt_rev_fp
32017cc577a4SJonathan Peyton 
32023041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(fixed4, kmp_int32, sub_cpt_rev, 32, -, fp, _Quad, 4i,
32033041982dSJonathan Peyton                            3, 0) // __kmpc_atomic_fixed4_sub_cpt_rev_fp
32043041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(fixed4u, kmp_uint32, sub_cpt_rev, 32, -, fp, _Quad,
32053041982dSJonathan Peyton                            4i, 3, 0) // __kmpc_atomic_fixed4u_sub_cpt_rev_fp
32063041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(fixed4, kmp_int32, div_cpt_rev, 32, /, fp, _Quad, 4i,
32073041982dSJonathan Peyton                            3, 0) // __kmpc_atomic_fixed4_div_cpt_rev_fp
32083041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(fixed4u, kmp_uint32, div_cpt_rev, 32, /, fp, _Quad,
32093041982dSJonathan Peyton                            4i, 3, 0) // __kmpc_atomic_fixed4u_div_cpt_rev_fp
32107cc577a4SJonathan Peyton 
32113041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(fixed8, kmp_int64, sub_cpt_rev, 64, -, fp, _Quad, 8i,
32123041982dSJonathan Peyton                            7,
32133041982dSJonathan Peyton                            KMP_ARCH_X86) // __kmpc_atomic_fixed8_sub_cpt_rev_fp
32143041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(fixed8u, kmp_uint64, sub_cpt_rev, 64, -, fp, _Quad,
32153041982dSJonathan Peyton                            8i, 7,
32163041982dSJonathan Peyton                            KMP_ARCH_X86) // __kmpc_atomic_fixed8u_sub_cpt_rev_fp
32173041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(fixed8, kmp_int64, div_cpt_rev, 64, /, fp, _Quad, 8i,
32183041982dSJonathan Peyton                            7,
32193041982dSJonathan Peyton                            KMP_ARCH_X86) // __kmpc_atomic_fixed8_div_cpt_rev_fp
32203041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(fixed8u, kmp_uint64, div_cpt_rev, 64, /, fp, _Quad,
32213041982dSJonathan Peyton                            8i, 7,
32223041982dSJonathan Peyton                            KMP_ARCH_X86) // __kmpc_atomic_fixed8u_div_cpt_rev_fp
32237cc577a4SJonathan Peyton 
32243041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(float4, kmp_real32, sub_cpt_rev, 32, -, fp, _Quad,
32253041982dSJonathan Peyton                            4r, 3,
32263041982dSJonathan Peyton                            KMP_ARCH_X86) // __kmpc_atomic_float4_sub_cpt_rev_fp
32273041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(float4, kmp_real32, div_cpt_rev, 32, /, fp, _Quad,
32283041982dSJonathan Peyton                            4r, 3,
32293041982dSJonathan Peyton                            KMP_ARCH_X86) // __kmpc_atomic_float4_div_cpt_rev_fp
32307cc577a4SJonathan Peyton 
32313041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(float8, kmp_real64, sub_cpt_rev, 64, -, fp, _Quad,
32323041982dSJonathan Peyton                            8r, 7,
32333041982dSJonathan Peyton                            KMP_ARCH_X86) // __kmpc_atomic_float8_sub_cpt_rev_fp
32343041982dSJonathan Peyton ATOMIC_CMPXCHG_CPT_REV_MIX(float8, kmp_real64, div_cpt_rev, 64, /, fp, _Quad,
32353041982dSJonathan Peyton                            8r, 7,
32363041982dSJonathan Peyton                            KMP_ARCH_X86) // __kmpc_atomic_float8_div_cpt_rev_fp
32377cc577a4SJonathan Peyton 
32383041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_REV_MIX(float10, long double, sub_cpt_rev, -, fp, _Quad,
32393041982dSJonathan Peyton                             10r, 1) // __kmpc_atomic_float10_sub_cpt_rev_fp
32403041982dSJonathan Peyton ATOMIC_CRITICAL_CPT_REV_MIX(float10, long double, div_cpt_rev, /, fp, _Quad,
32413041982dSJonathan Peyton                             10r, 1) // __kmpc_atomic_float10_div_cpt_rev_fp
32427cc577a4SJonathan Peyton 
32437cc577a4SJonathan Peyton #endif // KMP_HAVE_QUAD
32447cc577a4SJonathan Peyton 
32457cc577a4SJonathan Peyton //   OpenMP 4.0 Capture-write (swap): {v = x; x = expr;}
32467cc577a4SJonathan Peyton 
32477cc577a4SJonathan Peyton #define ATOMIC_BEGIN_SWP(TYPE_ID, TYPE)                                        \
32483041982dSJonathan Peyton   TYPE __kmpc_atomic_##TYPE_ID##_swp(ident_t *id_ref, int gtid, TYPE *lhs,     \
32493041982dSJonathan Peyton                                      TYPE rhs) {                               \
32507cc577a4SJonathan Peyton     KMP_DEBUG_ASSERT(__kmp_init_serial);                                       \
32517cc577a4SJonathan Peyton     KA_TRACE(100, ("__kmpc_atomic_" #TYPE_ID "_swp: T#%d\n", gtid));
32527cc577a4SJonathan Peyton 
32537cc577a4SJonathan Peyton #define CRITICAL_SWP(LCK_ID)                                                   \
32547cc577a4SJonathan Peyton   __kmp_acquire_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
32557cc577a4SJonathan Peyton                                                                                \
32567cc577a4SJonathan Peyton   old_value = (*lhs);                                                          \
32577cc577a4SJonathan Peyton   (*lhs) = rhs;                                                                \
32587cc577a4SJonathan Peyton                                                                                \
32597cc577a4SJonathan Peyton   __kmp_release_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
32607cc577a4SJonathan Peyton   return old_value;
32617cc577a4SJonathan Peyton 
32627cc577a4SJonathan Peyton // ------------------------------------------------------------------------
32637cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
32647cc577a4SJonathan Peyton #define GOMP_CRITICAL_SWP(FLAG)                                                \
32657cc577a4SJonathan Peyton   if ((FLAG) && (__kmp_atomic_mode == 2)) {                                    \
32667cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
32677cc577a4SJonathan Peyton     CRITICAL_SWP(0);                                                           \
32687cc577a4SJonathan Peyton   }
32697cc577a4SJonathan Peyton #else
32707cc577a4SJonathan Peyton #define GOMP_CRITICAL_SWP(FLAG)
32717cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
32727cc577a4SJonathan Peyton 
32737cc577a4SJonathan Peyton #define ATOMIC_XCHG_SWP(TYPE_ID, TYPE, BITS, GOMP_FLAG)                        \
32747cc577a4SJonathan Peyton   ATOMIC_BEGIN_SWP(TYPE_ID, TYPE)                                              \
32757cc577a4SJonathan Peyton   TYPE old_value;                                                              \
32767cc577a4SJonathan Peyton   GOMP_CRITICAL_SWP(GOMP_FLAG)                                                 \
32777cc577a4SJonathan Peyton   old_value = KMP_XCHG_FIXED##BITS(lhs, rhs);                                  \
32787cc577a4SJonathan Peyton   return old_value;                                                            \
32797cc577a4SJonathan Peyton   }
32807cc577a4SJonathan Peyton // ------------------------------------------------------------------------
32817cc577a4SJonathan Peyton #define ATOMIC_XCHG_FLOAT_SWP(TYPE_ID, TYPE, BITS, GOMP_FLAG)                  \
32827cc577a4SJonathan Peyton   ATOMIC_BEGIN_SWP(TYPE_ID, TYPE)                                              \
32837cc577a4SJonathan Peyton   TYPE old_value;                                                              \
32847cc577a4SJonathan Peyton   GOMP_CRITICAL_SWP(GOMP_FLAG)                                                 \
32857cc577a4SJonathan Peyton   old_value = KMP_XCHG_REAL##BITS(lhs, rhs);                                   \
32867cc577a4SJonathan Peyton   return old_value;                                                            \
32877cc577a4SJonathan Peyton   }
32887cc577a4SJonathan Peyton 
32897cc577a4SJonathan Peyton // ------------------------------------------------------------------------
32907cc577a4SJonathan Peyton #define CMPXCHG_SWP(TYPE, BITS)                                                \
32917cc577a4SJonathan Peyton   {                                                                            \
32927cc577a4SJonathan Peyton     TYPE KMP_ATOMIC_VOLATILE temp_val;                                         \
32937cc577a4SJonathan Peyton     TYPE old_value, new_value;                                                 \
32947cc577a4SJonathan Peyton     temp_val = *lhs;                                                           \
32957cc577a4SJonathan Peyton     old_value = temp_val;                                                      \
32967cc577a4SJonathan Peyton     new_value = rhs;                                                           \
32973041982dSJonathan Peyton     while (!KMP_COMPARE_AND_STORE_ACQ##BITS(                                   \
32983041982dSJonathan Peyton         (kmp_int##BITS *)lhs, *VOLATILE_CAST(kmp_int##BITS *) & old_value,     \
32993041982dSJonathan Peyton         *VOLATILE_CAST(kmp_int##BITS *) & new_value)) {                        \
33007cc577a4SJonathan Peyton       temp_val = *lhs;                                                         \
33017cc577a4SJonathan Peyton       old_value = temp_val;                                                    \
33027cc577a4SJonathan Peyton       new_value = rhs;                                                         \
33037cc577a4SJonathan Peyton     }                                                                          \
33047cc577a4SJonathan Peyton     return old_value;                                                          \
33057cc577a4SJonathan Peyton   }
33067cc577a4SJonathan Peyton 
33077cc577a4SJonathan Peyton // -------------------------------------------------------------------------
33087cc577a4SJonathan Peyton #define ATOMIC_CMPXCHG_SWP(TYPE_ID, TYPE, BITS, GOMP_FLAG)                     \
33097cc577a4SJonathan Peyton   ATOMIC_BEGIN_SWP(TYPE_ID, TYPE)                                              \
33107cc577a4SJonathan Peyton   TYPE old_value;                                                              \
3311b3d84790SMartin Storsjö   (void)old_value;                                                             \
33127cc577a4SJonathan Peyton   GOMP_CRITICAL_SWP(GOMP_FLAG)                                                 \
33137cc577a4SJonathan Peyton   CMPXCHG_SWP(TYPE, BITS)                                                      \
33147cc577a4SJonathan Peyton   }
33157cc577a4SJonathan Peyton 
33167cc577a4SJonathan Peyton ATOMIC_XCHG_SWP(fixed1, kmp_int8, 8, KMP_ARCH_X86) // __kmpc_atomic_fixed1_swp
33177cc577a4SJonathan Peyton ATOMIC_XCHG_SWP(fixed2, kmp_int16, 16, KMP_ARCH_X86) // __kmpc_atomic_fixed2_swp
33187cc577a4SJonathan Peyton ATOMIC_XCHG_SWP(fixed4, kmp_int32, 32, KMP_ARCH_X86) // __kmpc_atomic_fixed4_swp
33197cc577a4SJonathan Peyton 
33203041982dSJonathan Peyton ATOMIC_XCHG_FLOAT_SWP(float4, kmp_real32, 32,
33213041982dSJonathan Peyton                       KMP_ARCH_X86) // __kmpc_atomic_float4_swp
33227cc577a4SJonathan Peyton 
33237cc577a4SJonathan Peyton #if (KMP_ARCH_X86)
33243041982dSJonathan Peyton ATOMIC_CMPXCHG_SWP(fixed8, kmp_int64, 64,
33253041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_fixed8_swp
33263041982dSJonathan Peyton ATOMIC_CMPXCHG_SWP(float8, kmp_real64, 64,
33273041982dSJonathan Peyton                    KMP_ARCH_X86) // __kmpc_atomic_float8_swp
33287cc577a4SJonathan Peyton #else
33297cc577a4SJonathan Peyton ATOMIC_XCHG_SWP(fixed8, kmp_int64, 64, KMP_ARCH_X86) // __kmpc_atomic_fixed8_swp
33303041982dSJonathan Peyton ATOMIC_XCHG_FLOAT_SWP(float8, kmp_real64, 64,
33313041982dSJonathan Peyton                       KMP_ARCH_X86) // __kmpc_atomic_float8_swp
3332e4b4f994SJonathan Peyton #endif // (KMP_ARCH_X86)
33337cc577a4SJonathan Peyton 
33347cc577a4SJonathan Peyton // ------------------------------------------------------------------------
33353041982dSJonathan Peyton // Routines for Extended types: long double, _Quad, complex flavours (use
33363041982dSJonathan Peyton // critical section)
33377cc577a4SJonathan Peyton #define ATOMIC_CRITICAL_SWP(TYPE_ID, TYPE, LCK_ID, GOMP_FLAG)                  \
33387cc577a4SJonathan Peyton   ATOMIC_BEGIN_SWP(TYPE_ID, TYPE)                                              \
33397cc577a4SJonathan Peyton   TYPE old_value;                                                              \
33407cc577a4SJonathan Peyton   GOMP_CRITICAL_SWP(GOMP_FLAG)                                                 \
33417cc577a4SJonathan Peyton   CRITICAL_SWP(LCK_ID)                                                         \
33427cc577a4SJonathan Peyton   }
33437cc577a4SJonathan Peyton 
33447cc577a4SJonathan Peyton // ------------------------------------------------------------------------
33457cc577a4SJonathan Peyton // !!! TODO: check if we need to return void for cmplx4 routines
33467cc577a4SJonathan Peyton // Workaround for cmplx4. Regular routines with return value don't work
33477cc577a4SJonathan Peyton // on Win_32e. Let's return captured values through the additional parameter.
33487cc577a4SJonathan Peyton 
33497cc577a4SJonathan Peyton #define ATOMIC_BEGIN_SWP_WRK(TYPE_ID, TYPE)                                    \
33503041982dSJonathan Peyton   void __kmpc_atomic_##TYPE_ID##_swp(ident_t *id_ref, int gtid, TYPE *lhs,     \
33513041982dSJonathan Peyton                                      TYPE rhs, TYPE *out) {                    \
33527cc577a4SJonathan Peyton     KMP_DEBUG_ASSERT(__kmp_init_serial);                                       \
33537cc577a4SJonathan Peyton     KA_TRACE(100, ("__kmpc_atomic_" #TYPE_ID "_swp: T#%d\n", gtid));
33547cc577a4SJonathan Peyton 
33557cc577a4SJonathan Peyton #define CRITICAL_SWP_WRK(LCK_ID)                                               \
33567cc577a4SJonathan Peyton   __kmp_acquire_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
33577cc577a4SJonathan Peyton                                                                                \
33587cc577a4SJonathan Peyton   tmp = (*lhs);                                                                \
33597cc577a4SJonathan Peyton   (*lhs) = (rhs);                                                              \
33607cc577a4SJonathan Peyton   (*out) = tmp;                                                                \
33617cc577a4SJonathan Peyton   __kmp_release_atomic_lock(&ATOMIC_LOCK##LCK_ID, gtid);                       \
33627cc577a4SJonathan Peyton   return;
33637cc577a4SJonathan Peyton // ------------------------------------------------------------------------
33647cc577a4SJonathan Peyton 
33657cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
33667cc577a4SJonathan Peyton #define GOMP_CRITICAL_SWP_WRK(FLAG)                                            \
33677cc577a4SJonathan Peyton   if ((FLAG) && (__kmp_atomic_mode == 2)) {                                    \
33687cc577a4SJonathan Peyton     KMP_CHECK_GTID;                                                            \
33697cc577a4SJonathan Peyton     CRITICAL_SWP_WRK(0);                                                       \
33707cc577a4SJonathan Peyton   }
33717cc577a4SJonathan Peyton #else
33727cc577a4SJonathan Peyton #define GOMP_CRITICAL_SWP_WRK(FLAG)
33737cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
33747cc577a4SJonathan Peyton // ------------------------------------------------------------------------
33757cc577a4SJonathan Peyton 
33767cc577a4SJonathan Peyton #define ATOMIC_CRITICAL_SWP_WRK(TYPE_ID, TYPE, LCK_ID, GOMP_FLAG)              \
33777cc577a4SJonathan Peyton   ATOMIC_BEGIN_SWP_WRK(TYPE_ID, TYPE)                                          \
33787cc577a4SJonathan Peyton   TYPE tmp;                                                                    \
33797cc577a4SJonathan Peyton   GOMP_CRITICAL_SWP_WRK(GOMP_FLAG)                                             \
33807cc577a4SJonathan Peyton   CRITICAL_SWP_WRK(LCK_ID)                                                     \
33817cc577a4SJonathan Peyton   }
33827cc577a4SJonathan Peyton // The end of workaround for cmplx4
33837cc577a4SJonathan Peyton 
33847cc577a4SJonathan Peyton ATOMIC_CRITICAL_SWP(float10, long double, 10r, 1) // __kmpc_atomic_float10_swp
33857cc577a4SJonathan Peyton #if KMP_HAVE_QUAD
33867cc577a4SJonathan Peyton ATOMIC_CRITICAL_SWP(float16, QUAD_LEGACY, 16r, 1) // __kmpc_atomic_float16_swp
3387e4b4f994SJonathan Peyton #endif // KMP_HAVE_QUAD
33887cc577a4SJonathan Peyton // cmplx4 routine to return void
33897cc577a4SJonathan Peyton ATOMIC_CRITICAL_SWP_WRK(cmplx4, kmp_cmplx32, 8c, 1) // __kmpc_atomic_cmplx4_swp
33907cc577a4SJonathan Peyton 
33913041982dSJonathan Peyton // ATOMIC_CRITICAL_SWP( cmplx4, kmp_cmplx32,  8c,   1 )           //
33923041982dSJonathan Peyton // __kmpc_atomic_cmplx4_swp
33937cc577a4SJonathan Peyton 
33947cc577a4SJonathan Peyton ATOMIC_CRITICAL_SWP(cmplx8, kmp_cmplx64, 16c, 1) // __kmpc_atomic_cmplx8_swp
33957cc577a4SJonathan Peyton ATOMIC_CRITICAL_SWP(cmplx10, kmp_cmplx80, 20c, 1) // __kmpc_atomic_cmplx10_swp
33967cc577a4SJonathan Peyton #if KMP_HAVE_QUAD
33977cc577a4SJonathan Peyton ATOMIC_CRITICAL_SWP(cmplx16, CPLX128_LEG, 32c, 1) // __kmpc_atomic_cmplx16_swp
33987cc577a4SJonathan Peyton #if (KMP_ARCH_X86)
33993041982dSJonathan Peyton ATOMIC_CRITICAL_SWP(float16_a16, Quad_a16_t, 16r,
34003041982dSJonathan Peyton                     1) // __kmpc_atomic_float16_a16_swp
34013041982dSJonathan Peyton ATOMIC_CRITICAL_SWP(cmplx16_a16, kmp_cmplx128_a16_t, 32c,
34023041982dSJonathan Peyton                     1) // __kmpc_atomic_cmplx16_a16_swp
3403e4b4f994SJonathan Peyton #endif // (KMP_ARCH_X86)
3404e4b4f994SJonathan Peyton #endif // KMP_HAVE_QUAD
34057cc577a4SJonathan Peyton 
34067cc577a4SJonathan Peyton // End of OpenMP 4.0 Capture
34077cc577a4SJonathan Peyton 
34087cc577a4SJonathan Peyton #endif // KMP_ARCH_X86 || KMP_ARCH_X86_64
34097cc577a4SJonathan Peyton 
34107cc577a4SJonathan Peyton #undef OP_CRITICAL
34117cc577a4SJonathan Peyton 
34127cc577a4SJonathan Peyton /* ------------------------------------------------------------------------ */
34137cc577a4SJonathan Peyton /* Generic atomic routines                                                  */
34147cc577a4SJonathan Peyton 
__kmpc_atomic_1(ident_t * id_ref,int gtid,void * lhs,void * rhs,void (* f)(void *,void *,void *))34153041982dSJonathan Peyton void __kmpc_atomic_1(ident_t *id_ref, int gtid, void *lhs, void *rhs,
34163041982dSJonathan Peyton                      void (*f)(void *, void *, void *)) {
34177cc577a4SJonathan Peyton   KMP_DEBUG_ASSERT(__kmp_init_serial);
34187cc577a4SJonathan Peyton 
34197cc577a4SJonathan Peyton   if (
34207cc577a4SJonathan Peyton #if KMP_ARCH_X86 && defined(KMP_GOMP_COMPAT)
34217cc577a4SJonathan Peyton       FALSE /* must use lock */
34227cc577a4SJonathan Peyton #else
34237cc577a4SJonathan Peyton       TRUE
3424e4b4f994SJonathan Peyton #endif // KMP_ARCH_X86 && defined(KMP_GOMP_COMPAT)
34253041982dSJonathan Peyton   ) {
34267cc577a4SJonathan Peyton     kmp_int8 old_value, new_value;
34277cc577a4SJonathan Peyton 
34287cc577a4SJonathan Peyton     old_value = *(kmp_int8 *)lhs;
34297cc577a4SJonathan Peyton     (*f)(&new_value, &old_value, rhs);
34307cc577a4SJonathan Peyton 
34317cc577a4SJonathan Peyton     /* TODO: Should this be acquire or release? */
34323041982dSJonathan Peyton     while (!KMP_COMPARE_AND_STORE_ACQ8((kmp_int8 *)lhs, *(kmp_int8 *)&old_value,
34333041982dSJonathan Peyton                                        *(kmp_int8 *)&new_value)) {
34347cc577a4SJonathan Peyton       KMP_CPU_PAUSE();
34357cc577a4SJonathan Peyton 
34367cc577a4SJonathan Peyton       old_value = *(kmp_int8 *)lhs;
34377cc577a4SJonathan Peyton       (*f)(&new_value, &old_value, rhs);
34387cc577a4SJonathan Peyton     }
34397cc577a4SJonathan Peyton 
34407cc577a4SJonathan Peyton     return;
34413041982dSJonathan Peyton   } else {
34427cc577a4SJonathan Peyton     // All 1-byte data is of integer data type.
34437cc577a4SJonathan Peyton 
34447cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
34457cc577a4SJonathan Peyton     if (__kmp_atomic_mode == 2) {
34467cc577a4SJonathan Peyton       __kmp_acquire_atomic_lock(&__kmp_atomic_lock, gtid);
34473041982dSJonathan Peyton     } else
34487cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
34497cc577a4SJonathan Peyton       __kmp_acquire_atomic_lock(&__kmp_atomic_lock_1i, gtid);
34507cc577a4SJonathan Peyton 
34517cc577a4SJonathan Peyton     (*f)(lhs, lhs, rhs);
34527cc577a4SJonathan Peyton 
34537cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
34547cc577a4SJonathan Peyton     if (__kmp_atomic_mode == 2) {
34557cc577a4SJonathan Peyton       __kmp_release_atomic_lock(&__kmp_atomic_lock, gtid);
34563041982dSJonathan Peyton     } else
34577cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
34587cc577a4SJonathan Peyton       __kmp_release_atomic_lock(&__kmp_atomic_lock_1i, gtid);
34597cc577a4SJonathan Peyton   }
34607cc577a4SJonathan Peyton }
34617cc577a4SJonathan Peyton 
__kmpc_atomic_2(ident_t * id_ref,int gtid,void * lhs,void * rhs,void (* f)(void *,void *,void *))34623041982dSJonathan Peyton void __kmpc_atomic_2(ident_t *id_ref, int gtid, void *lhs, void *rhs,
34633041982dSJonathan Peyton                      void (*f)(void *, void *, void *)) {
34647cc577a4SJonathan Peyton   if (
34657cc577a4SJonathan Peyton #if KMP_ARCH_X86 && defined(KMP_GOMP_COMPAT)
34667cc577a4SJonathan Peyton       FALSE /* must use lock */
34677cc577a4SJonathan Peyton #elif KMP_ARCH_X86 || KMP_ARCH_X86_64
34687cc577a4SJonathan Peyton       TRUE /* no alignment problems */
34697cc577a4SJonathan Peyton #else
34707cc577a4SJonathan Peyton       !((kmp_uintptr_t)lhs & 0x1) /* make sure address is 2-byte aligned */
3471e4b4f994SJonathan Peyton #endif // KMP_ARCH_X86 && defined(KMP_GOMP_COMPAT)
34723041982dSJonathan Peyton   ) {
34737cc577a4SJonathan Peyton     kmp_int16 old_value, new_value;
34747cc577a4SJonathan Peyton 
34757cc577a4SJonathan Peyton     old_value = *(kmp_int16 *)lhs;
34767cc577a4SJonathan Peyton     (*f)(&new_value, &old_value, rhs);
34777cc577a4SJonathan Peyton 
34787cc577a4SJonathan Peyton     /* TODO: Should this be acquire or release? */
34793041982dSJonathan Peyton     while (!KMP_COMPARE_AND_STORE_ACQ16(
34803041982dSJonathan Peyton         (kmp_int16 *)lhs, *(kmp_int16 *)&old_value, *(kmp_int16 *)&new_value)) {
34817cc577a4SJonathan Peyton       KMP_CPU_PAUSE();
34827cc577a4SJonathan Peyton 
34837cc577a4SJonathan Peyton       old_value = *(kmp_int16 *)lhs;
34847cc577a4SJonathan Peyton       (*f)(&new_value, &old_value, rhs);
34857cc577a4SJonathan Peyton     }
34867cc577a4SJonathan Peyton 
34877cc577a4SJonathan Peyton     return;
34883041982dSJonathan Peyton   } else {
34897cc577a4SJonathan Peyton     // All 2-byte data is of integer data type.
34907cc577a4SJonathan Peyton 
34917cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
34927cc577a4SJonathan Peyton     if (__kmp_atomic_mode == 2) {
34937cc577a4SJonathan Peyton       __kmp_acquire_atomic_lock(&__kmp_atomic_lock, gtid);
34943041982dSJonathan Peyton     } else
34957cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
34967cc577a4SJonathan Peyton       __kmp_acquire_atomic_lock(&__kmp_atomic_lock_2i, gtid);
34977cc577a4SJonathan Peyton 
34987cc577a4SJonathan Peyton     (*f)(lhs, lhs, rhs);
34997cc577a4SJonathan Peyton 
35007cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
35017cc577a4SJonathan Peyton     if (__kmp_atomic_mode == 2) {
35027cc577a4SJonathan Peyton       __kmp_release_atomic_lock(&__kmp_atomic_lock, gtid);
35033041982dSJonathan Peyton     } else
35047cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
35057cc577a4SJonathan Peyton       __kmp_release_atomic_lock(&__kmp_atomic_lock_2i, gtid);
35067cc577a4SJonathan Peyton   }
35077cc577a4SJonathan Peyton }
35087cc577a4SJonathan Peyton 
__kmpc_atomic_4(ident_t * id_ref,int gtid,void * lhs,void * rhs,void (* f)(void *,void *,void *))35093041982dSJonathan Peyton void __kmpc_atomic_4(ident_t *id_ref, int gtid, void *lhs, void *rhs,
35103041982dSJonathan Peyton                      void (*f)(void *, void *, void *)) {
35117cc577a4SJonathan Peyton   KMP_DEBUG_ASSERT(__kmp_init_serial);
35127cc577a4SJonathan Peyton 
35137cc577a4SJonathan Peyton   if (
35147cc577a4SJonathan Peyton // FIXME: On IA-32 architecture, gcc uses cmpxchg only for 4-byte ints.
35157cc577a4SJonathan Peyton // Gomp compatibility is broken if this routine is called for floats.
35167cc577a4SJonathan Peyton #if KMP_ARCH_X86 || KMP_ARCH_X86_64
35177cc577a4SJonathan Peyton       TRUE /* no alignment problems */
35187cc577a4SJonathan Peyton #else
35197cc577a4SJonathan Peyton       !((kmp_uintptr_t)lhs & 0x3) /* make sure address is 4-byte aligned */
3520e4b4f994SJonathan Peyton #endif // KMP_ARCH_X86 || KMP_ARCH_X86_64
35213041982dSJonathan Peyton   ) {
35227cc577a4SJonathan Peyton     kmp_int32 old_value, new_value;
35237cc577a4SJonathan Peyton 
35247cc577a4SJonathan Peyton     old_value = *(kmp_int32 *)lhs;
35257cc577a4SJonathan Peyton     (*f)(&new_value, &old_value, rhs);
35267cc577a4SJonathan Peyton 
35277cc577a4SJonathan Peyton     /* TODO: Should this be acquire or release? */
35283041982dSJonathan Peyton     while (!KMP_COMPARE_AND_STORE_ACQ32(
35293041982dSJonathan Peyton         (kmp_int32 *)lhs, *(kmp_int32 *)&old_value, *(kmp_int32 *)&new_value)) {
35307cc577a4SJonathan Peyton       KMP_CPU_PAUSE();
35317cc577a4SJonathan Peyton 
35327cc577a4SJonathan Peyton       old_value = *(kmp_int32 *)lhs;
35337cc577a4SJonathan Peyton       (*f)(&new_value, &old_value, rhs);
35347cc577a4SJonathan Peyton     }
35357cc577a4SJonathan Peyton 
35367cc577a4SJonathan Peyton     return;
35373041982dSJonathan Peyton   } else {
35387cc577a4SJonathan Peyton     // Use __kmp_atomic_lock_4i for all 4-byte data,
35397cc577a4SJonathan Peyton     // even if it isn't of integer data type.
35407cc577a4SJonathan Peyton 
35417cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
35427cc577a4SJonathan Peyton     if (__kmp_atomic_mode == 2) {
35437cc577a4SJonathan Peyton       __kmp_acquire_atomic_lock(&__kmp_atomic_lock, gtid);
35443041982dSJonathan Peyton     } else
35457cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
35467cc577a4SJonathan Peyton       __kmp_acquire_atomic_lock(&__kmp_atomic_lock_4i, gtid);
35477cc577a4SJonathan Peyton 
35487cc577a4SJonathan Peyton     (*f)(lhs, lhs, rhs);
35497cc577a4SJonathan Peyton 
35507cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
35517cc577a4SJonathan Peyton     if (__kmp_atomic_mode == 2) {
35527cc577a4SJonathan Peyton       __kmp_release_atomic_lock(&__kmp_atomic_lock, gtid);
35533041982dSJonathan Peyton     } else
35547cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
35557cc577a4SJonathan Peyton       __kmp_release_atomic_lock(&__kmp_atomic_lock_4i, gtid);
35567cc577a4SJonathan Peyton   }
35577cc577a4SJonathan Peyton }
35587cc577a4SJonathan Peyton 
__kmpc_atomic_8(ident_t * id_ref,int gtid,void * lhs,void * rhs,void (* f)(void *,void *,void *))35593041982dSJonathan Peyton void __kmpc_atomic_8(ident_t *id_ref, int gtid, void *lhs, void *rhs,
35603041982dSJonathan Peyton                      void (*f)(void *, void *, void *)) {
35617cc577a4SJonathan Peyton   KMP_DEBUG_ASSERT(__kmp_init_serial);
35627cc577a4SJonathan Peyton   if (
35637cc577a4SJonathan Peyton 
35647cc577a4SJonathan Peyton #if KMP_ARCH_X86 && defined(KMP_GOMP_COMPAT)
35657cc577a4SJonathan Peyton       FALSE /* must use lock */
35667cc577a4SJonathan Peyton #elif KMP_ARCH_X86 || KMP_ARCH_X86_64
35677cc577a4SJonathan Peyton       TRUE /* no alignment problems */
35687cc577a4SJonathan Peyton #else
35697cc577a4SJonathan Peyton       !((kmp_uintptr_t)lhs & 0x7) /* make sure address is 8-byte aligned */
3570e4b4f994SJonathan Peyton #endif // KMP_ARCH_X86 && defined(KMP_GOMP_COMPAT)
35713041982dSJonathan Peyton   ) {
35727cc577a4SJonathan Peyton     kmp_int64 old_value, new_value;
35737cc577a4SJonathan Peyton 
35747cc577a4SJonathan Peyton     old_value = *(kmp_int64 *)lhs;
35757cc577a4SJonathan Peyton     (*f)(&new_value, &old_value, rhs);
35767cc577a4SJonathan Peyton     /* TODO: Should this be acquire or release? */
35773041982dSJonathan Peyton     while (!KMP_COMPARE_AND_STORE_ACQ64(
35783041982dSJonathan Peyton         (kmp_int64 *)lhs, *(kmp_int64 *)&old_value, *(kmp_int64 *)&new_value)) {
35797cc577a4SJonathan Peyton       KMP_CPU_PAUSE();
35807cc577a4SJonathan Peyton 
35817cc577a4SJonathan Peyton       old_value = *(kmp_int64 *)lhs;
35827cc577a4SJonathan Peyton       (*f)(&new_value, &old_value, rhs);
35837cc577a4SJonathan Peyton     }
35847cc577a4SJonathan Peyton 
35857cc577a4SJonathan Peyton     return;
35867cc577a4SJonathan Peyton   } else {
35877cc577a4SJonathan Peyton     // Use __kmp_atomic_lock_8i for all 8-byte data,
35887cc577a4SJonathan Peyton     // even if it isn't of integer data type.
35897cc577a4SJonathan Peyton 
35907cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
35917cc577a4SJonathan Peyton     if (__kmp_atomic_mode == 2) {
35927cc577a4SJonathan Peyton       __kmp_acquire_atomic_lock(&__kmp_atomic_lock, gtid);
35933041982dSJonathan Peyton     } else
35947cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
35957cc577a4SJonathan Peyton       __kmp_acquire_atomic_lock(&__kmp_atomic_lock_8i, gtid);
35967cc577a4SJonathan Peyton 
35977cc577a4SJonathan Peyton     (*f)(lhs, lhs, rhs);
35987cc577a4SJonathan Peyton 
35997cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
36007cc577a4SJonathan Peyton     if (__kmp_atomic_mode == 2) {
36017cc577a4SJonathan Peyton       __kmp_release_atomic_lock(&__kmp_atomic_lock, gtid);
36023041982dSJonathan Peyton     } else
36037cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
36047cc577a4SJonathan Peyton       __kmp_release_atomic_lock(&__kmp_atomic_lock_8i, gtid);
36057cc577a4SJonathan Peyton   }
36067cc577a4SJonathan Peyton }
3607c1988dbfSMalhar Jajoo #if KMP_ARCH_X86 || KMP_ARCH_X86_64
__kmpc_atomic_10(ident_t * id_ref,int gtid,void * lhs,void * rhs,void (* f)(void *,void *,void *))36083041982dSJonathan Peyton void __kmpc_atomic_10(ident_t *id_ref, int gtid, void *lhs, void *rhs,
36093041982dSJonathan Peyton                       void (*f)(void *, void *, void *)) {
36107cc577a4SJonathan Peyton   KMP_DEBUG_ASSERT(__kmp_init_serial);
36117cc577a4SJonathan Peyton 
36127cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
36137cc577a4SJonathan Peyton   if (__kmp_atomic_mode == 2) {
36147cc577a4SJonathan Peyton     __kmp_acquire_atomic_lock(&__kmp_atomic_lock, gtid);
36153041982dSJonathan Peyton   } else
36167cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
36177cc577a4SJonathan Peyton     __kmp_acquire_atomic_lock(&__kmp_atomic_lock_10r, gtid);
36187cc577a4SJonathan Peyton 
36197cc577a4SJonathan Peyton   (*f)(lhs, lhs, rhs);
36207cc577a4SJonathan Peyton 
36217cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
36227cc577a4SJonathan Peyton   if (__kmp_atomic_mode == 2) {
36237cc577a4SJonathan Peyton     __kmp_release_atomic_lock(&__kmp_atomic_lock, gtid);
36243041982dSJonathan Peyton   } else
36257cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
36267cc577a4SJonathan Peyton     __kmp_release_atomic_lock(&__kmp_atomic_lock_10r, gtid);
36277cc577a4SJonathan Peyton }
3628c1988dbfSMalhar Jajoo #endif // KMP_ARCH_X86 || KMP_ARCH_X86_64
36297cc577a4SJonathan Peyton 
__kmpc_atomic_16(ident_t * id_ref,int gtid,void * lhs,void * rhs,void (* f)(void *,void *,void *))36303041982dSJonathan Peyton void __kmpc_atomic_16(ident_t *id_ref, int gtid, void *lhs, void *rhs,
36313041982dSJonathan Peyton                       void (*f)(void *, void *, void *)) {
36327cc577a4SJonathan Peyton   KMP_DEBUG_ASSERT(__kmp_init_serial);
36337cc577a4SJonathan Peyton 
36347cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
36357cc577a4SJonathan Peyton   if (__kmp_atomic_mode == 2) {
36367cc577a4SJonathan Peyton     __kmp_acquire_atomic_lock(&__kmp_atomic_lock, gtid);
36373041982dSJonathan Peyton   } else
36387cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
36397cc577a4SJonathan Peyton     __kmp_acquire_atomic_lock(&__kmp_atomic_lock_16c, gtid);
36407cc577a4SJonathan Peyton 
36417cc577a4SJonathan Peyton   (*f)(lhs, lhs, rhs);
36427cc577a4SJonathan Peyton 
36437cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
36447cc577a4SJonathan Peyton   if (__kmp_atomic_mode == 2) {
36457cc577a4SJonathan Peyton     __kmp_release_atomic_lock(&__kmp_atomic_lock, gtid);
36463041982dSJonathan Peyton   } else
36477cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
36487cc577a4SJonathan Peyton     __kmp_release_atomic_lock(&__kmp_atomic_lock_16c, gtid);
36497cc577a4SJonathan Peyton }
3650c1988dbfSMalhar Jajoo #if KMP_ARCH_X86 || KMP_ARCH_X86_64
__kmpc_atomic_20(ident_t * id_ref,int gtid,void * lhs,void * rhs,void (* f)(void *,void *,void *))36513041982dSJonathan Peyton void __kmpc_atomic_20(ident_t *id_ref, int gtid, void *lhs, void *rhs,
36523041982dSJonathan Peyton                       void (*f)(void *, void *, void *)) {
36537cc577a4SJonathan Peyton   KMP_DEBUG_ASSERT(__kmp_init_serial);
36547cc577a4SJonathan Peyton 
36557cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
36567cc577a4SJonathan Peyton   if (__kmp_atomic_mode == 2) {
36577cc577a4SJonathan Peyton     __kmp_acquire_atomic_lock(&__kmp_atomic_lock, gtid);
36583041982dSJonathan Peyton   } else
36597cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
36607cc577a4SJonathan Peyton     __kmp_acquire_atomic_lock(&__kmp_atomic_lock_20c, gtid);
36617cc577a4SJonathan Peyton 
36627cc577a4SJonathan Peyton   (*f)(lhs, lhs, rhs);
36637cc577a4SJonathan Peyton 
36647cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
36657cc577a4SJonathan Peyton   if (__kmp_atomic_mode == 2) {
36667cc577a4SJonathan Peyton     __kmp_release_atomic_lock(&__kmp_atomic_lock, gtid);
36673041982dSJonathan Peyton   } else
36687cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
36697cc577a4SJonathan Peyton     __kmp_release_atomic_lock(&__kmp_atomic_lock_20c, gtid);
36707cc577a4SJonathan Peyton }
3671c1988dbfSMalhar Jajoo #endif // KMP_ARCH_X86 || KMP_ARCH_X86_64
__kmpc_atomic_32(ident_t * id_ref,int gtid,void * lhs,void * rhs,void (* f)(void *,void *,void *))36723041982dSJonathan Peyton void __kmpc_atomic_32(ident_t *id_ref, int gtid, void *lhs, void *rhs,
36733041982dSJonathan Peyton                       void (*f)(void *, void *, void *)) {
36747cc577a4SJonathan Peyton   KMP_DEBUG_ASSERT(__kmp_init_serial);
36757cc577a4SJonathan Peyton 
36767cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
36777cc577a4SJonathan Peyton   if (__kmp_atomic_mode == 2) {
36787cc577a4SJonathan Peyton     __kmp_acquire_atomic_lock(&__kmp_atomic_lock, gtid);
36793041982dSJonathan Peyton   } else
36807cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
36817cc577a4SJonathan Peyton     __kmp_acquire_atomic_lock(&__kmp_atomic_lock_32c, gtid);
36827cc577a4SJonathan Peyton 
36837cc577a4SJonathan Peyton   (*f)(lhs, lhs, rhs);
36847cc577a4SJonathan Peyton 
36857cc577a4SJonathan Peyton #ifdef KMP_GOMP_COMPAT
36867cc577a4SJonathan Peyton   if (__kmp_atomic_mode == 2) {
36877cc577a4SJonathan Peyton     __kmp_release_atomic_lock(&__kmp_atomic_lock, gtid);
36883041982dSJonathan Peyton   } else
36897cc577a4SJonathan Peyton #endif /* KMP_GOMP_COMPAT */
36907cc577a4SJonathan Peyton     __kmp_release_atomic_lock(&__kmp_atomic_lock_32c, gtid);
36917cc577a4SJonathan Peyton }
36927cc577a4SJonathan Peyton 
36933041982dSJonathan Peyton // AC: same two routines as GOMP_atomic_start/end, but will be called by our
36943041982dSJonathan Peyton // compiler; duplicated in order to not use 3-party names in pure Intel code
36957cc577a4SJonathan Peyton // TODO: consider adding GTID parameter after consultation with Ernesto/Xinmin.
__kmpc_atomic_start(void)36963041982dSJonathan Peyton void __kmpc_atomic_start(void) {
36977cc577a4SJonathan Peyton   int gtid = __kmp_entry_gtid();
36987cc577a4SJonathan Peyton   KA_TRACE(20, ("__kmpc_atomic_start: T#%d\n", gtid));
36997cc577a4SJonathan Peyton   __kmp_acquire_atomic_lock(&__kmp_atomic_lock, gtid);
37007cc577a4SJonathan Peyton }
37017cc577a4SJonathan Peyton 
__kmpc_atomic_end(void)37023041982dSJonathan Peyton void __kmpc_atomic_end(void) {
37037cc577a4SJonathan Peyton   int gtid = __kmp_get_gtid();
37047cc577a4SJonathan Peyton   KA_TRACE(20, ("__kmpc_atomic_end: T#%d\n", gtid));
37057cc577a4SJonathan Peyton   __kmp_release_atomic_lock(&__kmp_atomic_lock, gtid);
37067cc577a4SJonathan Peyton }
37077cc577a4SJonathan Peyton 
3708e38a1debSAndreyChurbanov #if KMP_ARCH_X86 || KMP_ARCH_X86_64
3709e38a1debSAndreyChurbanov 
3710621d7a75SAndreyChurbanov // OpenMP 5.1 compare and swap
3711621d7a75SAndreyChurbanov 
3712621d7a75SAndreyChurbanov /*!
3713621d7a75SAndreyChurbanov @param loc Source code location
3714621d7a75SAndreyChurbanov @param gtid Global thread id
3715621d7a75SAndreyChurbanov @param x Memory location to operate on
3716621d7a75SAndreyChurbanov @param e Expected value
3717621d7a75SAndreyChurbanov @param d Desired value
3718621d7a75SAndreyChurbanov @return Result of comparison
3719621d7a75SAndreyChurbanov 
3720621d7a75SAndreyChurbanov Implements Compare And Swap atomic operation.
3721621d7a75SAndreyChurbanov 
3722621d7a75SAndreyChurbanov Sample code:
3723621d7a75SAndreyChurbanov #pragma omp atomic compare update capture
3724621d7a75SAndreyChurbanov   { r = x == e; if(r) { x = d; } }
3725621d7a75SAndreyChurbanov */
__kmpc_atomic_bool_1_cas(ident_t * loc,int gtid,char * x,char e,char d)3726621d7a75SAndreyChurbanov bool __kmpc_atomic_bool_1_cas(ident_t *loc, int gtid, char *x, char e, char d) {
3727621d7a75SAndreyChurbanov   return KMP_COMPARE_AND_STORE_ACQ8(x, e, d);
3728621d7a75SAndreyChurbanov }
__kmpc_atomic_bool_2_cas(ident_t * loc,int gtid,short * x,short e,short d)3729621d7a75SAndreyChurbanov bool __kmpc_atomic_bool_2_cas(ident_t *loc, int gtid, short *x, short e,
3730621d7a75SAndreyChurbanov                               short d) {
3731621d7a75SAndreyChurbanov   return KMP_COMPARE_AND_STORE_ACQ16(x, e, d);
3732621d7a75SAndreyChurbanov }
__kmpc_atomic_bool_4_cas(ident_t * loc,int gtid,kmp_int32 * x,kmp_int32 e,kmp_int32 d)3733621d7a75SAndreyChurbanov bool __kmpc_atomic_bool_4_cas(ident_t *loc, int gtid, kmp_int32 *x, kmp_int32 e,
3734621d7a75SAndreyChurbanov                               kmp_int32 d) {
3735621d7a75SAndreyChurbanov   return KMP_COMPARE_AND_STORE_ACQ32(x, e, d);
3736621d7a75SAndreyChurbanov }
__kmpc_atomic_bool_8_cas(ident_t * loc,int gtid,kmp_int64 * x,kmp_int64 e,kmp_int64 d)3737621d7a75SAndreyChurbanov bool __kmpc_atomic_bool_8_cas(ident_t *loc, int gtid, kmp_int64 *x, kmp_int64 e,
3738621d7a75SAndreyChurbanov                               kmp_int64 d) {
3739621d7a75SAndreyChurbanov   return KMP_COMPARE_AND_STORE_ACQ64(x, e, d);
3740621d7a75SAndreyChurbanov }
3741621d7a75SAndreyChurbanov 
3742621d7a75SAndreyChurbanov /*!
3743621d7a75SAndreyChurbanov @param loc Source code location
3744621d7a75SAndreyChurbanov @param gtid Global thread id
3745621d7a75SAndreyChurbanov @param x Memory location to operate on
3746621d7a75SAndreyChurbanov @param e Expected value
3747621d7a75SAndreyChurbanov @param d Desired value
3748621d7a75SAndreyChurbanov @return Old value of x
3749621d7a75SAndreyChurbanov 
3750621d7a75SAndreyChurbanov Implements Compare And Swap atomic operation.
3751621d7a75SAndreyChurbanov 
3752621d7a75SAndreyChurbanov Sample code:
3753621d7a75SAndreyChurbanov #pragma omp atomic compare update capture
3754621d7a75SAndreyChurbanov   { v = x; if (x == e) { x = d; } }
3755621d7a75SAndreyChurbanov */
__kmpc_atomic_val_1_cas(ident_t * loc,int gtid,char * x,char e,char d)3756621d7a75SAndreyChurbanov char __kmpc_atomic_val_1_cas(ident_t *loc, int gtid, char *x, char e, char d) {
3757621d7a75SAndreyChurbanov   return KMP_COMPARE_AND_STORE_RET8(x, e, d);
3758621d7a75SAndreyChurbanov }
__kmpc_atomic_val_2_cas(ident_t * loc,int gtid,short * x,short e,short d)3759621d7a75SAndreyChurbanov short __kmpc_atomic_val_2_cas(ident_t *loc, int gtid, short *x, short e,
3760621d7a75SAndreyChurbanov                               short d) {
3761621d7a75SAndreyChurbanov   return KMP_COMPARE_AND_STORE_RET16(x, e, d);
3762621d7a75SAndreyChurbanov }
__kmpc_atomic_val_4_cas(ident_t * loc,int gtid,kmp_int32 * x,kmp_int32 e,kmp_int32 d)3763621d7a75SAndreyChurbanov kmp_int32 __kmpc_atomic_val_4_cas(ident_t *loc, int gtid, kmp_int32 *x,
3764621d7a75SAndreyChurbanov                                   kmp_int32 e, kmp_int32 d) {
3765621d7a75SAndreyChurbanov   return KMP_COMPARE_AND_STORE_RET32(x, e, d);
3766621d7a75SAndreyChurbanov }
__kmpc_atomic_val_8_cas(ident_t * loc,int gtid,kmp_int64 * x,kmp_int64 e,kmp_int64 d)3767621d7a75SAndreyChurbanov kmp_int64 __kmpc_atomic_val_8_cas(ident_t *loc, int gtid, kmp_int64 *x,
3768621d7a75SAndreyChurbanov                                   kmp_int64 e, kmp_int64 d) {
3769621d7a75SAndreyChurbanov   return KMP_COMPARE_AND_STORE_RET64(x, e, d);
3770621d7a75SAndreyChurbanov }
3771621d7a75SAndreyChurbanov 
3772621d7a75SAndreyChurbanov /*!
3773621d7a75SAndreyChurbanov @param loc Source code location
3774621d7a75SAndreyChurbanov @param gtid Global thread id
3775621d7a75SAndreyChurbanov @param x Memory location to operate on
3776621d7a75SAndreyChurbanov @param e Expected value
3777621d7a75SAndreyChurbanov @param d Desired value
3778621d7a75SAndreyChurbanov @param pv Captured value location
3779621d7a75SAndreyChurbanov @return Result of comparison
3780621d7a75SAndreyChurbanov 
3781621d7a75SAndreyChurbanov Implements Compare And Swap + Capture atomic operation.
3782621d7a75SAndreyChurbanov 
3783621d7a75SAndreyChurbanov v gets old valie of x if comparison failed, untouched otherwise.
3784621d7a75SAndreyChurbanov Sample code:
3785621d7a75SAndreyChurbanov #pragma omp atomic compare update capture
3786621d7a75SAndreyChurbanov   { r = x == e; if(r) { x = d; } else { v = x; } }
3787621d7a75SAndreyChurbanov */
__kmpc_atomic_bool_1_cas_cpt(ident_t * loc,int gtid,char * x,char e,char d,char * pv)3788621d7a75SAndreyChurbanov bool __kmpc_atomic_bool_1_cas_cpt(ident_t *loc, int gtid, char *x, char e,
3789621d7a75SAndreyChurbanov                                   char d, char *pv) {
3790621d7a75SAndreyChurbanov   char old = KMP_COMPARE_AND_STORE_RET8(x, e, d);
3791621d7a75SAndreyChurbanov   if (old == e)
3792621d7a75SAndreyChurbanov     return true;
3793621d7a75SAndreyChurbanov   KMP_ASSERT(pv != NULL);
3794621d7a75SAndreyChurbanov   *pv = old;
3795621d7a75SAndreyChurbanov   return false;
3796621d7a75SAndreyChurbanov }
__kmpc_atomic_bool_2_cas_cpt(ident_t * loc,int gtid,short * x,short e,short d,short * pv)3797621d7a75SAndreyChurbanov bool __kmpc_atomic_bool_2_cas_cpt(ident_t *loc, int gtid, short *x, short e,
3798621d7a75SAndreyChurbanov                                   short d, short *pv) {
3799621d7a75SAndreyChurbanov   short old = KMP_COMPARE_AND_STORE_RET16(x, e, d);
3800621d7a75SAndreyChurbanov   if (old == e)
3801621d7a75SAndreyChurbanov     return true;
3802621d7a75SAndreyChurbanov   KMP_ASSERT(pv != NULL);
3803621d7a75SAndreyChurbanov   *pv = old;
3804621d7a75SAndreyChurbanov   return false;
3805621d7a75SAndreyChurbanov }
__kmpc_atomic_bool_4_cas_cpt(ident_t * loc,int gtid,kmp_int32 * x,kmp_int32 e,kmp_int32 d,kmp_int32 * pv)3806621d7a75SAndreyChurbanov bool __kmpc_atomic_bool_4_cas_cpt(ident_t *loc, int gtid, kmp_int32 *x,
3807621d7a75SAndreyChurbanov                                   kmp_int32 e, kmp_int32 d, kmp_int32 *pv) {
3808621d7a75SAndreyChurbanov   kmp_int32 old = KMP_COMPARE_AND_STORE_RET32(x, e, d);
3809621d7a75SAndreyChurbanov   if (old == e)
3810621d7a75SAndreyChurbanov     return true;
3811621d7a75SAndreyChurbanov   KMP_ASSERT(pv != NULL);
3812621d7a75SAndreyChurbanov   *pv = old;
3813621d7a75SAndreyChurbanov   return false;
3814621d7a75SAndreyChurbanov }
__kmpc_atomic_bool_8_cas_cpt(ident_t * loc,int gtid,kmp_int64 * x,kmp_int64 e,kmp_int64 d,kmp_int64 * pv)3815621d7a75SAndreyChurbanov bool __kmpc_atomic_bool_8_cas_cpt(ident_t *loc, int gtid, kmp_int64 *x,
3816621d7a75SAndreyChurbanov                                   kmp_int64 e, kmp_int64 d, kmp_int64 *pv) {
3817621d7a75SAndreyChurbanov   kmp_int64 old = KMP_COMPARE_AND_STORE_RET64(x, e, d);
3818621d7a75SAndreyChurbanov   if (old == e)
3819621d7a75SAndreyChurbanov     return true;
3820621d7a75SAndreyChurbanov   KMP_ASSERT(pv != NULL);
3821621d7a75SAndreyChurbanov   *pv = old;
3822621d7a75SAndreyChurbanov   return false;
3823621d7a75SAndreyChurbanov }
3824621d7a75SAndreyChurbanov 
3825621d7a75SAndreyChurbanov /*!
3826621d7a75SAndreyChurbanov @param loc Source code location
3827621d7a75SAndreyChurbanov @param gtid Global thread id
3828621d7a75SAndreyChurbanov @param x Memory location to operate on
3829621d7a75SAndreyChurbanov @param e Expected value
3830621d7a75SAndreyChurbanov @param d Desired value
3831621d7a75SAndreyChurbanov @param pv Captured value location
3832621d7a75SAndreyChurbanov @return Old value of x
3833621d7a75SAndreyChurbanov 
3834621d7a75SAndreyChurbanov Implements Compare And Swap + Capture atomic operation.
3835621d7a75SAndreyChurbanov 
3836621d7a75SAndreyChurbanov v gets new valie of x.
3837621d7a75SAndreyChurbanov Sample code:
3838621d7a75SAndreyChurbanov #pragma omp atomic compare update capture
3839621d7a75SAndreyChurbanov   { if (x == e) { x = d; }; v = x; }
3840621d7a75SAndreyChurbanov */
__kmpc_atomic_val_1_cas_cpt(ident_t * loc,int gtid,char * x,char e,char d,char * pv)3841621d7a75SAndreyChurbanov char __kmpc_atomic_val_1_cas_cpt(ident_t *loc, int gtid, char *x, char e,
3842621d7a75SAndreyChurbanov                                  char d, char *pv) {
3843621d7a75SAndreyChurbanov   char old = KMP_COMPARE_AND_STORE_RET8(x, e, d);
3844621d7a75SAndreyChurbanov   KMP_ASSERT(pv != NULL);
3845621d7a75SAndreyChurbanov   *pv = old == e ? d : old;
3846621d7a75SAndreyChurbanov   return old;
3847621d7a75SAndreyChurbanov }
__kmpc_atomic_val_2_cas_cpt(ident_t * loc,int gtid,short * x,short e,short d,short * pv)3848621d7a75SAndreyChurbanov short __kmpc_atomic_val_2_cas_cpt(ident_t *loc, int gtid, short *x, short e,
3849621d7a75SAndreyChurbanov                                   short d, short *pv) {
3850621d7a75SAndreyChurbanov   short old = KMP_COMPARE_AND_STORE_RET16(x, e, d);
3851621d7a75SAndreyChurbanov   KMP_ASSERT(pv != NULL);
3852621d7a75SAndreyChurbanov   *pv = old == e ? d : old;
3853621d7a75SAndreyChurbanov   return old;
3854621d7a75SAndreyChurbanov }
__kmpc_atomic_val_4_cas_cpt(ident_t * loc,int gtid,kmp_int32 * x,kmp_int32 e,kmp_int32 d,kmp_int32 * pv)3855621d7a75SAndreyChurbanov kmp_int32 __kmpc_atomic_val_4_cas_cpt(ident_t *loc, int gtid, kmp_int32 *x,
3856621d7a75SAndreyChurbanov                                       kmp_int32 e, kmp_int32 d, kmp_int32 *pv) {
3857621d7a75SAndreyChurbanov   kmp_int32 old = KMP_COMPARE_AND_STORE_RET32(x, e, d);
3858621d7a75SAndreyChurbanov   KMP_ASSERT(pv != NULL);
3859621d7a75SAndreyChurbanov   *pv = old == e ? d : old;
3860621d7a75SAndreyChurbanov   return old;
3861621d7a75SAndreyChurbanov }
__kmpc_atomic_val_8_cas_cpt(ident_t * loc,int gtid,kmp_int64 * x,kmp_int64 e,kmp_int64 d,kmp_int64 * pv)3862621d7a75SAndreyChurbanov kmp_int64 __kmpc_atomic_val_8_cas_cpt(ident_t *loc, int gtid, kmp_int64 *x,
3863621d7a75SAndreyChurbanov                                       kmp_int64 e, kmp_int64 d, kmp_int64 *pv) {
3864621d7a75SAndreyChurbanov   kmp_int64 old = KMP_COMPARE_AND_STORE_RET64(x, e, d);
3865621d7a75SAndreyChurbanov   KMP_ASSERT(pv != NULL);
3866621d7a75SAndreyChurbanov   *pv = old == e ? d : old;
3867621d7a75SAndreyChurbanov   return old;
3868621d7a75SAndreyChurbanov }
3869621d7a75SAndreyChurbanov 
3870621d7a75SAndreyChurbanov // End OpenMP 5.1 compare + capture
3871e38a1debSAndreyChurbanov #endif // KMP_ARCH_X86 || KMP_ARCH_X86_64
3872621d7a75SAndreyChurbanov 
38737cc577a4SJonathan Peyton /*!
38747cc577a4SJonathan Peyton @}
38757cc577a4SJonathan Peyton */
38767cc577a4SJonathan Peyton 
38777cc577a4SJonathan Peyton // end of file
3878