37 #include "kmp_atomic.h"
40 typedef unsigned char uchar;
41 typedef unsigned short ushort;
564 #ifndef KMP_GOMP_COMPAT
565 int __kmp_atomic_mode = 1;
567 int __kmp_atomic_mode = 2;
572 kmp_atomic_lock_t __kmp_atomic_lock;
573 kmp_atomic_lock_t __kmp_atomic_lock_1i;
574 kmp_atomic_lock_t __kmp_atomic_lock_2i;
575 kmp_atomic_lock_t __kmp_atomic_lock_4i;
576 kmp_atomic_lock_t __kmp_atomic_lock_4r;
577 kmp_atomic_lock_t __kmp_atomic_lock_8i;
578 kmp_atomic_lock_t __kmp_atomic_lock_8r;
579 kmp_atomic_lock_t __kmp_atomic_lock_8c;
580 kmp_atomic_lock_t __kmp_atomic_lock_10r;
581 kmp_atomic_lock_t __kmp_atomic_lock_16r;
582 kmp_atomic_lock_t __kmp_atomic_lock_16c;
583 kmp_atomic_lock_t __kmp_atomic_lock_20c;
584 kmp_atomic_lock_t __kmp_atomic_lock_32c;
594 #define KMP_ATOMIC_VOLATILE volatile
598 static inline void operator +=( Quad_a4_t & lhs, Quad_a4_t & rhs ) { lhs.q += rhs.q; };
599 static inline void operator -=( Quad_a4_t & lhs, Quad_a4_t & rhs ) { lhs.q -= rhs.q; };
600 static inline void operator *=( Quad_a4_t & lhs, Quad_a4_t & rhs ) { lhs.q *= rhs.q; };
601 static inline void operator /=( Quad_a4_t & lhs, Quad_a4_t & rhs ) { lhs.q /= rhs.q; };
602 static inline bool operator < ( Quad_a4_t & lhs, Quad_a4_t & rhs ) {
return lhs.q < rhs.q; }
603 static inline bool operator > ( Quad_a4_t & lhs, Quad_a4_t & rhs ) {
return lhs.q > rhs.q; }
605 static inline void operator +=( Quad_a16_t & lhs, Quad_a16_t & rhs ) { lhs.q += rhs.q; };
606 static inline void operator -=( Quad_a16_t & lhs, Quad_a16_t & rhs ) { lhs.q -= rhs.q; };
607 static inline void operator *=( Quad_a16_t & lhs, Quad_a16_t & rhs ) { lhs.q *= rhs.q; };
608 static inline void operator /=( Quad_a16_t & lhs, Quad_a16_t & rhs ) { lhs.q /= rhs.q; };
609 static inline bool operator < ( Quad_a16_t & lhs, Quad_a16_t & rhs ) {
return lhs.q < rhs.q; }
610 static inline bool operator > ( Quad_a16_t & lhs, Quad_a16_t & rhs ) {
return lhs.q > rhs.q; }
612 static inline void operator +=( kmp_cmplx128_a4_t & lhs, kmp_cmplx128_a4_t & rhs ) { lhs.q += rhs.q; };
613 static inline void operator -=( kmp_cmplx128_a4_t & lhs, kmp_cmplx128_a4_t & rhs ) { lhs.q -= rhs.q; };
614 static inline void operator *=( kmp_cmplx128_a4_t & lhs, kmp_cmplx128_a4_t & rhs ) { lhs.q *= rhs.q; };
615 static inline void operator /=( kmp_cmplx128_a4_t & lhs, kmp_cmplx128_a4_t & rhs ) { lhs.q /= rhs.q; };
617 static inline void operator +=( kmp_cmplx128_a16_t & lhs, kmp_cmplx128_a16_t & rhs ) { lhs.q += rhs.q; };
618 static inline void operator -=( kmp_cmplx128_a16_t & lhs, kmp_cmplx128_a16_t & rhs ) { lhs.q -= rhs.q; };
619 static inline void operator *=( kmp_cmplx128_a16_t & lhs, kmp_cmplx128_a16_t & rhs ) { lhs.q *= rhs.q; };
620 static inline void operator /=( kmp_cmplx128_a16_t & lhs, kmp_cmplx128_a16_t & rhs ) { lhs.q /= rhs.q; };
633 #define KMP_CHECK_GTID \
634 if ( gtid == KMP_GTID_UNKNOWN ) { \
635 gtid = __kmp_entry_gtid(); \
636 } // check and get gtid when needed
642 #define ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE, RET_TYPE) \
643 RET_TYPE __kmpc_atomic_##TYPE_ID##_##OP_ID( ident_t *id_ref, int gtid, TYPE * lhs, TYPE rhs ) \
645 KMP_DEBUG_ASSERT( __kmp_init_serial ); \
646 KA_TRACE(100,("__kmpc_atomic_" #TYPE_ID "_" #OP_ID ": T#%d\n", gtid ));
650 #define ATOMIC_LOCK0 __kmp_atomic_lock // all types, for Gnu compat
651 #define ATOMIC_LOCK1i __kmp_atomic_lock_1i // char
652 #define ATOMIC_LOCK2i __kmp_atomic_lock_2i // short
653 #define ATOMIC_LOCK4i __kmp_atomic_lock_4i // long int
654 #define ATOMIC_LOCK4r __kmp_atomic_lock_4r // float
655 #define ATOMIC_LOCK8i __kmp_atomic_lock_8i // long long int
656 #define ATOMIC_LOCK8r __kmp_atomic_lock_8r // double
657 #define ATOMIC_LOCK8c __kmp_atomic_lock_8c // float complex
658 #define ATOMIC_LOCK10r __kmp_atomic_lock_10r // long double
659 #define ATOMIC_LOCK16r __kmp_atomic_lock_16r // _Quad
660 #define ATOMIC_LOCK16c __kmp_atomic_lock_16c // double complex
661 #define ATOMIC_LOCK20c __kmp_atomic_lock_20c // long double complex
662 #define ATOMIC_LOCK32c __kmp_atomic_lock_32c // _Quad complex
670 #define OP_CRITICAL(OP,LCK_ID) \
671 __kmp_acquire_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
675 __kmp_release_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid );
700 #ifdef KMP_GOMP_COMPAT
701 #define OP_GOMP_CRITICAL(OP,FLAG) \
702 if ( (FLAG) && (__kmp_atomic_mode == 2) ) { \
704 OP_CRITICAL( OP, 0 ); \
708 #define OP_GOMP_CRITICAL(OP,FLAG)
713 #define KMP_DO_PAUSE _mm_delay_32( 30 )
715 inline kmp_int32 __kmp_ex_compare_and_store32(
volatile kmp_int32 *p, kmp_int32 cv, kmp_int32 sv ) {
716 return __sync_bool_compare_and_swap( p, cv, sv );
718 inline kmp_int32 __kmp_ex_compare_and_store64(
volatile kmp_int64 *p, kmp_int64 cv, kmp_int64 sv ) {
719 return __sync_bool_compare_and_swap( p, cv, sv );
722 #define KMP_EX_COMPARE_AND_STORE_ACQ32 __kmp_ex_compare_and_store32
723 #define KMP_EX_COMPARE_AND_STORE_ACQ64 __kmp_ex_compare_and_store64
727 #define KMP_DO_PAUSE KMP_CPU_PAUSE()
729 #define KMP_EX_COMPARE_AND_STORE_ACQ32 KMP_COMPARE_AND_STORE_ACQ32
730 #define KMP_EX_COMPARE_AND_STORE_ACQ64 KMP_COMPARE_AND_STORE_ACQ64
734 #define KMP_EX_COMPARE_AND_STORE_ACQ8 KMP_COMPARE_AND_STORE_ACQ8
735 #define KMP_EX_COMPARE_AND_STORE_ACQ16 KMP_COMPARE_AND_STORE_ACQ16
744 #define OP_CMPXCHG(TYPE,BITS,OP) \
746 TYPE KMP_ATOMIC_VOLATILE temp_val; \
747 TYPE old_value, new_value; \
749 old_value = temp_val; \
750 new_value = old_value OP rhs; \
751 while ( ! KMP_EX_COMPARE_AND_STORE_ACQ##BITS( (kmp_int##BITS *) lhs, \
752 *VOLATILE_CAST(kmp_int##BITS *) &old_value, \
753 *VOLATILE_CAST(kmp_int##BITS *) &new_value ) ) \
758 old_value = temp_val; \
759 new_value = old_value OP rhs; \
770 #define OP_CMPXCHG_WORKAROUND(TYPE,BITS,OP) \
772 char anonym[ ( sizeof( TYPE ) == sizeof( kmp_int##BITS ) ) ? ( 1 ) : ( 0 ) ] = { 1 }; \
775 kmp_int##BITS *vvv; \
777 struct _sss old_value, new_value; \
778 old_value.vvv = ( kmp_int##BITS * )&old_value.cmp; \
779 new_value.vvv = ( kmp_int##BITS * )&new_value.cmp; \
780 *old_value.vvv = * ( volatile kmp_int##BITS * ) lhs; \
781 new_value.cmp = old_value.cmp OP rhs; \
782 while ( ! KMP_EX_COMPARE_AND_STORE_ACQ##BITS( (kmp_int##BITS *) lhs, \
783 *VOLATILE_CAST(kmp_int##BITS *) old_value.vvv, \
784 *VOLATILE_CAST(kmp_int##BITS *) new_value.vvv ) ) \
788 *old_value.vvv = * ( volatile kmp_int##BITS * ) lhs; \
789 new_value.cmp = old_value.cmp OP rhs; \
794 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
798 #define ATOMIC_FIXED_ADD(TYPE_ID,OP_ID,TYPE,BITS,OP,LCK_ID,MASK,GOMP_FLAG) \
799 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
800 OP_GOMP_CRITICAL(OP##=,GOMP_FLAG) \
802 KMP_TEST_THEN_ADD##BITS( lhs, OP rhs ); \
805 #define ATOMIC_FLOAT_ADD(TYPE_ID,OP_ID,TYPE,BITS,OP,LCK_ID,MASK,GOMP_FLAG) \
806 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
807 OP_GOMP_CRITICAL(OP##=,GOMP_FLAG) \
809 __kmp_test_then_add_real##BITS( lhs, OP rhs ); \
812 #define ATOMIC_CMPXCHG(TYPE_ID,OP_ID,TYPE,BITS,OP,LCK_ID,MASK,GOMP_FLAG) \
813 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
814 OP_GOMP_CRITICAL(OP##=,GOMP_FLAG) \
815 OP_CMPXCHG(TYPE,BITS,OP) \
819 #define ATOMIC_CMPXCHG_WORKAROUND(TYPE_ID,OP_ID,TYPE,BITS,OP,LCK_ID,MASK,GOMP_FLAG) \
820 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
821 OP_GOMP_CRITICAL(OP##=,GOMP_FLAG) \
822 OP_CMPXCHG_WORKAROUND(TYPE,BITS,OP) \
829 #define ATOMIC_FIXED_ADD(TYPE_ID,OP_ID,TYPE,BITS,OP,LCK_ID,MASK,GOMP_FLAG) \
830 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
831 OP_GOMP_CRITICAL(OP##=,GOMP_FLAG) \
832 if ( ! ( (kmp_uintptr_t) lhs & 0x##MASK) ) { \
834 KMP_TEST_THEN_ADD##BITS( lhs, OP rhs ); \
837 OP_CRITICAL(OP##=,LCK_ID) \
841 #define ATOMIC_FLOAT_ADD(TYPE_ID,OP_ID,TYPE,BITS,OP,LCK_ID,MASK,GOMP_FLAG) \
842 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
843 OP_GOMP_CRITICAL(OP##=,GOMP_FLAG) \
844 if ( ! ( (kmp_uintptr_t) lhs & 0x##MASK) ) { \
845 OP_CMPXCHG(TYPE,BITS,OP) \
848 OP_CRITICAL(OP##=,LCK_ID) \
852 #define ATOMIC_CMPXCHG(TYPE_ID,OP_ID,TYPE,BITS,OP,LCK_ID,MASK,GOMP_FLAG) \
853 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
854 OP_GOMP_CRITICAL(OP##=,GOMP_FLAG) \
855 if ( ! ( (kmp_uintptr_t) lhs & 0x##MASK) ) { \
856 OP_CMPXCHG(TYPE,BITS,OP) \
859 OP_CRITICAL(OP##=,LCK_ID) \
864 #define ATOMIC_CMPXCHG_WORKAROUND(TYPE_ID,OP_ID,TYPE,BITS,OP,LCK_ID,MASK,GOMP_FLAG) \
865 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
866 OP_GOMP_CRITICAL(OP##=,GOMP_FLAG) \
867 if ( ! ( (kmp_uintptr_t) lhs & 0x##MASK) ) { \
868 OP_CMPXCHG(TYPE,BITS,OP) \
871 OP_CRITICAL(OP##=,LCK_ID) \
878 ATOMIC_FIXED_ADD( fixed4, add, kmp_int32, 32, +, 4i, 3, 0 )
879 ATOMIC_FIXED_ADD( fixed4, sub, kmp_int32, 32, -, 4i, 3, 0 )
882 ATOMIC_CMPXCHG( float4, add, kmp_real32, 32, +, 4r, 3, KMP_ARCH_X86 )
883 ATOMIC_CMPXCHG( float4, sub, kmp_real32, 32, -, 4r, 3, KMP_ARCH_X86 )
885 ATOMIC_FLOAT_ADD( float4, add, kmp_real32, 32, +, 4r, 3, KMP_ARCH_X86 )
886 ATOMIC_FLOAT_ADD( float4, sub, kmp_real32, 32, -, 4r, 3, KMP_ARCH_X86 )
890 ATOMIC_FIXED_ADD( fixed8, add, kmp_int64, 64, +, 8i, 7, KMP_ARCH_X86 )
891 ATOMIC_FIXED_ADD( fixed8, sub, kmp_int64, 64, -, 8i, 7, KMP_ARCH_X86 )
894 ATOMIC_CMPXCHG( float8, add, kmp_real64, 64, +, 8r, 7, KMP_ARCH_X86 )
895 ATOMIC_CMPXCHG( float8, sub, kmp_real64, 64, -, 8r, 7, KMP_ARCH_X86 )
897 ATOMIC_FLOAT_ADD( float8, add, kmp_real64, 64, +, 8r, 7, KMP_ARCH_X86 )
898 ATOMIC_FLOAT_ADD( float8, sub, kmp_real64, 64, -, 8r, 7, KMP_ARCH_X86 )
916 ATOMIC_CMPXCHG( fixed1, add, kmp_int8, 8, +, 1i, 0, KMP_ARCH_X86 )
917 ATOMIC_CMPXCHG( fixed1, andb, kmp_int8, 8, &, 1i, 0, 0 )
918 ATOMIC_CMPXCHG( fixed1, div, kmp_int8, 8, /, 1i, 0, KMP_ARCH_X86 )
919 ATOMIC_CMPXCHG( fixed1u, div, kmp_uint8, 8, /, 1i, 0, KMP_ARCH_X86 )
920 ATOMIC_CMPXCHG( fixed1, mul, kmp_int8, 8, *, 1i, 0, KMP_ARCH_X86 )
921 ATOMIC_CMPXCHG( fixed1, orb, kmp_int8, 8, |, 1i, 0, 0 )
922 ATOMIC_CMPXCHG( fixed1, shl, kmp_int8, 8, <<, 1i, 0, KMP_ARCH_X86 )
923 ATOMIC_CMPXCHG( fixed1, shr, kmp_int8, 8, >>, 1i, 0, KMP_ARCH_X86 )
924 ATOMIC_CMPXCHG( fixed1u, shr, kmp_uint8, 8, >>, 1i, 0, KMP_ARCH_X86 )
925 ATOMIC_CMPXCHG( fixed1, sub, kmp_int8, 8, -, 1i, 0, KMP_ARCH_X86 )
926 ATOMIC_CMPXCHG( fixed1, xor, kmp_int8, 8, ^, 1i, 0, 0 )
927 ATOMIC_CMPXCHG( fixed2, add, kmp_int16, 16, +, 2i, 1, KMP_ARCH_X86 )
928 ATOMIC_CMPXCHG( fixed2, andb, kmp_int16, 16, &, 2i, 1, 0 )
929 ATOMIC_CMPXCHG( fixed2, div, kmp_int16, 16, /, 2i, 1, KMP_ARCH_X86 )
930 ATOMIC_CMPXCHG( fixed2u, div, kmp_uint16, 16, /, 2i, 1, KMP_ARCH_X86 )
931 ATOMIC_CMPXCHG( fixed2, mul, kmp_int16, 16, *, 2i, 1, KMP_ARCH_X86 )
932 ATOMIC_CMPXCHG( fixed2, orb, kmp_int16, 16, |, 2i, 1, 0 )
933 ATOMIC_CMPXCHG( fixed2, shl, kmp_int16, 16, <<, 2i, 1, KMP_ARCH_X86 )
934 ATOMIC_CMPXCHG( fixed2, shr, kmp_int16, 16, >>, 2i, 1, KMP_ARCH_X86 )
935 ATOMIC_CMPXCHG( fixed2u, shr, kmp_uint16, 16, >>, 2i, 1, KMP_ARCH_X86 )
936 ATOMIC_CMPXCHG( fixed2, sub, kmp_int16, 16, -, 2i, 1, KMP_ARCH_X86 )
937 ATOMIC_CMPXCHG( fixed2, xor, kmp_int16, 16, ^, 2i, 1, 0 )
938 ATOMIC_CMPXCHG( fixed4, andb, kmp_int32, 32, &, 4i, 3, 0 )
939 ATOMIC_CMPXCHG( fixed4, div, kmp_int32, 32, /, 4i, 3, KMP_ARCH_X86 )
940 ATOMIC_CMPXCHG( fixed4u, div, kmp_uint32, 32, /, 4i, 3, KMP_ARCH_X86 )
941 ATOMIC_CMPXCHG( fixed4, mul, kmp_int32, 32, *, 4i, 3, KMP_ARCH_X86 )
942 ATOMIC_CMPXCHG( fixed4, orb, kmp_int32, 32, |, 4i, 3, 0 )
943 ATOMIC_CMPXCHG( fixed4, shl, kmp_int32, 32, <<, 4i, 3, KMP_ARCH_X86 )
944 ATOMIC_CMPXCHG( fixed4, shr, kmp_int32, 32, >>, 4i, 3, KMP_ARCH_X86 )
945 ATOMIC_CMPXCHG( fixed4u, shr, kmp_uint32, 32, >>, 4i, 3, KMP_ARCH_X86 )
946 ATOMIC_CMPXCHG( fixed4, xor, kmp_int32, 32, ^, 4i, 3, 0 )
947 ATOMIC_CMPXCHG( fixed8, andb, kmp_int64, 64, &, 8i, 7, KMP_ARCH_X86 )
948 ATOMIC_CMPXCHG( fixed8, div, kmp_int64, 64, /, 8i, 7, KMP_ARCH_X86 )
949 ATOMIC_CMPXCHG( fixed8u, div, kmp_uint64, 64, /, 8i, 7, KMP_ARCH_X86 )
950 ATOMIC_CMPXCHG( fixed8, mul, kmp_int64, 64, *, 8i, 7, KMP_ARCH_X86 )
951 ATOMIC_CMPXCHG( fixed8, orb, kmp_int64, 64, |, 8i, 7, KMP_ARCH_X86 )
952 ATOMIC_CMPXCHG( fixed8, shl, kmp_int64, 64, <<, 8i, 7, KMP_ARCH_X86 )
953 ATOMIC_CMPXCHG( fixed8, shr, kmp_int64, 64, >>, 8i, 7, KMP_ARCH_X86 )
954 ATOMIC_CMPXCHG( fixed8u, shr, kmp_uint64, 64, >>, 8i, 7, KMP_ARCH_X86 )
955 ATOMIC_CMPXCHG( fixed8, xor, kmp_int64, 64, ^, 8i, 7, KMP_ARCH_X86 )
956 ATOMIC_CMPXCHG( float4, div, kmp_real32, 32, /, 4r, 3, KMP_ARCH_X86 )
957 ATOMIC_CMPXCHG( float4, mul, kmp_real32, 32, *, 4r, 3, KMP_ARCH_X86 )
958 ATOMIC_CMPXCHG( float8, div, kmp_real64, 64, /, 8r, 7, KMP_ARCH_X86 )
959 ATOMIC_CMPXCHG( float8, mul, kmp_real64, 64, *, 8r, 7, KMP_ARCH_X86 )
970 #define ATOMIC_CRIT_L(TYPE_ID,OP_ID,TYPE,OP,LCK_ID,GOMP_FLAG) \
971 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
972 OP_GOMP_CRITICAL( = *lhs OP, GOMP_FLAG ) \
973 OP_CRITICAL( = *lhs OP, LCK_ID ) \
976 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
980 #define ATOMIC_CMPX_L(TYPE_ID,OP_ID,TYPE,BITS,OP,LCK_ID,MASK,GOMP_FLAG) \
981 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
982 OP_GOMP_CRITICAL( = *lhs OP, GOMP_FLAG ) \
983 OP_CMPXCHG(TYPE,BITS,OP) \
989 #define ATOMIC_CMPX_L(TYPE_ID,OP_ID,TYPE,BITS,OP,LCK_ID,MASK,GOMP_FLAG) \
990 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
991 OP_GOMP_CRITICAL(= *lhs OP,GOMP_FLAG) \
992 if ( ! ( (kmp_uintptr_t) lhs & 0x##MASK) ) { \
993 OP_CMPXCHG(TYPE,BITS,OP) \
996 OP_CRITICAL(= *lhs OP,LCK_ID) \
1001 ATOMIC_CMPX_L( fixed1, andl,
char, 8, &&, 1i, 0, KMP_ARCH_X86 )
1002 ATOMIC_CMPX_L( fixed1, orl,
char, 8, ||, 1i, 0, KMP_ARCH_X86 )
1003 ATOMIC_CMPX_L( fixed2, andl,
short, 16, &&, 2i, 1, KMP_ARCH_X86 )
1004 ATOMIC_CMPX_L( fixed2, orl,
short, 16, ||, 2i, 1, KMP_ARCH_X86 )
1005 ATOMIC_CMPX_L( fixed4, andl, kmp_int32, 32, &&, 4i, 3, 0 )
1006 ATOMIC_CMPX_L( fixed4, orl, kmp_int32, 32, ||, 4i, 3, 0 )
1007 ATOMIC_CMPX_L( fixed8, andl, kmp_int64, 64, &&, 8i, 7, KMP_ARCH_X86 )
1008 ATOMIC_CMPX_L( fixed8, orl, kmp_int64, 64, ||, 8i, 7, KMP_ARCH_X86 )
1021 #define MIN_MAX_CRITSECT(OP,LCK_ID) \
1022 __kmp_acquire_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
1024 if ( *lhs OP rhs ) { \
1027 __kmp_release_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid );
1030 #ifdef KMP_GOMP_COMPAT
1031 #define GOMP_MIN_MAX_CRITSECT(OP,FLAG) \
1032 if (( FLAG ) && ( __kmp_atomic_mode == 2 )) { \
1034 MIN_MAX_CRITSECT( OP, 0 ); \
1038 #define GOMP_MIN_MAX_CRITSECT(OP,FLAG)
1042 #define MIN_MAX_CMPXCHG(TYPE,BITS,OP) \
1044 TYPE KMP_ATOMIC_VOLATILE temp_val; \
1047 old_value = temp_val; \
1048 while ( old_value OP rhs && \
1049 ! KMP_COMPARE_AND_STORE_ACQ##BITS( (kmp_int##BITS *) lhs, \
1050 *VOLATILE_CAST(kmp_int##BITS *) &old_value, \
1051 *VOLATILE_CAST(kmp_int##BITS *) &rhs ) ) \
1055 old_value = temp_val; \
1061 #define MIN_MAX_CRITICAL(TYPE_ID,OP_ID,TYPE,OP,LCK_ID,GOMP_FLAG) \
1062 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
1063 if ( *lhs OP rhs ) { \
1064 GOMP_MIN_MAX_CRITSECT(OP,GOMP_FLAG) \
1065 MIN_MAX_CRITSECT(OP,LCK_ID) \
1069 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
1073 #define MIN_MAX_COMPXCHG(TYPE_ID,OP_ID,TYPE,BITS,OP,LCK_ID,MASK,GOMP_FLAG) \
1074 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
1075 if ( *lhs OP rhs ) { \
1076 GOMP_MIN_MAX_CRITSECT(OP,GOMP_FLAG) \
1077 MIN_MAX_CMPXCHG(TYPE,BITS,OP) \
1084 #define MIN_MAX_COMPXCHG(TYPE_ID,OP_ID,TYPE,BITS,OP,LCK_ID,MASK,GOMP_FLAG) \
1085 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
1086 if ( *lhs OP rhs ) { \
1087 GOMP_MIN_MAX_CRITSECT(OP,GOMP_FLAG) \
1088 if ( ! ( (kmp_uintptr_t) lhs & 0x##MASK) ) { \
1089 MIN_MAX_CMPXCHG(TYPE,BITS,OP) \
1092 MIN_MAX_CRITSECT(OP,LCK_ID) \
1098 MIN_MAX_COMPXCHG( fixed1, max,
char, 8, <, 1i, 0, KMP_ARCH_X86 )
1099 MIN_MAX_COMPXCHG( fixed1, min,
char, 8, >, 1i, 0, KMP_ARCH_X86 )
1100 MIN_MAX_COMPXCHG( fixed2, max,
short, 16, <, 2i, 1, KMP_ARCH_X86 )
1101 MIN_MAX_COMPXCHG( fixed2, min,
short, 16, >, 2i, 1, KMP_ARCH_X86 )
1102 MIN_MAX_COMPXCHG( fixed4, max, kmp_int32, 32, <, 4i, 3, 0 )
1103 MIN_MAX_COMPXCHG( fixed4, min, kmp_int32, 32, >, 4i, 3, 0 )
1104 MIN_MAX_COMPXCHG( fixed8, max, kmp_int64, 64, <, 8i, 7, KMP_ARCH_X86 )
1105 MIN_MAX_COMPXCHG( fixed8, min, kmp_int64, 64, >, 8i, 7, KMP_ARCH_X86 )
1106 MIN_MAX_COMPXCHG( float4, max, kmp_real32, 32, <, 4r, 3, KMP_ARCH_X86 )
1107 MIN_MAX_COMPXCHG( float4, min, kmp_real32, 32, >, 4r, 3, KMP_ARCH_X86 )
1108 MIN_MAX_COMPXCHG( float8, max, kmp_real64, 64, <, 8r, 7, KMP_ARCH_X86 )
1109 MIN_MAX_COMPXCHG( float8, min, kmp_real64, 64, >, 8r, 7, KMP_ARCH_X86 )
1110 MIN_MAX_CRITICAL( float16, max, QUAD_LEGACY, <, 16r, 1 )
1111 MIN_MAX_CRITICAL( float16, min, QUAD_LEGACY, >, 16r, 1 )
1112 #if ( KMP_ARCH_X86 )
1113 MIN_MAX_CRITICAL( float16, max_a16, Quad_a16_t, <, 16r, 1 )
1114 MIN_MAX_CRITICAL( float16, min_a16, Quad_a16_t, >, 16r, 1 )
1119 #define ATOMIC_CRIT_EQV(TYPE_ID,OP_ID,TYPE,OP,LCK_ID,GOMP_FLAG) \
1120 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
1121 OP_GOMP_CRITICAL(^=~,GOMP_FLAG) \
1122 OP_CRITICAL(^=~,LCK_ID) \
1126 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
1129 #define ATOMIC_CMPX_EQV(TYPE_ID,OP_ID,TYPE,BITS,OP,LCK_ID,MASK,GOMP_FLAG) \
1130 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
1131 OP_GOMP_CRITICAL(^=~,GOMP_FLAG) \
1132 OP_CMPXCHG(TYPE,BITS,OP) \
1138 #define ATOMIC_CMPX_EQV(TYPE_ID,OP_ID,TYPE,BITS,OP,LCK_ID,MASK,GOMP_FLAG) \
1139 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
1140 OP_GOMP_CRITICAL(^=~,GOMP_FLAG) \
1141 if ( ! ( (kmp_uintptr_t) lhs & 0x##MASK) ) { \
1142 OP_CMPXCHG(TYPE,BITS,OP) \
1145 OP_CRITICAL(^=~,LCK_ID) \
1150 ATOMIC_CMPXCHG( fixed1, neqv, kmp_int8, 8, ^, 1i, 0, KMP_ARCH_X86 )
1151 ATOMIC_CMPXCHG( fixed2, neqv, kmp_int16, 16, ^, 2i, 1, KMP_ARCH_X86 )
1152 ATOMIC_CMPXCHG( fixed4, neqv, kmp_int32, 32, ^, 4i, 3, KMP_ARCH_X86 )
1153 ATOMIC_CMPXCHG( fixed8, neqv, kmp_int64, 64, ^, 8i, 7, KMP_ARCH_X86 )
1154 ATOMIC_CMPX_EQV( fixed1, eqv, kmp_int8, 8, ^~, 1i, 0, KMP_ARCH_X86 )
1155 ATOMIC_CMPX_EQV( fixed2, eqv, kmp_int16, 16, ^~, 2i, 1, KMP_ARCH_X86 )
1156 ATOMIC_CMPX_EQV( fixed4, eqv, kmp_int32, 32, ^~, 4i, 3, KMP_ARCH_X86 )
1157 ATOMIC_CMPX_EQV( fixed8, eqv, kmp_int64, 64, ^~, 8i, 7, KMP_ARCH_X86 )
1165 #define ATOMIC_CRITICAL(TYPE_ID,OP_ID,TYPE,OP,LCK_ID,GOMP_FLAG) \
1166 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
1167 OP_GOMP_CRITICAL(OP##=,GOMP_FLAG) \
1168 OP_CRITICAL(OP##=,LCK_ID) \
1173 ATOMIC_CRITICAL( float10, add,
long double, +, 10r, 1 )
1174 ATOMIC_CRITICAL( float10, sub,
long double, -, 10r, 1 )
1175 ATOMIC_CRITICAL( float10, mul,
long double, *, 10r, 1 )
1176 ATOMIC_CRITICAL( float10, div,
long double, /, 10r, 1 )
1178 ATOMIC_CRITICAL( float16, add, QUAD_LEGACY, +, 16r, 1 )
1179 ATOMIC_CRITICAL( float16, sub, QUAD_LEGACY, -, 16r, 1 )
1180 ATOMIC_CRITICAL( float16, mul, QUAD_LEGACY, *, 16r, 1 )
1181 ATOMIC_CRITICAL( float16, div, QUAD_LEGACY, /, 16r, 1 )
1182 #if ( KMP_ARCH_X86 )
1183 ATOMIC_CRITICAL( float16, add_a16, Quad_a16_t, +, 16r, 1 )
1184 ATOMIC_CRITICAL( float16, sub_a16, Quad_a16_t, -, 16r, 1 )
1185 ATOMIC_CRITICAL( float16, mul_a16, Quad_a16_t, *, 16r, 1 )
1186 ATOMIC_CRITICAL( float16, div_a16, Quad_a16_t, /, 16r, 1 )
1191 ATOMIC_CMPXCHG_WORKAROUND( cmplx4, add, kmp_cmplx32, 64, +, 8c, 7, 1 )
1192 ATOMIC_CMPXCHG_WORKAROUND( cmplx4, sub, kmp_cmplx32, 64, -, 8c, 7, 1 )
1193 ATOMIC_CMPXCHG_WORKAROUND( cmplx4, mul, kmp_cmplx32, 64, *, 8c, 7, 1 )
1194 ATOMIC_CMPXCHG_WORKAROUND( cmplx4, div, kmp_cmplx32, 64, /, 8c, 7, 1 )
1197 ATOMIC_CRITICAL( cmplx8, add, kmp_cmplx64, +, 16c, 1 )
1198 ATOMIC_CRITICAL( cmplx8, sub, kmp_cmplx64, -, 16c, 1 )
1199 ATOMIC_CRITICAL( cmplx8, mul, kmp_cmplx64, *, 16c, 1 )
1200 ATOMIC_CRITICAL( cmplx8, div, kmp_cmplx64, /, 16c, 1 )
1201 ATOMIC_CRITICAL( cmplx10, add, kmp_cmplx80, +, 20c, 1 )
1202 ATOMIC_CRITICAL( cmplx10, sub, kmp_cmplx80, -, 20c, 1 )
1203 ATOMIC_CRITICAL( cmplx10, mul, kmp_cmplx80, *, 20c, 1 )
1204 ATOMIC_CRITICAL( cmplx10, div, kmp_cmplx80, /, 20c, 1 )
1205 ATOMIC_CRITICAL( cmplx16, add, CPLX128_LEG, +, 32c, 1 )
1206 ATOMIC_CRITICAL( cmplx16, sub, CPLX128_LEG, -, 32c, 1 )
1207 ATOMIC_CRITICAL( cmplx16, mul, CPLX128_LEG, *, 32c, 1 )
1208 ATOMIC_CRITICAL( cmplx16, div, CPLX128_LEG, /, 32c, 1 )
1209 #if ( KMP_ARCH_X86 )
1210 ATOMIC_CRITICAL( cmplx16, add_a16, kmp_cmplx128_a16_t, +, 32c, 1 )
1211 ATOMIC_CRITICAL( cmplx16, sub_a16, kmp_cmplx128_a16_t, -, 32c, 1 )
1212 ATOMIC_CRITICAL( cmplx16, mul_a16, kmp_cmplx128_a16_t, *, 32c, 1 )
1213 ATOMIC_CRITICAL( cmplx16, div_a16, kmp_cmplx128_a16_t, /, 32c, 1 )
1220 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
1228 #define OP_CRITICAL_REV(OP,LCK_ID) \
1229 __kmp_acquire_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
1231 (*lhs) = (rhs) OP (*lhs); \
1233 __kmp_release_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid );
1235 #ifdef KMP_GOMP_COMPAT
1236 #define OP_GOMP_CRITICAL_REV(OP,FLAG) \
1237 if ( (FLAG) && (__kmp_atomic_mode == 2) ) { \
1239 OP_CRITICAL_REV( OP, 0 ); \
1243 #define OP_GOMP_CRITICAL_REV(OP,FLAG)
1251 #define ATOMIC_BEGIN_REV(TYPE_ID,OP_ID,TYPE, RET_TYPE) \
1252 RET_TYPE __kmpc_atomic_##TYPE_ID##_##OP_ID##_rev( ident_t *id_ref, int gtid, TYPE * lhs, TYPE rhs ) \
1254 KMP_DEBUG_ASSERT( __kmp_init_serial ); \
1255 KA_TRACE(100,("__kmpc_atomic_" #TYPE_ID "_" #OP_ID "_rev: T#%d\n", gtid ));
1264 #define OP_CMPXCHG_REV(TYPE,BITS,OP) \
1266 TYPE KMP_ATOMIC_VOLATILE temp_val; \
1267 TYPE old_value, new_value; \
1269 old_value = temp_val; \
1270 new_value = rhs OP old_value; \
1271 while ( ! KMP_EX_COMPARE_AND_STORE_ACQ##BITS( (kmp_int##BITS *) lhs, \
1272 *VOLATILE_CAST(kmp_int##BITS *) &old_value, \
1273 *VOLATILE_CAST(kmp_int##BITS *) &new_value ) ) \
1278 old_value = temp_val; \
1279 new_value = rhs OP old_value; \
1284 #define ATOMIC_CMPXCHG_REV(TYPE_ID,OP_ID,TYPE,BITS,OP,LCK_ID,GOMP_FLAG) \
1285 ATOMIC_BEGIN_REV(TYPE_ID,OP_ID,TYPE,void) \
1286 OP_GOMP_CRITICAL_REV(OP,GOMP_FLAG) \
1287 OP_CMPXCHG_REV(TYPE,BITS,OP) \
1304 ATOMIC_CMPXCHG_REV( fixed1, div, kmp_int8, 8, /, 1i, KMP_ARCH_X86 )
1305 ATOMIC_CMPXCHG_REV( fixed1u, div, kmp_uint8, 8, /, 1i, KMP_ARCH_X86 )
1306 ATOMIC_CMPXCHG_REV( fixed1, shl, kmp_int8, 8, <<, 1i, KMP_ARCH_X86 )
1307 ATOMIC_CMPXCHG_REV( fixed1, shr, kmp_int8, 8, >>, 1i, KMP_ARCH_X86 )
1308 ATOMIC_CMPXCHG_REV( fixed1u, shr, kmp_uint8, 8, >>, 1i, KMP_ARCH_X86 )
1309 ATOMIC_CMPXCHG_REV( fixed1, sub, kmp_int8, 8, -, 1i, KMP_ARCH_X86 )
1311 ATOMIC_CMPXCHG_REV( fixed2, div, kmp_int16, 16, /, 2i, KMP_ARCH_X86 )
1312 ATOMIC_CMPXCHG_REV( fixed2u, div, kmp_uint16, 16, /, 2i, KMP_ARCH_X86 )
1313 ATOMIC_CMPXCHG_REV( fixed2, shl, kmp_int16, 16, <<, 2i, KMP_ARCH_X86 )
1314 ATOMIC_CMPXCHG_REV( fixed2, shr, kmp_int16, 16, >>, 2i, KMP_ARCH_X86 )
1315 ATOMIC_CMPXCHG_REV( fixed2u, shr, kmp_uint16, 16, >>, 2i, KMP_ARCH_X86 )
1316 ATOMIC_CMPXCHG_REV( fixed2, sub, kmp_int16, 16, -, 2i, KMP_ARCH_X86 )
1318 ATOMIC_CMPXCHG_REV( fixed4, div, kmp_int32, 32, /, 4i, KMP_ARCH_X86 )
1319 ATOMIC_CMPXCHG_REV( fixed4u, div, kmp_uint32, 32, /, 4i, KMP_ARCH_X86 )
1320 ATOMIC_CMPXCHG_REV( fixed4, shl, kmp_int32, 32, <<, 4i, KMP_ARCH_X86 )
1321 ATOMIC_CMPXCHG_REV( fixed4, shr, kmp_int32, 32, >>, 4i, KMP_ARCH_X86 )
1322 ATOMIC_CMPXCHG_REV( fixed4u, shr, kmp_uint32, 32, >>, 4i, KMP_ARCH_X86 )
1323 ATOMIC_CMPXCHG_REV( fixed4, sub, kmp_int32, 32, -, 4i, KMP_ARCH_X86 )
1325 ATOMIC_CMPXCHG_REV( fixed8, div, kmp_int64, 64, /, 8i, KMP_ARCH_X86 )
1326 ATOMIC_CMPXCHG_REV( fixed8u, div, kmp_uint64, 64, /, 8i, KMP_ARCH_X86 )
1327 ATOMIC_CMPXCHG_REV( fixed8, shl, kmp_int64, 64, <<, 8i, KMP_ARCH_X86 )
1328 ATOMIC_CMPXCHG_REV( fixed8, shr, kmp_int64, 64, >>, 8i, KMP_ARCH_X86 )
1329 ATOMIC_CMPXCHG_REV( fixed8u, shr, kmp_uint64, 64, >>, 8i, KMP_ARCH_X86 )
1330 ATOMIC_CMPXCHG_REV( fixed8, sub, kmp_int64, 64, -, 8i, KMP_ARCH_X86 )
1332 ATOMIC_CMPXCHG_REV( float4, div, kmp_real32, 32, /, 4r, KMP_ARCH_X86 )
1333 ATOMIC_CMPXCHG_REV( float4, sub, kmp_real32, 32, -, 4r, KMP_ARCH_X86 )
1335 ATOMIC_CMPXCHG_REV( float8, div, kmp_real64, 64, /, 8r, KMP_ARCH_X86 )
1336 ATOMIC_CMPXCHG_REV( float8, sub, kmp_real64, 64, -, 8r, KMP_ARCH_X86 )
1344 #define ATOMIC_CRITICAL_REV(TYPE_ID,OP_ID,TYPE,OP,LCK_ID,GOMP_FLAG) \
1345 ATOMIC_BEGIN_REV(TYPE_ID,OP_ID,TYPE,void) \
1346 OP_GOMP_CRITICAL_REV(OP,GOMP_FLAG) \
1347 OP_CRITICAL_REV(OP,LCK_ID) \
1352 ATOMIC_CRITICAL_REV( float10, sub,
long double, -, 10r, 1 )
1353 ATOMIC_CRITICAL_REV( float10, div,
long double, /, 10r, 1 )
1355 ATOMIC_CRITICAL_REV( float16, sub, QUAD_LEGACY, -, 16r, 1 )
1356 ATOMIC_CRITICAL_REV( float16, div, QUAD_LEGACY, /, 16r, 1 )
1357 #if ( KMP_ARCH_X86 )
1358 ATOMIC_CRITICAL_REV( float16, sub_a16, Quad_a16_t, -, 16r, 1 )
1359 ATOMIC_CRITICAL_REV( float16, div_a16, Quad_a16_t, /, 16r, 1 )
1363 ATOMIC_CRITICAL_REV( cmplx4, sub, kmp_cmplx32, -, 8c, 1 )
1364 ATOMIC_CRITICAL_REV( cmplx4, div, kmp_cmplx32, /, 8c, 1 )
1365 ATOMIC_CRITICAL_REV( cmplx8, sub, kmp_cmplx64, -, 16c, 1 )
1366 ATOMIC_CRITICAL_REV( cmplx8, div, kmp_cmplx64, /, 16c, 1 )
1367 ATOMIC_CRITICAL_REV( cmplx10, sub, kmp_cmplx80, -, 20c, 1 )
1368 ATOMIC_CRITICAL_REV( cmplx10, div, kmp_cmplx80, /, 20c, 1 )
1369 ATOMIC_CRITICAL_REV( cmplx16, sub, CPLX128_LEG, -, 32c, 1 )
1370 ATOMIC_CRITICAL_REV( cmplx16, div, CPLX128_LEG, /, 32c, 1 )
1371 #if ( KMP_ARCH_X86 )
1372 ATOMIC_CRITICAL_REV( cmplx16, sub_a16, kmp_cmplx128_a16_t, -, 32c, 1 )
1373 ATOMIC_CRITICAL_REV( cmplx16, div_a16, kmp_cmplx128_a16_t, /, 32c, 1 )
1377 #endif //KMP_ARCH_X86 || KMP_ARCH_X86_64
1380 #endif //OMP_40_ENABLED
1394 #define ATOMIC_BEGIN_MIX(TYPE_ID,TYPE,OP_ID,RTYPE_ID,RTYPE) \
1395 void __kmpc_atomic_##TYPE_ID##_##OP_ID##_##RTYPE_ID( ident_t *id_ref, int gtid, TYPE * lhs, RTYPE rhs ) \
1397 KMP_DEBUG_ASSERT( __kmp_init_serial ); \
1398 KA_TRACE(100,("__kmpc_atomic_" #TYPE_ID "_" #OP_ID "_" #RTYPE_ID ": T#%d\n", gtid ));
1401 #define ATOMIC_CRITICAL_FP(TYPE_ID,TYPE,OP_ID,OP,RTYPE_ID,RTYPE,LCK_ID,GOMP_FLAG) \
1402 ATOMIC_BEGIN_MIX(TYPE_ID,TYPE,OP_ID,RTYPE_ID,RTYPE) \
1403 OP_GOMP_CRITICAL(OP##=,GOMP_FLAG) \
1404 OP_CRITICAL(OP##=,LCK_ID) \
1408 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
1411 #define ATOMIC_CMPXCHG_MIX(TYPE_ID,TYPE,OP_ID,BITS,OP,RTYPE_ID,RTYPE,LCK_ID,MASK,GOMP_FLAG) \
1412 ATOMIC_BEGIN_MIX(TYPE_ID,TYPE,OP_ID,RTYPE_ID,RTYPE) \
1413 OP_GOMP_CRITICAL(OP##=,GOMP_FLAG) \
1414 OP_CMPXCHG(TYPE,BITS,OP) \
1420 #define ATOMIC_CMPXCHG_MIX(TYPE_ID,TYPE,OP_ID,BITS,OP,RTYPE_ID,RTYPE,LCK_ID,MASK,GOMP_FLAG) \
1421 ATOMIC_BEGIN_MIX(TYPE_ID,TYPE,OP_ID,RTYPE_ID,RTYPE) \
1422 OP_GOMP_CRITICAL(OP##=,GOMP_FLAG) \
1423 if ( ! ( (kmp_uintptr_t) lhs & 0x##MASK) ) { \
1424 OP_CMPXCHG(TYPE,BITS,OP) \
1427 OP_CRITICAL(OP##=,LCK_ID) \
1433 ATOMIC_CMPXCHG_MIX( fixed1,
char, mul, 8, *, float8, kmp_real64, 1i, 0, KMP_ARCH_X86 )
1434 ATOMIC_CMPXCHG_MIX( fixed1,
char, div, 8, /, float8, kmp_real64, 1i, 0, KMP_ARCH_X86 )
1435 ATOMIC_CMPXCHG_MIX( fixed2,
short, mul, 16, *, float8, kmp_real64, 2i, 1, KMP_ARCH_X86 )
1436 ATOMIC_CMPXCHG_MIX( fixed2,
short, div, 16, /, float8, kmp_real64, 2i, 1, KMP_ARCH_X86 )
1437 ATOMIC_CMPXCHG_MIX( fixed4, kmp_int32, mul, 32, *, float8, kmp_real64, 4i, 3, 0 )
1438 ATOMIC_CMPXCHG_MIX( fixed4, kmp_int32, div, 32, /, float8, kmp_real64, 4i, 3, 0 )
1439 ATOMIC_CMPXCHG_MIX( fixed8, kmp_int64, mul, 64, *, float8, kmp_real64, 8i, 7, KMP_ARCH_X86 )
1440 ATOMIC_CMPXCHG_MIX( fixed8, kmp_int64, div, 64, /, float8, kmp_real64, 8i, 7, KMP_ARCH_X86 )
1441 ATOMIC_CMPXCHG_MIX( float4, kmp_real32, add, 32, +, float8, kmp_real64, 4r, 3, KMP_ARCH_X86 )
1442 ATOMIC_CMPXCHG_MIX( float4, kmp_real32, sub, 32, -, float8, kmp_real64, 4r, 3, KMP_ARCH_X86 )
1443 ATOMIC_CMPXCHG_MIX( float4, kmp_real32, mul, 32, *, float8, kmp_real64, 4r, 3, KMP_ARCH_X86 )
1444 ATOMIC_CMPXCHG_MIX( float4, kmp_real32, div, 32, /, float8, kmp_real64, 4r, 3, KMP_ARCH_X86 )
1448 ATOMIC_CMPXCHG_MIX( fixed1,
char, add, 8, +, fp, _Quad, 1i, 0, KMP_ARCH_X86 )
1449 ATOMIC_CMPXCHG_MIX( fixed1,
char, sub, 8, -, fp, _Quad, 1i, 0, KMP_ARCH_X86 )
1450 ATOMIC_CMPXCHG_MIX( fixed1,
char, mul, 8, *, fp, _Quad, 1i, 0, KMP_ARCH_X86 )
1451 ATOMIC_CMPXCHG_MIX( fixed1,
char, div, 8, /, fp, _Quad, 1i, 0, KMP_ARCH_X86 )
1452 ATOMIC_CMPXCHG_MIX( fixed1u, uchar, div, 8, /, fp, _Quad, 1i, 0, KMP_ARCH_X86 )
1454 ATOMIC_CMPXCHG_MIX( fixed2,
short, add, 16, +, fp, _Quad, 2i, 1, KMP_ARCH_X86 )
1455 ATOMIC_CMPXCHG_MIX( fixed2,
short, sub, 16, -, fp, _Quad, 2i, 1, KMP_ARCH_X86 )
1456 ATOMIC_CMPXCHG_MIX( fixed2,
short, mul, 16, *, fp, _Quad, 2i, 1, KMP_ARCH_X86 )
1457 ATOMIC_CMPXCHG_MIX( fixed2,
short, div, 16, /, fp, _Quad, 2i, 1, KMP_ARCH_X86 )
1458 ATOMIC_CMPXCHG_MIX( fixed2u, ushort, div, 16, /, fp, _Quad, 2i, 1, KMP_ARCH_X86 )
1460 ATOMIC_CMPXCHG_MIX( fixed4, kmp_int32, add, 32, +, fp, _Quad, 4i, 3, 0 )
1461 ATOMIC_CMPXCHG_MIX( fixed4, kmp_int32, sub, 32, -, fp, _Quad, 4i, 3, 0 )
1462 ATOMIC_CMPXCHG_MIX( fixed4, kmp_int32, mul, 32, *, fp, _Quad, 4i, 3, 0 )
1463 ATOMIC_CMPXCHG_MIX( fixed4, kmp_int32, div, 32, /, fp, _Quad, 4i, 3, 0 )
1464 ATOMIC_CMPXCHG_MIX( fixed4u, kmp_uint32, div, 32, /, fp, _Quad, 4i, 3, 0 )
1466 ATOMIC_CMPXCHG_MIX( fixed8, kmp_int64, add, 64, +, fp, _Quad, 8i, 7, KMP_ARCH_X86 )
1467 ATOMIC_CMPXCHG_MIX( fixed8, kmp_int64, sub, 64, -, fp, _Quad, 8i, 7, KMP_ARCH_X86 )
1468 ATOMIC_CMPXCHG_MIX( fixed8, kmp_int64, mul, 64, *, fp, _Quad, 8i, 7, KMP_ARCH_X86 )
1469 ATOMIC_CMPXCHG_MIX( fixed8, kmp_int64, div, 64, /, fp, _Quad, 8i, 7, KMP_ARCH_X86 )
1470 ATOMIC_CMPXCHG_MIX( fixed8u, kmp_uint64, div, 64, /, fp, _Quad, 8i, 7, KMP_ARCH_X86 )
1472 ATOMIC_CMPXCHG_MIX( float4, kmp_real32, add, 32, +, fp, _Quad, 4r, 3, KMP_ARCH_X86 )
1473 ATOMIC_CMPXCHG_MIX( float4, kmp_real32, sub, 32, -, fp, _Quad, 4r, 3, KMP_ARCH_X86 )
1474 ATOMIC_CMPXCHG_MIX( float4, kmp_real32, mul, 32, *, fp, _Quad, 4r, 3, KMP_ARCH_X86 )
1475 ATOMIC_CMPXCHG_MIX( float4, kmp_real32, div, 32, /, fp, _Quad, 4r, 3, KMP_ARCH_X86 )
1477 ATOMIC_CMPXCHG_MIX( float8, kmp_real64, add, 64, +, fp, _Quad, 8r, 7, KMP_ARCH_X86 )
1478 ATOMIC_CMPXCHG_MIX( float8, kmp_real64, sub, 64, -, fp, _Quad, 8r, 7, KMP_ARCH_X86 )
1479 ATOMIC_CMPXCHG_MIX( float8, kmp_real64, mul, 64, *, fp, _Quad, 8r, 7, KMP_ARCH_X86 )
1480 ATOMIC_CMPXCHG_MIX( float8, kmp_real64, div, 64, /, fp, _Quad, 8r, 7, KMP_ARCH_X86 )
1482 ATOMIC_CRITICAL_FP( float10,
long double, add, +, fp, _Quad, 10r, 1 )
1483 ATOMIC_CRITICAL_FP( float10,
long double, sub, -, fp, _Quad, 10r, 1 )
1484 ATOMIC_CRITICAL_FP( float10,
long double, mul, *, fp, _Quad, 10r, 1 )
1485 ATOMIC_CRITICAL_FP( float10,
long double, div, /, fp, _Quad, 10r, 1 )
1487 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
1491 #define ATOMIC_CMPXCHG_CMPLX(TYPE_ID,TYPE,OP_ID,BITS,OP,RTYPE_ID,RTYPE,LCK_ID,MASK,GOMP_FLAG) \
1492 ATOMIC_BEGIN_MIX(TYPE_ID,TYPE,OP_ID,RTYPE_ID,RTYPE) \
1493 OP_GOMP_CRITICAL(OP##=,GOMP_FLAG) \
1494 OP_CMPXCHG_WORKAROUND(TYPE,BITS,OP) \
1500 #define ATOMIC_CMPXCHG_CMPLX(TYPE_ID,TYPE,OP_ID,BITS,OP,RTYPE_ID,RTYPE,LCK_ID,MASK,GOMP_FLAG) \
1501 ATOMIC_BEGIN_MIX(TYPE_ID,TYPE,OP_ID,RTYPE_ID,RTYPE) \
1502 OP_GOMP_CRITICAL(OP##=,GOMP_FLAG) \
1503 if ( ! ( (kmp_uintptr_t) lhs & 0x##MASK) ) { \
1504 OP_CMPXCHG(TYPE,BITS,OP) \
1507 OP_CRITICAL(OP##=,LCK_ID) \
1512 ATOMIC_CMPXCHG_CMPLX( cmplx4, kmp_cmplx32, add, 64, +, cmplx8, kmp_cmplx64, 8c, 7, KMP_ARCH_X86 )
1513 ATOMIC_CMPXCHG_CMPLX( cmplx4, kmp_cmplx32, sub, 64, -, cmplx8, kmp_cmplx64, 8c, 7, KMP_ARCH_X86 )
1514 ATOMIC_CMPXCHG_CMPLX( cmplx4, kmp_cmplx32, mul, 64, *, cmplx8, kmp_cmplx64, 8c, 7, KMP_ARCH_X86 )
1515 ATOMIC_CMPXCHG_CMPLX( cmplx4, kmp_cmplx32, div, 64, /, cmplx8, kmp_cmplx64, 8c, 7, KMP_ARCH_X86 )
1518 #if KMP_ARCH_X86 || KMP_ARCH_X86_64
1530 #define ATOMIC_BEGIN_READ(TYPE_ID,OP_ID,TYPE, RET_TYPE) \
1531 RET_TYPE __kmpc_atomic_##TYPE_ID##_##OP_ID( ident_t *id_ref, int gtid, TYPE * loc ) \
1533 KMP_DEBUG_ASSERT( __kmp_init_serial ); \
1534 KA_TRACE(100,("__kmpc_atomic_" #TYPE_ID "_" #OP_ID ": T#%d\n", gtid ));
1546 #define OP_CMPXCHG_READ(TYPE,BITS,OP) \
1548 TYPE KMP_ATOMIC_VOLATILE temp_val; \
1551 kmp_int##BITS i_val; \
1553 union f_i_union old_value; \
1555 old_value.f_val = temp_val; \
1556 old_value.i_val = __kmp_compare_and_store_ret##BITS( (kmp_int##BITS *) loc, \
1557 *VOLATILE_CAST(kmp_int##BITS *) &old_value.i_val, \
1558 *VOLATILE_CAST(kmp_int##BITS *) &old_value.i_val ); \
1559 new_value = old_value.f_val; \
1569 #define OP_CRITICAL_READ(OP,LCK_ID) \
1570 __kmp_acquire_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
1572 new_value = (*loc); \
1574 __kmp_release_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid );
1577 #ifdef KMP_GOMP_COMPAT
1578 #define OP_GOMP_CRITICAL_READ(OP,FLAG) \
1579 if ( (FLAG) && (__kmp_atomic_mode == 2) ) { \
1581 OP_CRITICAL_READ( OP, 0 ); \
1585 #define OP_GOMP_CRITICAL_READ(OP,FLAG)
1589 #define ATOMIC_FIXED_READ(TYPE_ID,OP_ID,TYPE,BITS,OP,GOMP_FLAG) \
1590 ATOMIC_BEGIN_READ(TYPE_ID,OP_ID,TYPE,TYPE) \
1592 OP_GOMP_CRITICAL_READ(OP##=,GOMP_FLAG) \
1593 new_value = KMP_TEST_THEN_ADD##BITS( loc, OP 0 ); \
1597 #define ATOMIC_CMPXCHG_READ(TYPE_ID,OP_ID,TYPE,BITS,OP,GOMP_FLAG) \
1598 ATOMIC_BEGIN_READ(TYPE_ID,OP_ID,TYPE,TYPE) \
1600 OP_GOMP_CRITICAL_READ(OP##=,GOMP_FLAG) \
1601 OP_CMPXCHG_READ(TYPE,BITS,OP) \
1608 #define ATOMIC_CRITICAL_READ(TYPE_ID,OP_ID,TYPE,OP,LCK_ID,GOMP_FLAG) \
1609 ATOMIC_BEGIN_READ(TYPE_ID,OP_ID,TYPE,TYPE) \
1611 OP_GOMP_CRITICAL_READ(OP##=,GOMP_FLAG) \
1612 OP_CRITICAL_READ(OP,LCK_ID) \
1620 #if ( KMP_OS_WINDOWS )
1622 #define OP_CRITICAL_READ_WRK(OP,LCK_ID) \
1623 __kmp_acquire_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
1627 __kmp_release_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid );
1629 #ifdef KMP_GOMP_COMPAT
1630 #define OP_GOMP_CRITICAL_READ_WRK(OP,FLAG) \
1631 if ( (FLAG) && (__kmp_atomic_mode == 2) ) { \
1633 OP_CRITICAL_READ_WRK( OP, 0 ); \
1636 #define OP_GOMP_CRITICAL_READ_WRK(OP,FLAG)
1639 #define ATOMIC_BEGIN_READ_WRK(TYPE_ID,OP_ID,TYPE) \
1640 void __kmpc_atomic_##TYPE_ID##_##OP_ID( TYPE * out, ident_t *id_ref, int gtid, TYPE * loc ) \
1642 KMP_DEBUG_ASSERT( __kmp_init_serial ); \
1643 KA_TRACE(100,("__kmpc_atomic_" #TYPE_ID "_" #OP_ID ": T#%d\n", gtid ));
1646 #define ATOMIC_CRITICAL_READ_WRK(TYPE_ID,OP_ID,TYPE,OP,LCK_ID,GOMP_FLAG) \
1647 ATOMIC_BEGIN_READ_WRK(TYPE_ID,OP_ID,TYPE) \
1648 OP_GOMP_CRITICAL_READ_WRK(OP##=,GOMP_FLAG) \
1649 OP_CRITICAL_READ_WRK(OP,LCK_ID) \
1652 #endif // KMP_OS_WINDOWS
1656 ATOMIC_FIXED_READ( fixed4, rd, kmp_int32, 32, +, 0 )
1657 ATOMIC_FIXED_READ( fixed8, rd, kmp_int64, 64, +, KMP_ARCH_X86 )
1658 ATOMIC_CMPXCHG_READ( float4, rd, kmp_real32, 32, +, KMP_ARCH_X86 )
1659 ATOMIC_CMPXCHG_READ( float8, rd, kmp_real64, 64, +, KMP_ARCH_X86 )
1662 ATOMIC_CMPXCHG_READ( fixed1, rd, kmp_int8, 8, +, KMP_ARCH_X86 )
1663 ATOMIC_CMPXCHG_READ( fixed2, rd, kmp_int16, 16, +, KMP_ARCH_X86 )
1665 ATOMIC_CRITICAL_READ( float10, rd,
long double, +, 10r, 1 )
1666 ATOMIC_CRITICAL_READ( float16, rd, QUAD_LEGACY, +, 16r, 1 )
1669 #if ( KMP_OS_WINDOWS )
1670 ATOMIC_CRITICAL_READ_WRK( cmplx4, rd, kmp_cmplx32, +, 8c, 1 )
1672 ATOMIC_CRITICAL_READ( cmplx4, rd, kmp_cmplx32, +, 8c, 1 )
1674 ATOMIC_CRITICAL_READ( cmplx8, rd, kmp_cmplx64, +, 16c, 1 )
1675 ATOMIC_CRITICAL_READ( cmplx10, rd, kmp_cmplx80, +, 20c, 1 )
1676 ATOMIC_CRITICAL_READ( cmplx16, rd, CPLX128_LEG, +, 32c, 1 )
1677 #if ( KMP_ARCH_X86 )
1678 ATOMIC_CRITICAL_READ( float16, a16_rd, Quad_a16_t, +, 16r, 1 )
1679 ATOMIC_CRITICAL_READ( cmplx16, a16_rd, kmp_cmplx128_a16_t, +, 32c, 1 )
1687 #define ATOMIC_XCHG_WR(TYPE_ID,OP_ID,TYPE,BITS,OP,GOMP_FLAG) \
1688 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
1689 OP_GOMP_CRITICAL(OP,GOMP_FLAG) \
1690 __kmp_xchg_fixed##BITS( lhs, rhs ); \
1693 #define ATOMIC_XCHG_FLOAT_WR(TYPE_ID,OP_ID,TYPE,BITS,OP,GOMP_FLAG) \
1694 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
1695 OP_GOMP_CRITICAL(OP,GOMP_FLAG) \
1696 __kmp_xchg_real##BITS( lhs, rhs ); \
1707 #define OP_CMPXCHG_WR(TYPE,BITS,OP) \
1709 TYPE KMP_ATOMIC_VOLATILE temp_val; \
1710 TYPE old_value, new_value; \
1712 old_value = temp_val; \
1714 while ( ! KMP_COMPARE_AND_STORE_ACQ##BITS( (kmp_int##BITS *) lhs, \
1715 *VOLATILE_CAST(kmp_int##BITS *) &old_value, \
1716 *VOLATILE_CAST(kmp_int##BITS *) &new_value ) ) \
1721 old_value = temp_val; \
1727 #define ATOMIC_CMPXCHG_WR(TYPE_ID,OP_ID,TYPE,BITS,OP,GOMP_FLAG) \
1728 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
1729 OP_GOMP_CRITICAL(OP,GOMP_FLAG) \
1730 OP_CMPXCHG_WR(TYPE,BITS,OP) \
1738 #define ATOMIC_CRITICAL_WR(TYPE_ID,OP_ID,TYPE,OP,LCK_ID,GOMP_FLAG) \
1739 ATOMIC_BEGIN(TYPE_ID,OP_ID,TYPE,void) \
1740 OP_GOMP_CRITICAL(OP,GOMP_FLAG) \
1741 OP_CRITICAL(OP,LCK_ID) \
1745 ATOMIC_XCHG_WR( fixed1, wr, kmp_int8, 8, =, KMP_ARCH_X86 )
1746 ATOMIC_XCHG_WR( fixed2, wr, kmp_int16, 16, =, KMP_ARCH_X86 )
1747 ATOMIC_XCHG_WR( fixed4, wr, kmp_int32, 32, =, KMP_ARCH_X86 )
1748 #if ( KMP_ARCH_X86 )
1749 ATOMIC_CMPXCHG_WR( fixed8, wr, kmp_int64, 64, =, KMP_ARCH_X86 )
1751 ATOMIC_XCHG_WR( fixed8, wr, kmp_int64, 64, =, KMP_ARCH_X86 )
1754 ATOMIC_XCHG_FLOAT_WR( float4, wr, kmp_real32, 32, =, KMP_ARCH_X86 )
1755 #if ( KMP_ARCH_X86 )
1756 ATOMIC_CMPXCHG_WR( float8, wr, kmp_real64, 64, =, KMP_ARCH_X86 )
1758 ATOMIC_XCHG_FLOAT_WR( float8, wr, kmp_real64, 64, =, KMP_ARCH_X86 )
1761 ATOMIC_CRITICAL_WR( float10, wr,
long double, =, 10r, 1 )
1762 ATOMIC_CRITICAL_WR( float16, wr, QUAD_LEGACY, =, 16r, 1 )
1763 ATOMIC_CRITICAL_WR( cmplx4, wr, kmp_cmplx32, =, 8c, 1 )
1764 ATOMIC_CRITICAL_WR( cmplx8, wr, kmp_cmplx64, =, 16c, 1 )
1765 ATOMIC_CRITICAL_WR( cmplx10, wr, kmp_cmplx80, =, 20c, 1 )
1766 ATOMIC_CRITICAL_WR( cmplx16, wr, CPLX128_LEG, =, 32c, 1 )
1767 #if ( KMP_ARCH_X86 )
1768 ATOMIC_CRITICAL_WR( float16, a16_wr, Quad_a16_t, =, 16r, 1 )
1769 ATOMIC_CRITICAL_WR( cmplx16, a16_wr, kmp_cmplx128_a16_t, =, 32c, 1 )
1781 #define ATOMIC_BEGIN_CPT(TYPE_ID,OP_ID,TYPE,RET_TYPE) \
1782 RET_TYPE __kmpc_atomic_##TYPE_ID##_##OP_ID( ident_t *id_ref, int gtid, TYPE * lhs, TYPE rhs, int flag ) \
1784 KMP_DEBUG_ASSERT( __kmp_init_serial ); \
1785 KA_TRACE(100,("__kmpc_atomic_" #TYPE_ID "_" #OP_ID ": T#%d\n", gtid ));
1793 #define OP_CRITICAL_CPT(OP,LCK_ID) \
1794 __kmp_acquire_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
1798 new_value = (*lhs); \
1800 new_value = (*lhs); \
1804 __kmp_release_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
1808 #ifdef KMP_GOMP_COMPAT
1809 #define OP_GOMP_CRITICAL_CPT(OP,FLAG) \
1810 if ( (FLAG) && (__kmp_atomic_mode == 2) ) { \
1812 OP_CRITICAL_CPT( OP##=, 0 ); \
1815 #define OP_GOMP_CRITICAL_CPT(OP,FLAG)
1825 #define OP_CMPXCHG_CPT(TYPE,BITS,OP) \
1827 TYPE KMP_ATOMIC_VOLATILE temp_val; \
1828 TYPE old_value, new_value; \
1830 old_value = temp_val; \
1831 new_value = old_value OP rhs; \
1832 while ( ! KMP_COMPARE_AND_STORE_ACQ##BITS( (kmp_int##BITS *) lhs, \
1833 *VOLATILE_CAST(kmp_int##BITS *) &old_value, \
1834 *VOLATILE_CAST(kmp_int##BITS *) &new_value ) ) \
1839 old_value = temp_val; \
1840 new_value = old_value OP rhs; \
1849 #define ATOMIC_CMPXCHG_CPT(TYPE_ID,OP_ID,TYPE,BITS,OP,GOMP_FLAG) \
1850 ATOMIC_BEGIN_CPT(TYPE_ID,OP_ID,TYPE,TYPE) \
1852 OP_GOMP_CRITICAL_CPT(OP,GOMP_FLAG) \
1853 OP_CMPXCHG_CPT(TYPE,BITS,OP) \
1857 #define ATOMIC_FIXED_ADD_CPT(TYPE_ID,OP_ID,TYPE,BITS,OP,GOMP_FLAG) \
1858 ATOMIC_BEGIN_CPT(TYPE_ID,OP_ID,TYPE,TYPE) \
1859 TYPE old_value, new_value; \
1860 OP_GOMP_CRITICAL_CPT(OP,GOMP_FLAG) \
1862 old_value = KMP_TEST_THEN_ADD##BITS( lhs, OP rhs ); \
1864 return old_value OP rhs; \
1869 #define ATOMIC_FLOAT_ADD_CPT(TYPE_ID,OP_ID,TYPE,BITS,OP,GOMP_FLAG) \
1870 ATOMIC_BEGIN_CPT(TYPE_ID,OP_ID,TYPE,TYPE) \
1871 TYPE old_value, new_value; \
1872 OP_GOMP_CRITICAL_CPT(OP,GOMP_FLAG) \
1874 old_value = __kmp_test_then_add_real##BITS( lhs, OP rhs ); \
1876 return old_value OP rhs; \
1882 ATOMIC_FIXED_ADD_CPT( fixed4, add_cpt, kmp_int32, 32, +, 0 )
1883 ATOMIC_FIXED_ADD_CPT( fixed4, sub_cpt, kmp_int32, 32, -, 0 )
1884 ATOMIC_FIXED_ADD_CPT( fixed8, add_cpt, kmp_int64, 64, +, KMP_ARCH_X86 )
1885 ATOMIC_FIXED_ADD_CPT( fixed8, sub_cpt, kmp_int64, 64, -, KMP_ARCH_X86 )
1888 ATOMIC_CMPXCHG_CPT( float4, add_cpt, kmp_real32, 32, +, KMP_ARCH_X86 )
1889 ATOMIC_CMPXCHG_CPT( float4, sub_cpt, kmp_real32, 32, -, KMP_ARCH_X86 )
1890 ATOMIC_CMPXCHG_CPT( float8, add_cpt, kmp_real64, 64, +, KMP_ARCH_X86 )
1891 ATOMIC_CMPXCHG_CPT( float8, sub_cpt, kmp_real64, 64, -, KMP_ARCH_X86 )
1893 ATOMIC_FLOAT_ADD_CPT( float4, add_cpt, kmp_real32, 32, +, KMP_ARCH_X86 )
1894 ATOMIC_FLOAT_ADD_CPT( float4, sub_cpt, kmp_real32, 32, -, KMP_ARCH_X86 )
1895 ATOMIC_FLOAT_ADD_CPT( float8, add_cpt, kmp_real64, 64, +, KMP_ARCH_X86 )
1896 ATOMIC_FLOAT_ADD_CPT( float8, sub_cpt, kmp_real64, 64, -, KMP_ARCH_X86 )
1911 ATOMIC_CMPXCHG_CPT( fixed1, add_cpt, kmp_int8, 8, +, KMP_ARCH_X86 )
1912 ATOMIC_CMPXCHG_CPT( fixed1, andb_cpt, kmp_int8, 8, &, 0 )
1913 ATOMIC_CMPXCHG_CPT( fixed1, div_cpt, kmp_int8, 8, /, KMP_ARCH_X86 )
1914 ATOMIC_CMPXCHG_CPT( fixed1u, div_cpt, kmp_uint8, 8, /, KMP_ARCH_X86 )
1915 ATOMIC_CMPXCHG_CPT( fixed1, mul_cpt, kmp_int8, 8, *, KMP_ARCH_X86 )
1916 ATOMIC_CMPXCHG_CPT( fixed1, orb_cpt, kmp_int8, 8, |, 0 )
1917 ATOMIC_CMPXCHG_CPT( fixed1, shl_cpt, kmp_int8, 8, <<, KMP_ARCH_X86 )
1918 ATOMIC_CMPXCHG_CPT( fixed1, shr_cpt, kmp_int8, 8, >>, KMP_ARCH_X86 )
1919 ATOMIC_CMPXCHG_CPT( fixed1u, shr_cpt, kmp_uint8, 8, >>, KMP_ARCH_X86 )
1920 ATOMIC_CMPXCHG_CPT( fixed1, sub_cpt, kmp_int8, 8, -, KMP_ARCH_X86 )
1921 ATOMIC_CMPXCHG_CPT( fixed1, xor_cpt, kmp_int8, 8, ^, 0 )
1922 ATOMIC_CMPXCHG_CPT( fixed2, add_cpt, kmp_int16, 16, +, KMP_ARCH_X86 )
1923 ATOMIC_CMPXCHG_CPT( fixed2, andb_cpt, kmp_int16, 16, &, 0 )
1924 ATOMIC_CMPXCHG_CPT( fixed2, div_cpt, kmp_int16, 16, /, KMP_ARCH_X86 )
1925 ATOMIC_CMPXCHG_CPT( fixed2u, div_cpt, kmp_uint16, 16, /, KMP_ARCH_X86 )
1926 ATOMIC_CMPXCHG_CPT( fixed2, mul_cpt, kmp_int16, 16, *, KMP_ARCH_X86 )
1927 ATOMIC_CMPXCHG_CPT( fixed2, orb_cpt, kmp_int16, 16, |, 0 )
1928 ATOMIC_CMPXCHG_CPT( fixed2, shl_cpt, kmp_int16, 16, <<, KMP_ARCH_X86 )
1929 ATOMIC_CMPXCHG_CPT( fixed2, shr_cpt, kmp_int16, 16, >>, KMP_ARCH_X86 )
1930 ATOMIC_CMPXCHG_CPT( fixed2u, shr_cpt, kmp_uint16, 16, >>, KMP_ARCH_X86 )
1931 ATOMIC_CMPXCHG_CPT( fixed2, sub_cpt, kmp_int16, 16, -, KMP_ARCH_X86 )
1932 ATOMIC_CMPXCHG_CPT( fixed2, xor_cpt, kmp_int16, 16, ^, 0 )
1933 ATOMIC_CMPXCHG_CPT( fixed4, andb_cpt, kmp_int32, 32, &, 0 )
1934 ATOMIC_CMPXCHG_CPT( fixed4, div_cpt, kmp_int32, 32, /, KMP_ARCH_X86 )
1935 ATOMIC_CMPXCHG_CPT( fixed4u, div_cpt, kmp_uint32, 32, /, KMP_ARCH_X86 )
1936 ATOMIC_CMPXCHG_CPT( fixed4, mul_cpt, kmp_int32, 32, *, KMP_ARCH_X86 )
1937 ATOMIC_CMPXCHG_CPT( fixed4, orb_cpt, kmp_int32, 32, |, 0 )
1938 ATOMIC_CMPXCHG_CPT( fixed4, shl_cpt, kmp_int32, 32, <<, KMP_ARCH_X86 )
1939 ATOMIC_CMPXCHG_CPT( fixed4, shr_cpt, kmp_int32, 32, >>, KMP_ARCH_X86 )
1940 ATOMIC_CMPXCHG_CPT( fixed4u, shr_cpt, kmp_uint32, 32, >>, KMP_ARCH_X86 )
1941 ATOMIC_CMPXCHG_CPT( fixed4, xor_cpt, kmp_int32, 32, ^, 0 )
1942 ATOMIC_CMPXCHG_CPT( fixed8, andb_cpt, kmp_int64, 64, &, KMP_ARCH_X86 )
1943 ATOMIC_CMPXCHG_CPT( fixed8, div_cpt, kmp_int64, 64, /, KMP_ARCH_X86 )
1944 ATOMIC_CMPXCHG_CPT( fixed8u, div_cpt, kmp_uint64, 64, /, KMP_ARCH_X86 )
1945 ATOMIC_CMPXCHG_CPT( fixed8, mul_cpt, kmp_int64, 64, *, KMP_ARCH_X86 )
1946 ATOMIC_CMPXCHG_CPT( fixed8, orb_cpt, kmp_int64, 64, |, KMP_ARCH_X86 )
1947 ATOMIC_CMPXCHG_CPT( fixed8, shl_cpt, kmp_int64, 64, <<, KMP_ARCH_X86 )
1948 ATOMIC_CMPXCHG_CPT( fixed8, shr_cpt, kmp_int64, 64, >>, KMP_ARCH_X86 )
1949 ATOMIC_CMPXCHG_CPT( fixed8u, shr_cpt, kmp_uint64, 64, >>, KMP_ARCH_X86 )
1950 ATOMIC_CMPXCHG_CPT( fixed8, xor_cpt, kmp_int64, 64, ^, KMP_ARCH_X86 )
1951 ATOMIC_CMPXCHG_CPT( float4, div_cpt, kmp_real32, 32, /, KMP_ARCH_X86 )
1952 ATOMIC_CMPXCHG_CPT( float4, mul_cpt, kmp_real32, 32, *, KMP_ARCH_X86 )
1953 ATOMIC_CMPXCHG_CPT( float8, div_cpt, kmp_real64, 64, /, KMP_ARCH_X86 )
1954 ATOMIC_CMPXCHG_CPT( float8, mul_cpt, kmp_real64, 64, *, KMP_ARCH_X86 )
1967 #define OP_CRITICAL_L_CPT(OP,LCK_ID) \
1968 __kmp_acquire_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
1973 new_value = (*lhs); \
1975 __kmp_release_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid );
1978 #ifdef KMP_GOMP_COMPAT
1979 #define OP_GOMP_CRITICAL_L_CPT(OP,FLAG) \
1980 if ( (FLAG) && (__kmp_atomic_mode == 2) ) { \
1982 OP_CRITICAL_L_CPT( OP, 0 ); \
1986 #define OP_GOMP_CRITICAL_L_CPT(OP,FLAG)
1991 #define ATOMIC_CMPX_L_CPT(TYPE_ID,OP_ID,TYPE,BITS,OP,GOMP_FLAG) \
1992 ATOMIC_BEGIN_CPT(TYPE_ID,OP_ID,TYPE,TYPE) \
1994 OP_GOMP_CRITICAL_L_CPT( = *lhs OP, GOMP_FLAG ) \
1995 OP_CMPXCHG_CPT(TYPE,BITS,OP) \
1998 ATOMIC_CMPX_L_CPT( fixed1, andl_cpt,
char, 8, &&, KMP_ARCH_X86 )
1999 ATOMIC_CMPX_L_CPT( fixed1, orl_cpt,
char, 8, ||, KMP_ARCH_X86 )
2000 ATOMIC_CMPX_L_CPT( fixed2, andl_cpt,
short, 16, &&, KMP_ARCH_X86 )
2001 ATOMIC_CMPX_L_CPT( fixed2, orl_cpt,
short, 16, ||, KMP_ARCH_X86 )
2002 ATOMIC_CMPX_L_CPT( fixed4, andl_cpt, kmp_int32, 32, &&, 0 )
2003 ATOMIC_CMPX_L_CPT( fixed4, orl_cpt, kmp_int32, 32, ||, 0 )
2004 ATOMIC_CMPX_L_CPT( fixed8, andl_cpt, kmp_int64, 64, &&, KMP_ARCH_X86 )
2005 ATOMIC_CMPX_L_CPT( fixed8, orl_cpt, kmp_int64, 64, ||, KMP_ARCH_X86 )
2018 #define MIN_MAX_CRITSECT_CPT(OP,LCK_ID) \
2019 __kmp_acquire_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
2021 if ( *lhs OP rhs ) { \
2027 new_value = old_value; \
2029 __kmp_release_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
2033 #ifdef KMP_GOMP_COMPAT
2034 #define GOMP_MIN_MAX_CRITSECT_CPT(OP,FLAG) \
2035 if (( FLAG ) && ( __kmp_atomic_mode == 2 )) { \
2037 MIN_MAX_CRITSECT_CPT( OP, 0 ); \
2040 #define GOMP_MIN_MAX_CRITSECT_CPT(OP,FLAG)
2044 #define MIN_MAX_CMPXCHG_CPT(TYPE,BITS,OP) \
2046 TYPE KMP_ATOMIC_VOLATILE temp_val; \
2049 old_value = temp_val; \
2050 while ( old_value OP rhs && \
2051 ! KMP_COMPARE_AND_STORE_ACQ##BITS( (kmp_int##BITS *) lhs, \
2052 *VOLATILE_CAST(kmp_int##BITS *) &old_value, \
2053 *VOLATILE_CAST(kmp_int##BITS *) &rhs ) ) \
2057 old_value = temp_val; \
2067 #define MIN_MAX_CRITICAL_CPT(TYPE_ID,OP_ID,TYPE,OP,LCK_ID,GOMP_FLAG) \
2068 ATOMIC_BEGIN_CPT(TYPE_ID,OP_ID,TYPE,TYPE) \
2069 TYPE new_value, old_value; \
2070 if ( *lhs OP rhs ) { \
2071 GOMP_MIN_MAX_CRITSECT_CPT(OP,GOMP_FLAG) \
2072 MIN_MAX_CRITSECT_CPT(OP,LCK_ID) \
2077 #define MIN_MAX_COMPXCHG_CPT(TYPE_ID,OP_ID,TYPE,BITS,OP,GOMP_FLAG) \
2078 ATOMIC_BEGIN_CPT(TYPE_ID,OP_ID,TYPE,TYPE) \
2079 TYPE new_value, old_value; \
2080 if ( *lhs OP rhs ) { \
2081 GOMP_MIN_MAX_CRITSECT_CPT(OP,GOMP_FLAG) \
2082 MIN_MAX_CMPXCHG_CPT(TYPE,BITS,OP) \
2088 MIN_MAX_COMPXCHG_CPT( fixed1, max_cpt,
char, 8, <, KMP_ARCH_X86 )
2089 MIN_MAX_COMPXCHG_CPT( fixed1, min_cpt,
char, 8, >, KMP_ARCH_X86 )
2090 MIN_MAX_COMPXCHG_CPT( fixed2, max_cpt,
short, 16, <, KMP_ARCH_X86 )
2091 MIN_MAX_COMPXCHG_CPT( fixed2, min_cpt,
short, 16, >, KMP_ARCH_X86 )
2092 MIN_MAX_COMPXCHG_CPT( fixed4, max_cpt, kmp_int32, 32, <, 0 )
2093 MIN_MAX_COMPXCHG_CPT( fixed4, min_cpt, kmp_int32, 32, >, 0 )
2094 MIN_MAX_COMPXCHG_CPT( fixed8, max_cpt, kmp_int64, 64, <, KMP_ARCH_X86 )
2095 MIN_MAX_COMPXCHG_CPT( fixed8, min_cpt, kmp_int64, 64, >, KMP_ARCH_X86 )
2096 MIN_MAX_COMPXCHG_CPT( float4, max_cpt, kmp_real32, 32, <, KMP_ARCH_X86 )
2097 MIN_MAX_COMPXCHG_CPT( float4, min_cpt, kmp_real32, 32, >, KMP_ARCH_X86 )
2098 MIN_MAX_COMPXCHG_CPT( float8, max_cpt, kmp_real64, 64, <, KMP_ARCH_X86 )
2099 MIN_MAX_COMPXCHG_CPT( float8, min_cpt, kmp_real64, 64, >, KMP_ARCH_X86 )
2100 MIN_MAX_CRITICAL_CPT( float16, max_cpt, QUAD_LEGACY, <, 16r, 1 )
2101 MIN_MAX_CRITICAL_CPT( float16, min_cpt, QUAD_LEGACY, >, 16r, 1 )
2102 #if ( KMP_ARCH_X86 )
2103 MIN_MAX_CRITICAL_CPT( float16, max_a16_cpt, Quad_a16_t, <, 16r, 1 )
2104 MIN_MAX_CRITICAL_CPT( float16, min_a16_cpt, Quad_a16_t, >, 16r, 1 )
2108 #ifdef KMP_GOMP_COMPAT
2109 #define OP_GOMP_CRITICAL_EQV_CPT(OP,FLAG) \
2110 if ( (FLAG) && (__kmp_atomic_mode == 2) ) { \
2112 OP_CRITICAL_CPT( OP, 0 ); \
2115 #define OP_GOMP_CRITICAL_EQV_CPT(OP,FLAG)
2118 #define ATOMIC_CMPX_EQV_CPT(TYPE_ID,OP_ID,TYPE,BITS,OP,GOMP_FLAG) \
2119 ATOMIC_BEGIN_CPT(TYPE_ID,OP_ID,TYPE,TYPE) \
2121 OP_GOMP_CRITICAL_EQV_CPT(^=~,GOMP_FLAG) \
2122 OP_CMPXCHG_CPT(TYPE,BITS,OP) \
2127 ATOMIC_CMPXCHG_CPT( fixed1, neqv_cpt, kmp_int8, 8, ^, KMP_ARCH_X86 )
2128 ATOMIC_CMPXCHG_CPT( fixed2, neqv_cpt, kmp_int16, 16, ^, KMP_ARCH_X86 )
2129 ATOMIC_CMPXCHG_CPT( fixed4, neqv_cpt, kmp_int32, 32, ^, KMP_ARCH_X86 )
2130 ATOMIC_CMPXCHG_CPT( fixed8, neqv_cpt, kmp_int64, 64, ^, KMP_ARCH_X86 )
2131 ATOMIC_CMPX_EQV_CPT( fixed1, eqv_cpt, kmp_int8, 8, ^~, KMP_ARCH_X86 )
2132 ATOMIC_CMPX_EQV_CPT( fixed2, eqv_cpt, kmp_int16, 16, ^~, KMP_ARCH_X86 )
2133 ATOMIC_CMPX_EQV_CPT( fixed4, eqv_cpt, kmp_int32, 32, ^~, KMP_ARCH_X86 )
2134 ATOMIC_CMPX_EQV_CPT( fixed8, eqv_cpt, kmp_int64, 64, ^~, KMP_ARCH_X86 )
2141 #define ATOMIC_CRITICAL_CPT(TYPE_ID,OP_ID,TYPE,OP,LCK_ID,GOMP_FLAG) \
2142 ATOMIC_BEGIN_CPT(TYPE_ID,OP_ID,TYPE,TYPE) \
2144 OP_GOMP_CRITICAL_CPT(OP,GOMP_FLAG) \
2145 OP_CRITICAL_CPT(OP##=,LCK_ID) \
2152 #define OP_CRITICAL_CPT_WRK(OP,LCK_ID) \
2153 __kmp_acquire_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
2163 __kmp_release_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
2167 #ifdef KMP_GOMP_COMPAT
2168 #define OP_GOMP_CRITICAL_CPT_WRK(OP,FLAG) \
2169 if ( (FLAG) && (__kmp_atomic_mode == 2) ) { \
2171 OP_CRITICAL_CPT_WRK( OP##=, 0 ); \
2174 #define OP_GOMP_CRITICAL_CPT_WRK(OP,FLAG)
2178 #define ATOMIC_BEGIN_WRK(TYPE_ID,OP_ID,TYPE) \
2179 void __kmpc_atomic_##TYPE_ID##_##OP_ID( ident_t *id_ref, int gtid, TYPE * lhs, TYPE rhs, TYPE * out, int flag ) \
2181 KMP_DEBUG_ASSERT( __kmp_init_serial ); \
2182 KA_TRACE(100,("__kmpc_atomic_" #TYPE_ID "_" #OP_ID ": T#%d\n", gtid ));
2185 #define ATOMIC_CRITICAL_CPT_WRK(TYPE_ID,OP_ID,TYPE,OP,LCK_ID,GOMP_FLAG) \
2186 ATOMIC_BEGIN_WRK(TYPE_ID,OP_ID,TYPE) \
2187 OP_GOMP_CRITICAL_CPT_WRK(OP,GOMP_FLAG) \
2188 OP_CRITICAL_CPT_WRK(OP##=,LCK_ID) \
2194 ATOMIC_CRITICAL_CPT( float10, add_cpt,
long double, +, 10r, 1 )
2195 ATOMIC_CRITICAL_CPT( float10, sub_cpt,
long double, -, 10r, 1 )
2196 ATOMIC_CRITICAL_CPT( float10, mul_cpt,
long double, *, 10r, 1 )
2197 ATOMIC_CRITICAL_CPT( float10, div_cpt,
long double, /, 10r, 1 )
2199 ATOMIC_CRITICAL_CPT( float16, add_cpt, QUAD_LEGACY, +, 16r, 1 )
2200 ATOMIC_CRITICAL_CPT( float16, sub_cpt, QUAD_LEGACY, -, 16r, 1 )
2201 ATOMIC_CRITICAL_CPT( float16, mul_cpt, QUAD_LEGACY, *, 16r, 1 )
2202 ATOMIC_CRITICAL_CPT( float16, div_cpt, QUAD_LEGACY, /, 16r, 1 )
2203 #if ( KMP_ARCH_X86 )
2204 ATOMIC_CRITICAL_CPT( float16, add_a16_cpt, Quad_a16_t, +, 16r, 1 )
2205 ATOMIC_CRITICAL_CPT( float16, sub_a16_cpt, Quad_a16_t, -, 16r, 1 )
2206 ATOMIC_CRITICAL_CPT( float16, mul_a16_cpt, Quad_a16_t, *, 16r, 1 )
2207 ATOMIC_CRITICAL_CPT( float16, div_a16_cpt, Quad_a16_t, /, 16r, 1 )
2213 ATOMIC_CRITICAL_CPT_WRK( cmplx4, add_cpt, kmp_cmplx32, +, 8c, 1 )
2214 ATOMIC_CRITICAL_CPT_WRK( cmplx4, sub_cpt, kmp_cmplx32, -, 8c, 1 )
2215 ATOMIC_CRITICAL_CPT_WRK( cmplx4, mul_cpt, kmp_cmplx32, *, 8c, 1 )
2216 ATOMIC_CRITICAL_CPT_WRK( cmplx4, div_cpt, kmp_cmplx32, /, 8c, 1 )
2218 ATOMIC_CRITICAL_CPT( cmplx8, add_cpt, kmp_cmplx64, +, 16c, 1 )
2219 ATOMIC_CRITICAL_CPT( cmplx8, sub_cpt, kmp_cmplx64, -, 16c, 1 )
2220 ATOMIC_CRITICAL_CPT( cmplx8, mul_cpt, kmp_cmplx64, *, 16c, 1 )
2221 ATOMIC_CRITICAL_CPT( cmplx8, div_cpt, kmp_cmplx64, /, 16c, 1 )
2222 ATOMIC_CRITICAL_CPT( cmplx10, add_cpt, kmp_cmplx80, +, 20c, 1 )
2223 ATOMIC_CRITICAL_CPT( cmplx10, sub_cpt, kmp_cmplx80, -, 20c, 1 )
2224 ATOMIC_CRITICAL_CPT( cmplx10, mul_cpt, kmp_cmplx80, *, 20c, 1 )
2225 ATOMIC_CRITICAL_CPT( cmplx10, div_cpt, kmp_cmplx80, /, 20c, 1 )
2226 ATOMIC_CRITICAL_CPT( cmplx16, add_cpt, CPLX128_LEG, +, 32c, 1 )
2227 ATOMIC_CRITICAL_CPT( cmplx16, sub_cpt, CPLX128_LEG, -, 32c, 1 )
2228 ATOMIC_CRITICAL_CPT( cmplx16, mul_cpt, CPLX128_LEG, *, 32c, 1 )
2229 ATOMIC_CRITICAL_CPT( cmplx16, div_cpt, CPLX128_LEG, /, 32c, 1 )
2230 #if ( KMP_ARCH_X86 )
2231 ATOMIC_CRITICAL_CPT( cmplx16, add_a16_cpt, kmp_cmplx128_a16_t, +, 32c, 1 )
2232 ATOMIC_CRITICAL_CPT( cmplx16, sub_a16_cpt, kmp_cmplx128_a16_t, -, 32c, 1 )
2233 ATOMIC_CRITICAL_CPT( cmplx16, mul_a16_cpt, kmp_cmplx128_a16_t, *, 32c, 1 )
2234 ATOMIC_CRITICAL_CPT( cmplx16, div_a16_cpt, kmp_cmplx128_a16_t, /, 32c, 1 )
2248 #define OP_CRITICAL_CPT_REV(OP,LCK_ID) \
2249 __kmp_acquire_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
2253 (*lhs) = (rhs) OP (*lhs); \
2254 new_value = (*lhs); \
2256 new_value = (*lhs);\
2257 (*lhs) = (rhs) OP (*lhs); \
2259 __kmp_release_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
2263 #ifdef KMP_GOMP_COMPAT
2264 #define OP_GOMP_CRITICAL_CPT_REV(OP,FLAG) \
2265 if ( (FLAG) && (__kmp_atomic_mode == 2) ) { \
2267 OP_CRITICAL_CPT_REV( OP, 0 ); \
2270 #define OP_GOMP_CRITICAL_CPT_REV(OP,FLAG)
2280 #define OP_CMPXCHG_CPT_REV(TYPE,BITS,OP) \
2282 TYPE KMP_ATOMIC_VOLATILE temp_val; \
2283 TYPE old_value, new_value; \
2285 old_value = temp_val; \
2286 new_value = rhs OP old_value; \
2287 while ( ! KMP_COMPARE_AND_STORE_ACQ##BITS( (kmp_int##BITS *) lhs, \
2288 *VOLATILE_CAST(kmp_int##BITS *) &old_value, \
2289 *VOLATILE_CAST(kmp_int##BITS *) &new_value ) ) \
2294 old_value = temp_val; \
2295 new_value = rhs OP old_value; \
2304 #define ATOMIC_CMPXCHG_CPT_REV(TYPE_ID,OP_ID,TYPE,BITS,OP,GOMP_FLAG) \
2305 ATOMIC_BEGIN_CPT(TYPE_ID,OP_ID,TYPE,TYPE) \
2307 TYPE KMP_ATOMIC_VOLATILE temp_val; \
2308 OP_GOMP_CRITICAL_CPT_REV(OP,GOMP_FLAG) \
2309 OP_CMPXCHG_CPT_REV(TYPE,BITS,OP) \
2313 ATOMIC_CMPXCHG_CPT_REV( fixed1, div_cpt_rev, kmp_int8, 8, /, KMP_ARCH_X86 )
2314 ATOMIC_CMPXCHG_CPT_REV( fixed1u, div_cpt_rev, kmp_uint8, 8, /, KMP_ARCH_X86 )
2315 ATOMIC_CMPXCHG_CPT_REV( fixed1, shl_cpt_rev, kmp_int8, 8, <<, KMP_ARCH_X86 )
2316 ATOMIC_CMPXCHG_CPT_REV( fixed1, shr_cpt_rev, kmp_int8, 8, >>, KMP_ARCH_X86 )
2317 ATOMIC_CMPXCHG_CPT_REV( fixed1u, shr_cpt_rev, kmp_uint8, 8, >>, KMP_ARCH_X86 )
2318 ATOMIC_CMPXCHG_CPT_REV( fixed1, sub_cpt_rev, kmp_int8, 8, -, KMP_ARCH_X86 )
2319 ATOMIC_CMPXCHG_CPT_REV( fixed2, div_cpt_rev, kmp_int16, 16, /, KMP_ARCH_X86 )
2320 ATOMIC_CMPXCHG_CPT_REV( fixed2u, div_cpt_rev, kmp_uint16, 16, /, KMP_ARCH_X86 )
2321 ATOMIC_CMPXCHG_CPT_REV( fixed2, shl_cpt_rev, kmp_int16, 16, <<, KMP_ARCH_X86 )
2322 ATOMIC_CMPXCHG_CPT_REV( fixed2, shr_cpt_rev, kmp_int16, 16, >>, KMP_ARCH_X86 )
2323 ATOMIC_CMPXCHG_CPT_REV( fixed2u, shr_cpt_rev, kmp_uint16, 16, >>, KMP_ARCH_X86 )
2324 ATOMIC_CMPXCHG_CPT_REV( fixed2, sub_cpt_rev, kmp_int16, 16, -, KMP_ARCH_X86 )
2325 ATOMIC_CMPXCHG_CPT_REV( fixed4, div_cpt_rev, kmp_int32, 32, /, KMP_ARCH_X86 )
2326 ATOMIC_CMPXCHG_CPT_REV( fixed4u, div_cpt_rev, kmp_uint32, 32, /, KMP_ARCH_X86 )
2327 ATOMIC_CMPXCHG_CPT_REV( fixed4, shl_cpt_rev, kmp_int32, 32, <<, KMP_ARCH_X86 )
2328 ATOMIC_CMPXCHG_CPT_REV( fixed4, shr_cpt_rev, kmp_int32, 32, >>, KMP_ARCH_X86 )
2329 ATOMIC_CMPXCHG_CPT_REV( fixed4u, shr_cpt_rev, kmp_uint32, 32, >>, KMP_ARCH_X86 )
2330 ATOMIC_CMPXCHG_CPT_REV( fixed4, sub_cpt_rev, kmp_int32, 32, -, KMP_ARCH_X86 )
2331 ATOMIC_CMPXCHG_CPT_REV( fixed8, div_cpt_rev, kmp_int64, 64, /, KMP_ARCH_X86 )
2332 ATOMIC_CMPXCHG_CPT_REV( fixed8u, div_cpt_rev, kmp_uint64, 64, /, KMP_ARCH_X86 )
2333 ATOMIC_CMPXCHG_CPT_REV( fixed8, shl_cpt_rev, kmp_int64, 64, <<, KMP_ARCH_X86 )
2334 ATOMIC_CMPXCHG_CPT_REV( fixed8, shr_cpt_rev, kmp_int64, 64, >>, KMP_ARCH_X86 )
2335 ATOMIC_CMPXCHG_CPT_REV( fixed8u, shr_cpt_rev, kmp_uint64, 64, >>, KMP_ARCH_X86 )
2336 ATOMIC_CMPXCHG_CPT_REV( fixed8, sub_cpt_rev, kmp_int64, 64, -, KMP_ARCH_X86 )
2337 ATOMIC_CMPXCHG_CPT_REV( float4, div_cpt_rev, kmp_real32, 32, /, KMP_ARCH_X86 )
2338 ATOMIC_CMPXCHG_CPT_REV( float4, sub_cpt_rev, kmp_real32, 32, -, KMP_ARCH_X86 )
2339 ATOMIC_CMPXCHG_CPT_REV( float8, div_cpt_rev, kmp_real64, 64, /, KMP_ARCH_X86 )
2340 ATOMIC_CMPXCHG_CPT_REV( float8, sub_cpt_rev, kmp_real64, 64, -, KMP_ARCH_X86 )
2349 #define ATOMIC_CRITICAL_CPT_REV(TYPE_ID,OP_ID,TYPE,OP,LCK_ID,GOMP_FLAG) \
2350 ATOMIC_BEGIN_CPT(TYPE_ID,OP_ID,TYPE,TYPE) \
2352 TYPE KMP_ATOMIC_VOLATILE temp_val; \
2354 OP_GOMP_CRITICAL_CPT_REV(OP,GOMP_FLAG) \
2355 OP_CRITICAL_CPT_REV(OP,LCK_ID) \
2361 ATOMIC_CRITICAL_CPT_REV( float10, sub_cpt_rev,
long double, -, 10r, 1 )
2362 ATOMIC_CRITICAL_CPT_REV( float10, div_cpt_rev,
long double, /, 10r, 1 )
2364 ATOMIC_CRITICAL_CPT_REV( float16, sub_cpt_rev, QUAD_LEGACY, -, 16r, 1 )
2365 ATOMIC_CRITICAL_CPT_REV( float16, div_cpt_rev, QUAD_LEGACY, /, 16r, 1 )
2366 #if ( KMP_ARCH_X86 )
2367 ATOMIC_CRITICAL_CPT_REV( float16, sub_a16_cpt_rev, Quad_a16_t, -, 16r, 1 )
2368 ATOMIC_CRITICAL_CPT_REV( float16, div_a16_cpt_rev, Quad_a16_t, /, 16r, 1 )
2377 #define OP_CRITICAL_CPT_REV_WRK(OP,LCK_ID) \
2378 __kmp_acquire_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
2381 (*lhs) = (rhs) OP (*lhs); \
2385 (*lhs) = (rhs) OP (*lhs); \
2388 __kmp_release_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
2392 #ifdef KMP_GOMP_COMPAT
2393 #define OP_GOMP_CRITICAL_CPT_REV_WRK(OP,FLAG) \
2394 if ( (FLAG) && (__kmp_atomic_mode == 2) ) { \
2396 OP_CRITICAL_CPT_REV_WRK( OP, 0 ); \
2399 #define OP_GOMP_CRITICAL_CPT_REV_WRK(OP,FLAG)
2403 #define ATOMIC_CRITICAL_CPT_REV_WRK(TYPE_ID,OP_ID,TYPE,OP,LCK_ID,GOMP_FLAG) \
2404 ATOMIC_BEGIN_WRK(TYPE_ID,OP_ID,TYPE) \
2405 OP_GOMP_CRITICAL_CPT_REV_WRK(OP,GOMP_FLAG) \
2406 OP_CRITICAL_CPT_REV_WRK(OP,LCK_ID) \
2413 ATOMIC_CRITICAL_CPT_REV_WRK( cmplx4, sub_cpt_rev, kmp_cmplx32, -, 8c, 1 )
2414 ATOMIC_CRITICAL_CPT_REV_WRK( cmplx4, div_cpt_rev, kmp_cmplx32, /, 8c, 1 )
2416 ATOMIC_CRITICAL_CPT_REV( cmplx8, sub_cpt_rev, kmp_cmplx64, -, 16c, 1 )
2417 ATOMIC_CRITICAL_CPT_REV( cmplx8, div_cpt_rev, kmp_cmplx64, /, 16c, 1 )
2418 ATOMIC_CRITICAL_CPT_REV( cmplx10, sub_cpt_rev, kmp_cmplx80, -, 20c, 1 )
2419 ATOMIC_CRITICAL_CPT_REV( cmplx10, div_cpt_rev, kmp_cmplx80, /, 20c, 1 )
2420 ATOMIC_CRITICAL_CPT_REV( cmplx16, sub_cpt_rev, CPLX128_LEG, -, 32c, 1 )
2421 ATOMIC_CRITICAL_CPT_REV( cmplx16, div_cpt_rev, CPLX128_LEG, /, 32c, 1 )
2422 #if ( KMP_ARCH_X86 )
2423 ATOMIC_CRITICAL_CPT_REV( cmplx16, sub_a16_cpt_rev, kmp_cmplx128_a16_t, -, 32c, 1 )
2424 ATOMIC_CRITICAL_CPT_REV( cmplx16, div_a16_cpt_rev, kmp_cmplx128_a16_t, /, 32c, 1 )
2429 #define ATOMIC_BEGIN_SWP(TYPE_ID,TYPE) \
2430 TYPE __kmpc_atomic_##TYPE_ID##_swp( ident_t *id_ref, int gtid, TYPE * lhs, TYPE rhs ) \
2432 KMP_DEBUG_ASSERT( __kmp_init_serial ); \
2433 KA_TRACE(100,("__kmpc_atomic_" #TYPE_ID "_swp: T#%d\n", gtid ));
2435 #define CRITICAL_SWP(LCK_ID) \
2436 __kmp_acquire_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
2438 old_value = (*lhs); \
2441 __kmp_release_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
2445 #ifdef KMP_GOMP_COMPAT
2446 #define GOMP_CRITICAL_SWP(FLAG) \
2447 if ( (FLAG) && (__kmp_atomic_mode == 2) ) { \
2449 CRITICAL_SWP( 0 ); \
2452 #define GOMP_CRITICAL_SWP(FLAG)
2456 #define ATOMIC_XCHG_SWP(TYPE_ID,TYPE,BITS,GOMP_FLAG) \
2457 ATOMIC_BEGIN_SWP(TYPE_ID,TYPE) \
2459 GOMP_CRITICAL_SWP(GOMP_FLAG) \
2460 old_value = __kmp_xchg_fixed##BITS( lhs, rhs ); \
2464 #define ATOMIC_XCHG_FLOAT_SWP(TYPE_ID,TYPE,BITS,GOMP_FLAG) \
2465 ATOMIC_BEGIN_SWP(TYPE_ID,TYPE) \
2467 GOMP_CRITICAL_SWP(GOMP_FLAG) \
2468 old_value = __kmp_xchg_real##BITS( lhs, rhs ); \
2473 #define CMPXCHG_SWP(TYPE,BITS) \
2475 TYPE KMP_ATOMIC_VOLATILE temp_val; \
2476 TYPE old_value, new_value; \
2478 old_value = temp_val; \
2480 while ( ! KMP_COMPARE_AND_STORE_ACQ##BITS( (kmp_int##BITS *) lhs, \
2481 *VOLATILE_CAST(kmp_int##BITS *) &old_value, \
2482 *VOLATILE_CAST(kmp_int##BITS *) &new_value ) ) \
2487 old_value = temp_val; \
2494 #define ATOMIC_CMPXCHG_SWP(TYPE_ID,TYPE,BITS,GOMP_FLAG) \
2495 ATOMIC_BEGIN_SWP(TYPE_ID,TYPE) \
2497 GOMP_CRITICAL_SWP(GOMP_FLAG) \
2498 CMPXCHG_SWP(TYPE,BITS) \
2501 ATOMIC_XCHG_SWP( fixed1, kmp_int8, 8, KMP_ARCH_X86 )
2502 ATOMIC_XCHG_SWP( fixed2, kmp_int16, 16, KMP_ARCH_X86 )
2503 ATOMIC_XCHG_SWP( fixed4, kmp_int32, 32, KMP_ARCH_X86 )
2505 ATOMIC_XCHG_FLOAT_SWP( float4, kmp_real32, 32, KMP_ARCH_X86 )
2507 #if ( KMP_ARCH_X86 )
2508 ATOMIC_CMPXCHG_SWP( fixed8, kmp_int64, 64, KMP_ARCH_X86 )
2509 ATOMIC_CMPXCHG_SWP( float8, kmp_real64, 64, KMP_ARCH_X86 )
2511 ATOMIC_XCHG_SWP( fixed8, kmp_int64, 64, KMP_ARCH_X86 )
2512 ATOMIC_XCHG_FLOAT_SWP( float8, kmp_real64, 64, KMP_ARCH_X86 )
2517 #define ATOMIC_CRITICAL_SWP(TYPE_ID,TYPE,LCK_ID,GOMP_FLAG) \
2518 ATOMIC_BEGIN_SWP(TYPE_ID,TYPE) \
2520 GOMP_CRITICAL_SWP(GOMP_FLAG) \
2521 CRITICAL_SWP(LCK_ID) \
2530 #define ATOMIC_BEGIN_SWP_WRK(TYPE_ID,TYPE) \
2531 void __kmpc_atomic_##TYPE_ID##_swp( ident_t *id_ref, int gtid, TYPE * lhs, TYPE rhs, TYPE * out ) \
2533 KMP_DEBUG_ASSERT( __kmp_init_serial ); \
2534 KA_TRACE(100,("__kmpc_atomic_" #TYPE_ID "_swp: T#%d\n", gtid ));
2537 #define CRITICAL_SWP_WRK(LCK_ID) \
2538 __kmp_acquire_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
2543 __kmp_release_atomic_lock( & ATOMIC_LOCK##LCK_ID, gtid ); \
2548 #ifdef KMP_GOMP_COMPAT
2549 #define GOMP_CRITICAL_SWP_WRK(FLAG) \
2550 if ( (FLAG) && (__kmp_atomic_mode == 2) ) { \
2552 CRITICAL_SWP_WRK( 0 ); \
2555 #define GOMP_CRITICAL_SWP_WRK(FLAG)
2559 #define ATOMIC_CRITICAL_SWP_WRK(TYPE_ID, TYPE,LCK_ID,GOMP_FLAG) \
2560 ATOMIC_BEGIN_SWP_WRK(TYPE_ID,TYPE) \
2562 GOMP_CRITICAL_SWP_WRK(GOMP_FLAG) \
2563 CRITICAL_SWP_WRK(LCK_ID) \
2568 ATOMIC_CRITICAL_SWP( float10,
long double, 10r, 1 )
2569 ATOMIC_CRITICAL_SWP( float16, QUAD_LEGACY, 16r, 1 )
2571 ATOMIC_CRITICAL_SWP_WRK( cmplx4, kmp_cmplx32, 8c, 1 )
2576 ATOMIC_CRITICAL_SWP( cmplx8, kmp_cmplx64, 16c, 1 )
2577 ATOMIC_CRITICAL_SWP( cmplx10, kmp_cmplx80, 20c, 1 )
2578 ATOMIC_CRITICAL_SWP( cmplx16, CPLX128_LEG, 32c, 1 )
2579 #if ( KMP_ARCH_X86 )
2580 ATOMIC_CRITICAL_SWP( float16_a16, Quad_a16_t, 16r, 1 )
2581 ATOMIC_CRITICAL_SWP( cmplx16_a16, kmp_cmplx128_a16_t, 32c, 1 )
2587 #endif //OMP_40_ENABLED
2589 #endif //KMP_ARCH_X86 || KMP_ARCH_X86_64
2599 __kmpc_atomic_1(
ident_t *id_ref,
int gtid,
void* lhs,
void* rhs,
void (*f)(
void *,
void *,
void * ) )
2601 KMP_DEBUG_ASSERT( __kmp_init_serial );
2604 #
if KMP_ARCH_X86 && defined(KMP_GOMP_COMPAT)
2611 kmp_int8 old_value, new_value;
2613 old_value = *(kmp_int8 *) lhs;
2614 (*f)( &new_value, &old_value, rhs );
2617 while ( ! KMP_COMPARE_AND_STORE_ACQ8 ( (kmp_int8 *) lhs,
2618 *(kmp_int8 *) &old_value, *(kmp_int8 *) &new_value ) )
2622 old_value = *(kmp_int8 *) lhs;
2623 (*f)( &new_value, &old_value, rhs );
2633 #ifdef KMP_GOMP_COMPAT
2634 if ( __kmp_atomic_mode == 2 ) {
2635 __kmp_acquire_atomic_lock( & __kmp_atomic_lock, gtid );
2639 __kmp_acquire_atomic_lock( & __kmp_atomic_lock_1i, gtid );
2641 (*f)( lhs, lhs, rhs );
2643 #ifdef KMP_GOMP_COMPAT
2644 if ( __kmp_atomic_mode == 2 ) {
2645 __kmp_release_atomic_lock( & __kmp_atomic_lock, gtid );
2649 __kmp_release_atomic_lock( & __kmp_atomic_lock_1i, gtid );
2654 __kmpc_atomic_2(
ident_t *id_ref,
int gtid,
void* lhs,
void* rhs,
void (*f)(
void *,
void *,
void * ) )
2657 #
if KMP_ARCH_X86 && defined(KMP_GOMP_COMPAT)
2659 #elif KMP_ARCH_X86 || KMP_ARCH_X86_64
2662 ! ( (kmp_uintptr_t) lhs & 0x1)
2666 kmp_int16 old_value, new_value;
2668 old_value = *(kmp_int16 *) lhs;
2669 (*f)( &new_value, &old_value, rhs );
2672 while ( ! KMP_COMPARE_AND_STORE_ACQ16 ( (kmp_int16 *) lhs,
2673 *(kmp_int16 *) &old_value, *(kmp_int16 *) &new_value ) )
2677 old_value = *(kmp_int16 *) lhs;
2678 (*f)( &new_value, &old_value, rhs );
2688 #ifdef KMP_GOMP_COMPAT
2689 if ( __kmp_atomic_mode == 2 ) {
2690 __kmp_acquire_atomic_lock( & __kmp_atomic_lock, gtid );
2694 __kmp_acquire_atomic_lock( & __kmp_atomic_lock_2i, gtid );
2696 (*f)( lhs, lhs, rhs );
2698 #ifdef KMP_GOMP_COMPAT
2699 if ( __kmp_atomic_mode == 2 ) {
2700 __kmp_release_atomic_lock( & __kmp_atomic_lock, gtid );
2704 __kmp_release_atomic_lock( & __kmp_atomic_lock_2i, gtid );
2709 __kmpc_atomic_4(
ident_t *id_ref,
int gtid,
void* lhs,
void* rhs,
void (*f)(
void *,
void *,
void * ) )
2711 KMP_DEBUG_ASSERT( __kmp_init_serial );
2718 #
if KMP_ARCH_X86 || KMP_ARCH_X86_64
2721 ! ( (kmp_uintptr_t) lhs & 0x3)
2725 kmp_int32 old_value, new_value;
2727 old_value = *(kmp_int32 *) lhs;
2728 (*f)( &new_value, &old_value, rhs );
2731 while ( ! KMP_COMPARE_AND_STORE_ACQ32 ( (kmp_int32 *) lhs,
2732 *(kmp_int32 *) &old_value, *(kmp_int32 *) &new_value ) )
2736 old_value = *(kmp_int32 *) lhs;
2737 (*f)( &new_value, &old_value, rhs );
2748 #ifdef KMP_GOMP_COMPAT
2749 if ( __kmp_atomic_mode == 2 ) {
2750 __kmp_acquire_atomic_lock( & __kmp_atomic_lock, gtid );
2754 __kmp_acquire_atomic_lock( & __kmp_atomic_lock_4i, gtid );
2756 (*f)( lhs, lhs, rhs );
2758 #ifdef KMP_GOMP_COMPAT
2759 if ( __kmp_atomic_mode == 2 ) {
2760 __kmp_release_atomic_lock( & __kmp_atomic_lock, gtid );
2764 __kmp_release_atomic_lock( & __kmp_atomic_lock_4i, gtid );
2769 __kmpc_atomic_8(
ident_t *id_ref,
int gtid,
void* lhs,
void* rhs,
void (*f)(
void *,
void *,
void * ) )
2771 KMP_DEBUG_ASSERT( __kmp_init_serial );
2774 #
if KMP_ARCH_X86 && defined(KMP_GOMP_COMPAT)
2776 #elif KMP_ARCH_X86 || KMP_ARCH_X86_64
2779 ! ( (kmp_uintptr_t) lhs & 0x7)
2783 kmp_int64 old_value, new_value;
2785 old_value = *(kmp_int64 *) lhs;
2786 (*f)( &new_value, &old_value, rhs );
2788 while ( ! KMP_COMPARE_AND_STORE_ACQ64 ( (kmp_int64 *) lhs,
2789 *(kmp_int64 *) &old_value,
2790 *(kmp_int64 *) &new_value ) )
2794 old_value = *(kmp_int64 *) lhs;
2795 (*f)( &new_value, &old_value, rhs );
2805 #ifdef KMP_GOMP_COMPAT
2806 if ( __kmp_atomic_mode == 2 ) {
2807 __kmp_acquire_atomic_lock( & __kmp_atomic_lock, gtid );
2811 __kmp_acquire_atomic_lock( & __kmp_atomic_lock_8i, gtid );
2813 (*f)( lhs, lhs, rhs );
2815 #ifdef KMP_GOMP_COMPAT
2816 if ( __kmp_atomic_mode == 2 ) {
2817 __kmp_release_atomic_lock( & __kmp_atomic_lock, gtid );
2821 __kmp_release_atomic_lock( & __kmp_atomic_lock_8i, gtid );
2826 __kmpc_atomic_10(
ident_t *id_ref,
int gtid,
void* lhs,
void* rhs,
void (*f)(
void *,
void *,
void * ) )
2828 KMP_DEBUG_ASSERT( __kmp_init_serial );
2830 #ifdef KMP_GOMP_COMPAT
2831 if ( __kmp_atomic_mode == 2 ) {
2832 __kmp_acquire_atomic_lock( & __kmp_atomic_lock, gtid );
2836 __kmp_acquire_atomic_lock( & __kmp_atomic_lock_10r, gtid );
2838 (*f)( lhs, lhs, rhs );
2840 #ifdef KMP_GOMP_COMPAT
2841 if ( __kmp_atomic_mode == 2 ) {
2842 __kmp_release_atomic_lock( & __kmp_atomic_lock, gtid );
2846 __kmp_release_atomic_lock( & __kmp_atomic_lock_10r, gtid );
2850 __kmpc_atomic_16(
ident_t *id_ref,
int gtid,
void* lhs,
void* rhs,
void (*f)(
void *,
void *,
void * ) )
2852 KMP_DEBUG_ASSERT( __kmp_init_serial );
2854 #ifdef KMP_GOMP_COMPAT
2855 if ( __kmp_atomic_mode == 2 ) {
2856 __kmp_acquire_atomic_lock( & __kmp_atomic_lock, gtid );
2860 __kmp_acquire_atomic_lock( & __kmp_atomic_lock_16c, gtid );
2862 (*f)( lhs, lhs, rhs );
2864 #ifdef KMP_GOMP_COMPAT
2865 if ( __kmp_atomic_mode == 2 ) {
2866 __kmp_release_atomic_lock( & __kmp_atomic_lock, gtid );
2870 __kmp_release_atomic_lock( & __kmp_atomic_lock_16c, gtid );
2874 __kmpc_atomic_20(
ident_t *id_ref,
int gtid,
void* lhs,
void* rhs,
void (*f)(
void *,
void *,
void * ) )
2876 KMP_DEBUG_ASSERT( __kmp_init_serial );
2878 #ifdef KMP_GOMP_COMPAT
2879 if ( __kmp_atomic_mode == 2 ) {
2880 __kmp_acquire_atomic_lock( & __kmp_atomic_lock, gtid );
2884 __kmp_acquire_atomic_lock( & __kmp_atomic_lock_20c, gtid );
2886 (*f)( lhs, lhs, rhs );
2888 #ifdef KMP_GOMP_COMPAT
2889 if ( __kmp_atomic_mode == 2 ) {
2890 __kmp_release_atomic_lock( & __kmp_atomic_lock, gtid );
2894 __kmp_release_atomic_lock( & __kmp_atomic_lock_20c, gtid );
2898 __kmpc_atomic_32(
ident_t *id_ref,
int gtid,
void* lhs,
void* rhs,
void (*f)(
void *,
void *,
void * ) )
2900 KMP_DEBUG_ASSERT( __kmp_init_serial );
2902 #ifdef KMP_GOMP_COMPAT
2903 if ( __kmp_atomic_mode == 2 ) {
2904 __kmp_acquire_atomic_lock( & __kmp_atomic_lock, gtid );
2908 __kmp_acquire_atomic_lock( & __kmp_atomic_lock_32c, gtid );
2910 (*f)( lhs, lhs, rhs );
2912 #ifdef KMP_GOMP_COMPAT
2913 if ( __kmp_atomic_mode == 2 ) {
2914 __kmp_release_atomic_lock( & __kmp_atomic_lock, gtid );
2918 __kmp_release_atomic_lock( & __kmp_atomic_lock_32c, gtid );
2925 __kmpc_atomic_start(
void)
2927 int gtid = __kmp_entry_gtid();
2928 KA_TRACE(20, (
"__kmpc_atomic_start: T#%d\n", gtid));
2929 __kmp_acquire_atomic_lock(&__kmp_atomic_lock, gtid);
2934 __kmpc_atomic_end(
void)
2936 int gtid = __kmp_get_gtid();
2937 KA_TRACE(20, (
"__kmpc_atomic_end: T#%d\n", gtid));
2938 __kmp_release_atomic_lock(&__kmp_atomic_lock, gtid);